1 | /* |
2 | * Copyright (C) 2003, 2006 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> |
4 | * Copyright (C) 2009, 2012 Google Inc. All rights reserved. |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
22 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
23 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #ifndef ResourceRequestBase_h |
29 | #define ResourceRequestBase_h |
30 | |
31 | #include "FormData.h" |
32 | #include "HTTPHeaderMap.h" |
33 | #include "IntRect.h" |
34 | #include "ResourceLoadPriority.h" |
35 | #include <wtf/URL.h> |
36 | |
37 | namespace WebCore { |
38 | |
39 | enum class ResourceRequestCachePolicy : uint8_t { |
40 | UseProtocolCachePolicy, // normal load, equivalent to fetch "default" cache mode. |
41 | ReloadIgnoringCacheData, // reload, equivalent to fetch "reload"cache mode. |
42 | ReturnCacheDataElseLoad, // back/forward or encoding change - allow stale data, equivalent to fetch "force-cache" cache mode. |
43 | ReturnCacheDataDontLoad, // results of a post - allow stale data and only use cache, equivalent to fetch "only-if-cached" cache mode. |
44 | DoNotUseAnyCache, // Bypass the cache entirely, equivalent to fetch "no-store" cache mode. |
45 | RefreshAnyCacheData, // Serve cache data only if revalidated, equivalent to fetch "no-cache" mode. |
46 | }; |
47 | |
48 | enum HTTPBodyUpdatePolicy : uint8_t { |
49 | DoNotUpdateHTTPBody, |
50 | UpdateHTTPBody |
51 | }; |
52 | |
53 | class ResourceRequest; |
54 | class ResourceResponse; |
55 | |
56 | // Do not use this type directly. Use ResourceRequest instead. |
57 | class ResourceRequestBase { |
58 | WTF_MAKE_FAST_ALLOCATED; |
59 | public: |
60 | WEBCORE_EXPORT ResourceRequest isolatedCopy() const; |
61 | WEBCORE_EXPORT void setAsIsolatedCopy(const ResourceRequest&); |
62 | |
63 | WEBCORE_EXPORT bool isNull() const; |
64 | WEBCORE_EXPORT bool isEmpty() const; |
65 | |
66 | WEBCORE_EXPORT const URL& url() const; |
67 | WEBCORE_EXPORT void setURL(const URL& url); |
68 | |
69 | WEBCORE_EXPORT ResourceRequest redirectedRequest(const ResourceResponse&, bool shouldClearReferrerOnHTTPSToHTTPRedirect) const; |
70 | |
71 | WEBCORE_EXPORT void removeCredentials(); |
72 | |
73 | WEBCORE_EXPORT ResourceRequestCachePolicy cachePolicy() const; |
74 | WEBCORE_EXPORT void setCachePolicy(ResourceRequestCachePolicy cachePolicy); |
75 | |
76 | double timeoutInterval() const; // May return 0 when using platform default. |
77 | void setTimeoutInterval(double timeoutInterval); |
78 | |
79 | WEBCORE_EXPORT const URL& firstPartyForCookies() const; |
80 | WEBCORE_EXPORT void setFirstPartyForCookies(const URL&); |
81 | |
82 | // Same-Site cookies; see <https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-2.1> |
83 | // and <https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-5.2>. |
84 | // FIXME: For some reason the main resource request may be updated more than once. We start off as Unspecified |
85 | // to detect if we need to compute the same-site and top-site state or not. See FIXME in DocumentLoader::startLoadingMainResource(). |
86 | enum class SameSiteDisposition : uint8_t { Unspecified, SameSite, CrossSite }; |
87 | bool isSameSiteUnspecified() const { return m_sameSiteDisposition == SameSiteDisposition::Unspecified; } |
88 | WEBCORE_EXPORT bool isSameSite() const; // Whether this request's registrable domain matches the request's initiator's "site for cookies". |
89 | WEBCORE_EXPORT void setIsSameSite(bool); |
90 | WEBCORE_EXPORT bool isTopSite() const; // Whether this request is for a top-level navigation. |
91 | WEBCORE_EXPORT void setIsTopSite(bool); |
92 | |
93 | WEBCORE_EXPORT const String& httpMethod() const; |
94 | WEBCORE_EXPORT void setHTTPMethod(const String& httpMethod); |
95 | |
96 | WEBCORE_EXPORT const HTTPHeaderMap& () const; |
97 | WEBCORE_EXPORT void (HTTPHeaderMap); |
98 | |
99 | WEBCORE_EXPORT String (const String& name) const; |
100 | WEBCORE_EXPORT String (HTTPHeaderName) const; |
101 | WEBCORE_EXPORT void (const String& name, const String& value); |
102 | WEBCORE_EXPORT void (HTTPHeaderName, const String& value); |
103 | WEBCORE_EXPORT void (HTTPHeaderName, const String& value); |
104 | WEBCORE_EXPORT void (const String& name, const String& value); |
105 | WEBCORE_EXPORT void (HTTPHeaderName, const String&); |
106 | |
107 | WEBCORE_EXPORT bool (HTTPHeaderName) const; |
108 | |
109 | // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead. |
110 | template<size_t length> String (const char (&)[length]) const = delete; |
111 | template<size_t length> void (const char (&)[length], const String&) = delete; |
112 | template<size_t length> void (const char (&)[length], const String&) = delete; |
113 | |
114 | WEBCORE_EXPORT void clearHTTPAuthorization(); |
115 | |
116 | WEBCORE_EXPORT String httpContentType() const; |
117 | WEBCORE_EXPORT void setHTTPContentType(const String&); |
118 | WEBCORE_EXPORT void clearHTTPContentType(); |
119 | |
120 | bool (HTTPHeaderName) const; |
121 | |
122 | WEBCORE_EXPORT String httpReferrer() const; |
123 | bool hasHTTPReferrer() const; |
124 | WEBCORE_EXPORT void setHTTPReferrer(const String&); |
125 | WEBCORE_EXPORT void setExistingHTTPReferrerToOriginString(); |
126 | WEBCORE_EXPORT void clearHTTPReferrer(); |
127 | |
128 | WEBCORE_EXPORT String httpOrigin() const; |
129 | bool hasHTTPOrigin() const; |
130 | void setHTTPOrigin(const String&); |
131 | WEBCORE_EXPORT void clearHTTPOrigin(); |
132 | |
133 | WEBCORE_EXPORT String httpUserAgent() const; |
134 | WEBCORE_EXPORT void setHTTPUserAgent(const String&); |
135 | void clearHTTPUserAgent(); |
136 | |
137 | String httpAccept() const; |
138 | void setHTTPAccept(const String&); |
139 | void clearHTTPAccept(); |
140 | |
141 | void clearHTTPAcceptEncoding(); |
142 | |
143 | const Vector<String>& responseContentDispositionEncodingFallbackArray() const { return m_responseContentDispositionEncodingFallbackArray; } |
144 | WEBCORE_EXPORT void setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2 = String(), const String& encoding3 = String()); |
145 | |
146 | WEBCORE_EXPORT FormData* httpBody() const; |
147 | WEBCORE_EXPORT bool hasUpload() const; |
148 | WEBCORE_EXPORT void setHTTPBody(RefPtr<FormData>&&); |
149 | |
150 | bool allowCookies() const; |
151 | void setAllowCookies(bool allowCookies); |
152 | |
153 | WEBCORE_EXPORT ResourceLoadPriority priority() const; |
154 | WEBCORE_EXPORT void setPriority(ResourceLoadPriority); |
155 | |
156 | WEBCORE_EXPORT static String partitionName(const String& domain); |
157 | const String& cachePartition() const { return m_cachePartition; } |
158 | WEBCORE_EXPORT void setCachePartition(const String&); |
159 | void setDomainForCachePartition(const String& domain) { setCachePartition(partitionName(domain)); } |
160 | |
161 | WEBCORE_EXPORT bool isConditional() const; |
162 | WEBCORE_EXPORT void makeUnconditional(); |
163 | |
164 | // Whether this request should be hidden from the Inspector. |
165 | bool hiddenFromInspector() const { return m_hiddenFromInspector; } |
166 | void setHiddenFromInspector(bool hiddenFromInspector) { m_hiddenFromInspector = hiddenFromInspector; } |
167 | |
168 | enum class Requester : uint8_t { Unspecified, Main, XHR, Fetch, Media, ImportScripts }; |
169 | Requester requester() const { return m_requester; } |
170 | void setRequester(Requester requester) { m_requester = requester; } |
171 | |
172 | // Who initiated the request so the Inspector can associate it with a context. E.g. a Web Worker. |
173 | String initiatorIdentifier() const { return m_initiatorIdentifier; } |
174 | void setInitiatorIdentifier(const String& identifier) { m_initiatorIdentifier = identifier; } |
175 | |
176 | // Additional information for the Inspector to be able to identify the node that initiated this request. |
177 | const Optional<int>& inspectorInitiatorNodeIdentifier() const { return m_inspectorInitiatorNodeIdentifier; } |
178 | void setInspectorInitiatorNodeIdentifier(int inspectorInitiatorNodeIdentifier) { m_inspectorInitiatorNodeIdentifier = inspectorInitiatorNodeIdentifier; } |
179 | |
180 | #if USE(SYSTEM_PREVIEW) |
181 | WEBCORE_EXPORT bool isSystemPreview() const; |
182 | WEBCORE_EXPORT void setSystemPreview(bool); |
183 | |
184 | WEBCORE_EXPORT const IntRect& systemPreviewRect() const; |
185 | WEBCORE_EXPORT void setSystemPreviewRect(const IntRect&); |
186 | #endif |
187 | |
188 | #if !PLATFORM(COCOA) |
189 | bool encodingRequiresPlatformData() const { return true; } |
190 | #endif |
191 | template<class Encoder> void encodeWithoutPlatformData(Encoder&) const; |
192 | template<class Decoder> bool decodeWithoutPlatformData(Decoder&); |
193 | |
194 | WEBCORE_EXPORT static double defaultTimeoutInterval(); // May return 0 when using platform default. |
195 | WEBCORE_EXPORT static void setDefaultTimeoutInterval(double); |
196 | |
197 | WEBCORE_EXPORT static bool equal(const ResourceRequest&, const ResourceRequest&); |
198 | |
199 | protected: |
200 | // Used when ResourceRequest is initialized from a platform representation of the request |
201 | ResourceRequestBase() |
202 | : m_platformRequestUpdated(true) |
203 | , m_platformRequestBodyUpdated(true) |
204 | { |
205 | } |
206 | |
207 | ResourceRequestBase(const URL& url, ResourceRequestCachePolicy policy) |
208 | : m_url(url) |
209 | , m_timeoutInterval(s_defaultTimeoutInterval) |
210 | , m_httpMethod("GET"_s ) |
211 | , m_cachePolicy(policy) |
212 | , m_allowCookies(true) |
213 | , m_resourceRequestUpdated(true) |
214 | , m_resourceRequestBodyUpdated(true) |
215 | { |
216 | } |
217 | |
218 | void updatePlatformRequest(HTTPBodyUpdatePolicy = HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody) const; |
219 | void updateResourceRequest(HTTPBodyUpdatePolicy = HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody) const; |
220 | |
221 | template<class Encoder> void encodeBase(Encoder&) const; |
222 | template<class Decoder> bool decodeBase(Decoder&); |
223 | |
224 | // The ResourceRequest subclass may "shadow" this method to compare platform specific fields |
225 | static bool platformCompare(const ResourceRequest&, const ResourceRequest&) { return true; } |
226 | |
227 | URL m_url; |
228 | double m_timeoutInterval; // 0 is a magic value for platform default on platforms that have one. |
229 | URL m_firstPartyForCookies; |
230 | String m_httpMethod; |
231 | String m_initiatorIdentifier; |
232 | String m_cachePartition { emptyString() }; |
233 | HTTPHeaderMap ; |
234 | Vector<String> m_responseContentDispositionEncodingFallbackArray; |
235 | RefPtr<FormData> m_httpBody; |
236 | ResourceRequestCachePolicy m_cachePolicy { ResourceRequestCachePolicy::UseProtocolCachePolicy }; |
237 | SameSiteDisposition m_sameSiteDisposition { SameSiteDisposition::Unspecified }; |
238 | ResourceLoadPriority m_priority { ResourceLoadPriority::Low }; |
239 | Requester m_requester { Requester::Unspecified }; |
240 | Optional<int> m_inspectorInitiatorNodeIdentifier; |
241 | bool m_allowCookies { false }; |
242 | mutable bool m_resourceRequestUpdated { false }; |
243 | mutable bool m_platformRequestUpdated { false }; |
244 | mutable bool m_resourceRequestBodyUpdated { false }; |
245 | mutable bool m_platformRequestBodyUpdated { false }; |
246 | bool m_hiddenFromInspector { false }; |
247 | bool m_isTopSite { false }; |
248 | #if USE(SYSTEM_PREVIEW) |
249 | bool m_isSystemPreview { false }; |
250 | IntRect m_systemPreviewRect; |
251 | #endif |
252 | |
253 | private: |
254 | const ResourceRequest& asResourceRequest() const; |
255 | |
256 | WEBCORE_EXPORT static double s_defaultTimeoutInterval; |
257 | }; |
258 | |
259 | bool (const ResourceRequestBase&, const ResourceRequestBase&); |
260 | |
261 | inline bool operator==(const ResourceRequest& a, const ResourceRequest& b) { return ResourceRequestBase::equal(a, b); } |
262 | inline bool operator!=(ResourceRequest& a, const ResourceRequest& b) { return !(a == b); } |
263 | |
264 | WEBCORE_EXPORT unsigned initializeMaximumHTTPConnectionCountPerHost(); |
265 | #if PLATFORM(IOS_FAMILY) |
266 | WEBCORE_EXPORT void initializeHTTPConnectionSettingsOnStartup(); |
267 | #endif |
268 | |
269 | template<class Encoder> |
270 | ALWAYS_INLINE void ResourceRequestBase::encodeBase(Encoder& encoder) const |
271 | { |
272 | encoder << m_url; |
273 | encoder << m_timeoutInterval; |
274 | encoder << m_firstPartyForCookies.string(); |
275 | encoder << m_httpMethod; |
276 | encoder << m_httpHeaderFields; |
277 | encoder << m_responseContentDispositionEncodingFallbackArray; |
278 | encoder.encodeEnum(m_cachePolicy); |
279 | encoder << m_allowCookies; |
280 | encoder.encodeEnum(m_sameSiteDisposition); |
281 | encoder << m_isTopSite; |
282 | encoder.encodeEnum(m_priority); |
283 | encoder.encodeEnum(m_requester); |
284 | } |
285 | |
286 | template<class Decoder> |
287 | ALWAYS_INLINE bool ResourceRequestBase::decodeBase(Decoder& decoder) |
288 | { |
289 | if (!decoder.decode(m_url)) |
290 | return false; |
291 | |
292 | if (!decoder.decode(m_timeoutInterval)) |
293 | return false; |
294 | |
295 | String firstPartyForCookies; |
296 | if (!decoder.decode(firstPartyForCookies)) |
297 | return false; |
298 | m_firstPartyForCookies = URL({ }, firstPartyForCookies); |
299 | |
300 | if (!decoder.decode(m_httpMethod)) |
301 | return false; |
302 | |
303 | if (!decoder.decode(m_httpHeaderFields)) |
304 | return false; |
305 | |
306 | if (!decoder.decode(m_responseContentDispositionEncodingFallbackArray)) |
307 | return false; |
308 | |
309 | ResourceRequestCachePolicy cachePolicy; |
310 | if (!decoder.decodeEnum(cachePolicy)) |
311 | return false; |
312 | m_cachePolicy = cachePolicy; |
313 | |
314 | bool allowCookies; |
315 | if (!decoder.decode(allowCookies)) |
316 | return false; |
317 | m_allowCookies = allowCookies; |
318 | |
319 | SameSiteDisposition sameSiteDisposition; |
320 | if (!decoder.decodeEnum(sameSiteDisposition)) |
321 | return false; |
322 | m_sameSiteDisposition = sameSiteDisposition; |
323 | |
324 | bool isTopSite; |
325 | if (!decoder.decode(isTopSite)) |
326 | return false; |
327 | m_isTopSite = isTopSite; |
328 | |
329 | ResourceLoadPriority priority; |
330 | if (!decoder.decodeEnum(priority)) |
331 | return false; |
332 | m_priority = priority; |
333 | |
334 | if (!decoder.decodeEnum(m_requester)) |
335 | return false; |
336 | |
337 | return true; |
338 | } |
339 | |
340 | template<class Encoder> |
341 | void ResourceRequestBase::encodeWithoutPlatformData(Encoder& encoder) const |
342 | { |
343 | ASSERT(!m_httpBody); |
344 | ASSERT(!m_platformRequestUpdated); |
345 | encodeBase(encoder); |
346 | } |
347 | |
348 | template<class Decoder> |
349 | bool ResourceRequestBase::decodeWithoutPlatformData(Decoder& decoder) |
350 | { |
351 | return decodeBase(decoder); |
352 | } |
353 | |
354 | } // namespace WebCore |
355 | |
356 | #endif // ResourceRequestBase_h |
357 | |