1 | /* |
2 | * Copyright (C) 2003, 2006 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2009, 2012 Google Inc. All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * |
14 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
15 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
18 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | */ |
26 | #include "config.h" |
27 | #include "ResourceRequestBase.h" |
28 | |
29 | #include "HTTPHeaderNames.h" |
30 | #include "PublicSuffix.h" |
31 | #include "ResourceRequest.h" |
32 | #include "ResourceResponse.h" |
33 | #include "SecurityPolicy.h" |
34 | #include <wtf/PointerComparison.h> |
35 | |
36 | namespace WebCore { |
37 | |
38 | #if PLATFORM(IOS_FAMILY) || USE(CFURLCONNECTION) |
39 | double ResourceRequestBase::s_defaultTimeoutInterval = INT_MAX; |
40 | #else |
41 | // Will use NSURLRequest default timeout unless set to a non-zero value with setDefaultTimeoutInterval(). |
42 | // For libsoup the timeout enabled with integer milliseconds. We set 0 as the default value to avoid integer overflow. |
43 | double ResourceRequestBase::s_defaultTimeoutInterval = 0; |
44 | #endif |
45 | |
46 | inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const |
47 | { |
48 | return *static_cast<const ResourceRequest*>(this); |
49 | } |
50 | |
51 | ResourceRequest ResourceRequestBase::isolatedCopy() const |
52 | { |
53 | ResourceRequest request; |
54 | request.setAsIsolatedCopy(asResourceRequest()); |
55 | return request; |
56 | } |
57 | |
58 | void ResourceRequestBase::setAsIsolatedCopy(const ResourceRequest& other) |
59 | { |
60 | setURL(other.url().isolatedCopy()); |
61 | setCachePolicy(other.cachePolicy()); |
62 | setTimeoutInterval(other.timeoutInterval()); |
63 | setFirstPartyForCookies(other.firstPartyForCookies().isolatedCopy()); |
64 | setHTTPMethod(other.httpMethod().isolatedCopy()); |
65 | setPriority(other.priority()); |
66 | setRequester(other.requester()); |
67 | setInitiatorIdentifier(other.initiatorIdentifier().isolatedCopy()); |
68 | setCachePartition(other.cachePartition().isolatedCopy()); |
69 | |
70 | if (auto inspectorInitiatorNodeIdentifier = other.inspectorInitiatorNodeIdentifier()) |
71 | setInspectorInitiatorNodeIdentifier(*inspectorInitiatorNodeIdentifier); |
72 | |
73 | if (!other.isSameSiteUnspecified()) |
74 | setIsSameSite(other.isSameSite()); |
75 | setIsTopSite(other.isTopSite()); |
76 | |
77 | updateResourceRequest(); |
78 | m_httpHeaderFields = other.httpHeaderFields().isolatedCopy(); |
79 | |
80 | size_t encodingCount = other.m_responseContentDispositionEncodingFallbackArray.size(); |
81 | if (encodingCount > 0) { |
82 | String encoding1 = other.m_responseContentDispositionEncodingFallbackArray[0].isolatedCopy(); |
83 | String encoding2; |
84 | String encoding3; |
85 | if (encodingCount > 1) { |
86 | encoding2 = other.m_responseContentDispositionEncodingFallbackArray[1].isolatedCopy(); |
87 | if (encodingCount > 2) |
88 | encoding3 = other.m_responseContentDispositionEncodingFallbackArray[2].isolatedCopy(); |
89 | } |
90 | ASSERT(encodingCount <= 3); |
91 | setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3); |
92 | } |
93 | if (other.m_httpBody) |
94 | setHTTPBody(other.m_httpBody->isolatedCopy()); |
95 | setAllowCookies(other.m_allowCookies); |
96 | } |
97 | |
98 | bool ResourceRequestBase::isEmpty() const |
99 | { |
100 | updateResourceRequest(); |
101 | |
102 | return m_url.isEmpty(); |
103 | } |
104 | |
105 | bool ResourceRequestBase::isNull() const |
106 | { |
107 | updateResourceRequest(); |
108 | |
109 | return m_url.isNull(); |
110 | } |
111 | |
112 | const URL& ResourceRequestBase::url() const |
113 | { |
114 | updateResourceRequest(); |
115 | |
116 | return m_url; |
117 | } |
118 | |
119 | void ResourceRequestBase::setURL(const URL& url) |
120 | { |
121 | updateResourceRequest(); |
122 | |
123 | m_url = url; |
124 | |
125 | m_platformRequestUpdated = false; |
126 | } |
127 | |
128 | static bool shouldUseGet(const ResourceRequestBase& request, const ResourceResponse& redirectResponse) |
129 | { |
130 | if (redirectResponse.httpStatusCode() == 301 || redirectResponse.httpStatusCode() == 302) |
131 | return equalLettersIgnoringASCIICase(request.httpMethod(), "post" ); |
132 | return redirectResponse.httpStatusCode() == 303; |
133 | } |
134 | |
135 | ResourceRequest ResourceRequestBase::redirectedRequest(const ResourceResponse& redirectResponse, bool shouldClearReferrerOnHTTPSToHTTPRedirect) const |
136 | { |
137 | ASSERT(redirectResponse.isRedirection()); |
138 | // This method is based on https://fetch.spec.whatwg.org/#http-redirect-fetch. |
139 | // It also implements additional processing like done by CFNetwork layer. |
140 | |
141 | auto request = asResourceRequest(); |
142 | auto location = redirectResponse.httpHeaderField(HTTPHeaderName::Location); |
143 | |
144 | request.setURL(location.isEmpty() ? URL { } : URL { redirectResponse.url(), location }); |
145 | |
146 | if (shouldUseGet(*this, redirectResponse)) { |
147 | request.setHTTPMethod("GET"_s ); |
148 | request.setHTTPBody(nullptr); |
149 | request.clearHTTPContentType(); |
150 | request.m_httpHeaderFields.remove(HTTPHeaderName::ContentLength); |
151 | } |
152 | |
153 | if (shouldClearReferrerOnHTTPSToHTTPRedirect && !request.url().protocolIs("https" ) && WTF::protocolIs(request.httpReferrer(), "https" )) |
154 | request.clearHTTPReferrer(); |
155 | |
156 | if (!protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) |
157 | request.clearHTTPOrigin(); |
158 | request.clearHTTPAuthorization(); |
159 | request.m_httpHeaderFields.remove(HTTPHeaderName::ProxyAuthorization); |
160 | |
161 | return request; |
162 | } |
163 | |
164 | void ResourceRequestBase::removeCredentials() |
165 | { |
166 | updateResourceRequest(); |
167 | |
168 | if (m_url.user().isEmpty() && m_url.pass().isEmpty()) |
169 | return; |
170 | |
171 | m_url.setUser(String()); |
172 | m_url.setPass(String()); |
173 | |
174 | m_platformRequestUpdated = false; |
175 | } |
176 | |
177 | ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const |
178 | { |
179 | updateResourceRequest(); |
180 | |
181 | return m_cachePolicy; |
182 | } |
183 | |
184 | void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy) |
185 | { |
186 | updateResourceRequest(); |
187 | |
188 | if (m_cachePolicy == cachePolicy) |
189 | return; |
190 | |
191 | m_cachePolicy = cachePolicy; |
192 | |
193 | m_platformRequestUpdated = false; |
194 | } |
195 | |
196 | double ResourceRequestBase::timeoutInterval() const |
197 | { |
198 | updateResourceRequest(); |
199 | |
200 | return m_timeoutInterval; |
201 | } |
202 | |
203 | void ResourceRequestBase::setTimeoutInterval(double timeoutInterval) |
204 | { |
205 | updateResourceRequest(); |
206 | |
207 | if (m_timeoutInterval == timeoutInterval) |
208 | return; |
209 | |
210 | m_timeoutInterval = timeoutInterval; |
211 | |
212 | m_platformRequestUpdated = false; |
213 | } |
214 | |
215 | const URL& ResourceRequestBase::firstPartyForCookies() const |
216 | { |
217 | updateResourceRequest(); |
218 | |
219 | return m_firstPartyForCookies; |
220 | } |
221 | |
222 | void ResourceRequestBase::setFirstPartyForCookies(const URL& firstPartyForCookies) |
223 | { |
224 | updateResourceRequest(); |
225 | |
226 | if (m_firstPartyForCookies == firstPartyForCookies) |
227 | return; |
228 | |
229 | m_firstPartyForCookies = firstPartyForCookies; |
230 | |
231 | m_platformRequestUpdated = false; |
232 | } |
233 | |
234 | bool ResourceRequestBase::isSameSite() const |
235 | { |
236 | updateResourceRequest(); |
237 | |
238 | return m_sameSiteDisposition == SameSiteDisposition::SameSite; |
239 | } |
240 | |
241 | void ResourceRequestBase::setIsSameSite(bool isSameSite) |
242 | { |
243 | updateResourceRequest(); |
244 | |
245 | SameSiteDisposition newDisposition = isSameSite ? SameSiteDisposition::SameSite : SameSiteDisposition::CrossSite; |
246 | if (m_sameSiteDisposition == newDisposition) |
247 | return; |
248 | |
249 | m_sameSiteDisposition = newDisposition; |
250 | |
251 | m_platformRequestUpdated = false; |
252 | } |
253 | |
254 | bool ResourceRequestBase::isTopSite() const |
255 | { |
256 | updateResourceRequest(); |
257 | |
258 | return m_isTopSite; |
259 | } |
260 | |
261 | void ResourceRequestBase::setIsTopSite(bool isTopSite) |
262 | { |
263 | updateResourceRequest(); |
264 | |
265 | if (m_isTopSite == isTopSite) |
266 | return; |
267 | |
268 | m_isTopSite = isTopSite; |
269 | |
270 | m_platformRequestUpdated = false; |
271 | } |
272 | |
273 | const String& ResourceRequestBase::httpMethod() const |
274 | { |
275 | updateResourceRequest(); |
276 | |
277 | return m_httpMethod; |
278 | } |
279 | |
280 | void ResourceRequestBase::setHTTPMethod(const String& httpMethod) |
281 | { |
282 | updateResourceRequest(); |
283 | |
284 | if (m_httpMethod == httpMethod) |
285 | return; |
286 | |
287 | m_httpMethod = httpMethod; |
288 | |
289 | m_platformRequestUpdated = false; |
290 | } |
291 | |
292 | const HTTPHeaderMap& ResourceRequestBase::() const |
293 | { |
294 | updateResourceRequest(); |
295 | |
296 | return m_httpHeaderFields; |
297 | } |
298 | |
299 | String ResourceRequestBase::(const String& name) const |
300 | { |
301 | updateResourceRequest(); |
302 | |
303 | return m_httpHeaderFields.get(name); |
304 | } |
305 | |
306 | String ResourceRequestBase::(HTTPHeaderName name) const |
307 | { |
308 | updateResourceRequest(); |
309 | |
310 | return m_httpHeaderFields.get(name); |
311 | } |
312 | |
313 | void ResourceRequestBase::(const String& name, const String& value) |
314 | { |
315 | updateResourceRequest(); |
316 | |
317 | m_httpHeaderFields.set(name, value); |
318 | |
319 | m_platformRequestUpdated = false; |
320 | } |
321 | |
322 | void ResourceRequestBase::(HTTPHeaderName name, const String& value) |
323 | { |
324 | updateResourceRequest(); |
325 | |
326 | m_httpHeaderFields.set(name, value); |
327 | |
328 | m_platformRequestUpdated = false; |
329 | } |
330 | |
331 | void ResourceRequestBase::clearHTTPAuthorization() |
332 | { |
333 | updateResourceRequest(); |
334 | |
335 | if (!m_httpHeaderFields.remove(HTTPHeaderName::Authorization)) |
336 | return; |
337 | |
338 | m_platformRequestUpdated = false; |
339 | } |
340 | |
341 | String ResourceRequestBase::httpContentType() const |
342 | { |
343 | return httpHeaderField(HTTPHeaderName::ContentType); |
344 | } |
345 | |
346 | void ResourceRequestBase::setHTTPContentType(const String& httpContentType) |
347 | { |
348 | setHTTPHeaderField(HTTPHeaderName::ContentType, httpContentType); |
349 | } |
350 | |
351 | void ResourceRequestBase::clearHTTPContentType() |
352 | { |
353 | updateResourceRequest(); |
354 | |
355 | m_httpHeaderFields.remove(HTTPHeaderName::ContentType); |
356 | |
357 | m_platformRequestUpdated = false; |
358 | } |
359 | |
360 | String ResourceRequestBase::httpReferrer() const |
361 | { |
362 | return httpHeaderField(HTTPHeaderName::Referer); |
363 | } |
364 | |
365 | bool ResourceRequestBase::hasHTTPReferrer() const |
366 | { |
367 | return m_httpHeaderFields.contains(HTTPHeaderName::Referer); |
368 | } |
369 | |
370 | void ResourceRequestBase::setHTTPReferrer(const String& httpReferrer) |
371 | { |
372 | setHTTPHeaderField(HTTPHeaderName::Referer, httpReferrer); |
373 | } |
374 | |
375 | void ResourceRequestBase::setExistingHTTPReferrerToOriginString() |
376 | { |
377 | if (!hasHTTPReferrer()) |
378 | return; |
379 | |
380 | setHTTPHeaderField(HTTPHeaderName::Referer, SecurityPolicy::referrerToOriginString(httpReferrer())); |
381 | } |
382 | |
383 | void ResourceRequestBase::clearHTTPReferrer() |
384 | { |
385 | updateResourceRequest(); |
386 | |
387 | m_httpHeaderFields.remove(HTTPHeaderName::Referer); |
388 | |
389 | m_platformRequestUpdated = false; |
390 | } |
391 | |
392 | String ResourceRequestBase::httpOrigin() const |
393 | { |
394 | return httpHeaderField(HTTPHeaderName::Origin); |
395 | } |
396 | |
397 | void ResourceRequestBase::setHTTPOrigin(const String& httpOrigin) |
398 | { |
399 | setHTTPHeaderField(HTTPHeaderName::Origin, httpOrigin); |
400 | } |
401 | |
402 | bool ResourceRequestBase::hasHTTPOrigin() const |
403 | { |
404 | return m_httpHeaderFields.contains(HTTPHeaderName::Origin); |
405 | } |
406 | |
407 | void ResourceRequestBase::clearHTTPOrigin() |
408 | { |
409 | updateResourceRequest(); |
410 | |
411 | m_httpHeaderFields.remove(HTTPHeaderName::Origin); |
412 | |
413 | m_platformRequestUpdated = false; |
414 | } |
415 | |
416 | bool ResourceRequestBase::(HTTPHeaderName name) const |
417 | { |
418 | return m_httpHeaderFields.contains(name); |
419 | } |
420 | |
421 | String ResourceRequestBase::httpUserAgent() const |
422 | { |
423 | return httpHeaderField(HTTPHeaderName::UserAgent); |
424 | } |
425 | |
426 | void ResourceRequestBase::setHTTPUserAgent(const String& httpUserAgent) |
427 | { |
428 | setHTTPHeaderField(HTTPHeaderName::UserAgent, httpUserAgent); |
429 | } |
430 | |
431 | void ResourceRequestBase::clearHTTPUserAgent() |
432 | { |
433 | updateResourceRequest(); |
434 | |
435 | m_httpHeaderFields.remove(HTTPHeaderName::UserAgent); |
436 | |
437 | m_platformRequestUpdated = false; |
438 | } |
439 | |
440 | String ResourceRequestBase::httpAccept() const |
441 | { |
442 | return httpHeaderField(HTTPHeaderName::Accept); |
443 | } |
444 | |
445 | void ResourceRequestBase::setHTTPAccept(const String& httpAccept) |
446 | { |
447 | setHTTPHeaderField(HTTPHeaderName::Accept, httpAccept); |
448 | } |
449 | |
450 | void ResourceRequestBase::clearHTTPAccept() |
451 | { |
452 | updateResourceRequest(); |
453 | |
454 | m_httpHeaderFields.remove(HTTPHeaderName::Accept); |
455 | |
456 | m_platformRequestUpdated = false; |
457 | } |
458 | |
459 | void ResourceRequestBase::clearHTTPAcceptEncoding() |
460 | { |
461 | updateResourceRequest(); |
462 | |
463 | m_httpHeaderFields.remove(HTTPHeaderName::AcceptEncoding); |
464 | |
465 | m_platformRequestUpdated = false; |
466 | } |
467 | |
468 | void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3) |
469 | { |
470 | updateResourceRequest(); |
471 | |
472 | m_responseContentDispositionEncodingFallbackArray.clear(); |
473 | m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(!encoding1.isNull() + !encoding2.isNull() + !encoding3.isNull()); |
474 | if (!encoding1.isNull()) |
475 | m_responseContentDispositionEncodingFallbackArray.uncheckedAppend(encoding1); |
476 | if (!encoding2.isNull()) |
477 | m_responseContentDispositionEncodingFallbackArray.uncheckedAppend(encoding2); |
478 | if (!encoding3.isNull()) |
479 | m_responseContentDispositionEncodingFallbackArray.uncheckedAppend(encoding3); |
480 | |
481 | m_platformRequestUpdated = false; |
482 | } |
483 | |
484 | FormData* ResourceRequestBase::httpBody() const |
485 | { |
486 | updateResourceRequest(HTTPBodyUpdatePolicy::UpdateHTTPBody); |
487 | |
488 | return m_httpBody.get(); |
489 | } |
490 | |
491 | bool ResourceRequestBase::hasUpload() const |
492 | { |
493 | if (auto* body = httpBody()) { |
494 | for (auto& element : body->elements()) { |
495 | if (WTF::holds_alternative<WebCore::FormDataElement::EncodedFileData>(element.data) || WTF::holds_alternative<WebCore::FormDataElement::EncodedBlobData>(element.data)) |
496 | return true; |
497 | } |
498 | } |
499 | |
500 | return false; |
501 | } |
502 | |
503 | void ResourceRequestBase::setHTTPBody(RefPtr<FormData>&& httpBody) |
504 | { |
505 | updateResourceRequest(); |
506 | |
507 | m_httpBody = WTFMove(httpBody); |
508 | |
509 | m_resourceRequestBodyUpdated = true; |
510 | |
511 | m_platformRequestBodyUpdated = false; |
512 | } |
513 | |
514 | bool ResourceRequestBase::allowCookies() const |
515 | { |
516 | updateResourceRequest(); |
517 | |
518 | return m_allowCookies; |
519 | } |
520 | |
521 | void ResourceRequestBase::setAllowCookies(bool allowCookies) |
522 | { |
523 | updateResourceRequest(); |
524 | |
525 | if (m_allowCookies == allowCookies) |
526 | return; |
527 | |
528 | m_allowCookies = allowCookies; |
529 | |
530 | m_platformRequestUpdated = false; |
531 | } |
532 | |
533 | ResourceLoadPriority ResourceRequestBase::priority() const |
534 | { |
535 | updateResourceRequest(); |
536 | |
537 | return m_priority; |
538 | } |
539 | |
540 | void ResourceRequestBase::setPriority(ResourceLoadPriority priority) |
541 | { |
542 | updateResourceRequest(); |
543 | |
544 | if (m_priority == priority) |
545 | return; |
546 | |
547 | m_priority = priority; |
548 | |
549 | m_platformRequestUpdated = false; |
550 | } |
551 | |
552 | void ResourceRequestBase::(HTTPHeaderName name, const String& value) |
553 | { |
554 | updateResourceRequest(); |
555 | |
556 | if (!m_httpHeaderFields.addIfNotPresent(name, value)) |
557 | return; |
558 | |
559 | m_platformRequestUpdated = false; |
560 | } |
561 | |
562 | void ResourceRequestBase::(HTTPHeaderName name, const String& value) |
563 | { |
564 | updateResourceRequest(); |
565 | |
566 | m_httpHeaderFields.add(name, value); |
567 | |
568 | m_platformRequestUpdated = false; |
569 | } |
570 | |
571 | void ResourceRequestBase::(const String& name, const String& value) |
572 | { |
573 | updateResourceRequest(); |
574 | |
575 | m_httpHeaderFields.add(name, value); |
576 | |
577 | m_platformRequestUpdated = false; |
578 | } |
579 | |
580 | bool ResourceRequestBase::(HTTPHeaderName ) const |
581 | { |
582 | return m_httpHeaderFields.contains(headerName); |
583 | } |
584 | |
585 | void ResourceRequestBase::(HTTPHeaderMap ) |
586 | { |
587 | updateResourceRequest(); |
588 | |
589 | m_httpHeaderFields = WTFMove(headerFields); |
590 | |
591 | m_platformRequestUpdated = false; |
592 | } |
593 | |
594 | #if USE(SYSTEM_PREVIEW) |
595 | bool ResourceRequestBase::isSystemPreview() const |
596 | { |
597 | return m_isSystemPreview; |
598 | } |
599 | |
600 | void ResourceRequestBase::setSystemPreview(bool s) |
601 | { |
602 | m_isSystemPreview = s; |
603 | } |
604 | |
605 | const IntRect& ResourceRequestBase::systemPreviewRect() const |
606 | { |
607 | return m_systemPreviewRect; |
608 | } |
609 | |
610 | void ResourceRequestBase::setSystemPreviewRect(const IntRect& rect) |
611 | { |
612 | m_systemPreviewRect = rect; |
613 | } |
614 | #endif |
615 | |
616 | bool (const ResourceRequestBase& a, const ResourceRequestBase& b) |
617 | { |
618 | if (a.url() != b.url()) |
619 | return false; |
620 | |
621 | if (a.cachePolicy() != b.cachePolicy()) |
622 | return false; |
623 | |
624 | if (a.timeoutInterval() != b.timeoutInterval()) |
625 | return false; |
626 | |
627 | if (a.firstPartyForCookies() != b.firstPartyForCookies()) |
628 | return false; |
629 | |
630 | if (a.isSameSite() != b.isSameSite()) |
631 | return false; |
632 | |
633 | if (a.isTopSite() != b.isTopSite()) |
634 | return false; |
635 | |
636 | if (a.httpMethod() != b.httpMethod()) |
637 | return false; |
638 | |
639 | if (a.allowCookies() != b.allowCookies()) |
640 | return false; |
641 | |
642 | if (a.priority() != b.priority()) |
643 | return false; |
644 | |
645 | if (a.requester() != b.requester()) |
646 | return false; |
647 | |
648 | return arePointingToEqualData(a.httpBody(), b.httpBody()); |
649 | } |
650 | |
651 | bool ResourceRequestBase::equal(const ResourceRequest& a, const ResourceRequest& b) |
652 | { |
653 | if (!equalIgnoringHeaderFields(a, b)) |
654 | return false; |
655 | |
656 | if (a.httpHeaderFields() != b.httpHeaderFields()) |
657 | return false; |
658 | |
659 | return ResourceRequest::platformCompare(a, b); |
660 | } |
661 | |
662 | static const HTTPHeaderName [] = { |
663 | HTTPHeaderName::IfMatch, |
664 | HTTPHeaderName::IfModifiedSince, |
665 | HTTPHeaderName::IfNoneMatch, |
666 | HTTPHeaderName::IfRange, |
667 | HTTPHeaderName::IfUnmodifiedSince |
668 | }; |
669 | |
670 | bool ResourceRequestBase::isConditional() const |
671 | { |
672 | updateResourceRequest(); |
673 | |
674 | for (auto : conditionalHeaderNames) { |
675 | if (m_httpHeaderFields.contains(headerName)) |
676 | return true; |
677 | } |
678 | |
679 | return false; |
680 | } |
681 | |
682 | void ResourceRequestBase::makeUnconditional() |
683 | { |
684 | updateResourceRequest(); |
685 | |
686 | for (auto : conditionalHeaderNames) |
687 | m_httpHeaderFields.remove(headerName); |
688 | } |
689 | |
690 | double ResourceRequestBase::defaultTimeoutInterval() |
691 | { |
692 | return s_defaultTimeoutInterval; |
693 | } |
694 | |
695 | void ResourceRequestBase::setDefaultTimeoutInterval(double timeoutInterval) |
696 | { |
697 | s_defaultTimeoutInterval = timeoutInterval; |
698 | } |
699 | |
700 | void ResourceRequestBase::updatePlatformRequest(HTTPBodyUpdatePolicy bodyPolicy) const |
701 | { |
702 | if (!m_platformRequestUpdated) { |
703 | ASSERT(m_resourceRequestUpdated); |
704 | const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest(); |
705 | m_platformRequestUpdated = true; |
706 | } |
707 | |
708 | if (!m_platformRequestBodyUpdated && bodyPolicy == HTTPBodyUpdatePolicy::UpdateHTTPBody) { |
709 | ASSERT(m_resourceRequestBodyUpdated); |
710 | const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformHTTPBody(); |
711 | m_platformRequestBodyUpdated = true; |
712 | } |
713 | } |
714 | |
715 | void ResourceRequestBase::updateResourceRequest(HTTPBodyUpdatePolicy bodyPolicy) const |
716 | { |
717 | if (!m_resourceRequestUpdated) { |
718 | ASSERT(m_platformRequestUpdated); |
719 | const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest(); |
720 | m_resourceRequestUpdated = true; |
721 | } |
722 | |
723 | if (!m_resourceRequestBodyUpdated && bodyPolicy == HTTPBodyUpdatePolicy::UpdateHTTPBody) { |
724 | ASSERT(m_platformRequestBodyUpdated); |
725 | const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceHTTPBody(); |
726 | m_resourceRequestBodyUpdated = true; |
727 | } |
728 | } |
729 | |
730 | #if !PLATFORM(COCOA) && !USE(CFURLCONNECTION) && !USE(SOUP) |
731 | unsigned initializeMaximumHTTPConnectionCountPerHost() |
732 | { |
733 | // This is used by the loader to control the number of issued parallel load requests. |
734 | // Four seems to be a common default in HTTP frameworks. |
735 | return 4; |
736 | } |
737 | #endif |
738 | |
739 | void ResourceRequestBase::setCachePartition(const String& cachePartition) |
740 | { |
741 | #if ENABLE(CACHE_PARTITIONING) |
742 | ASSERT(!cachePartition.isNull()); |
743 | ASSERT(cachePartition == partitionName(cachePartition)); |
744 | m_cachePartition = cachePartition; |
745 | #else |
746 | UNUSED_PARAM(cachePartition); |
747 | #endif |
748 | } |
749 | |
750 | String ResourceRequestBase::partitionName(const String& domain) |
751 | { |
752 | #if ENABLE(PUBLIC_SUFFIX_LIST) |
753 | if (domain.isNull()) |
754 | return emptyString(); |
755 | String highLevel = topPrivatelyControlledDomain(domain); |
756 | if (highLevel.isNull()) |
757 | return emptyString(); |
758 | return highLevel; |
759 | #else |
760 | UNUSED_PARAM(domain); |
761 | #if ENABLE(CACHE_PARTITIONING) |
762 | #error Cache partitioning requires PUBLIC_SUFFIX_LIST |
763 | #endif |
764 | return emptyString(); |
765 | #endif |
766 | } |
767 | |
768 | } |
769 | |