255768d26ca69f18fdaa8ea4beb407122093425e
[WebKit-https.git] / Source / WebCore / platform / network / ResourceRequestBase.h
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 <wtf/URL.h>
35 #include "ResourceLoadPriority.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& httpHeaderFields() const;
97     WEBCORE_EXPORT void setHTTPHeaderFields(HTTPHeaderMap);
98
99     WEBCORE_EXPORT String httpHeaderField(const String& name) const;
100     WEBCORE_EXPORT String httpHeaderField(HTTPHeaderName) const;
101     WEBCORE_EXPORT void setHTTPHeaderField(const String& name, const String& value);
102     WEBCORE_EXPORT void setHTTPHeaderField(HTTPHeaderName, const String& value);
103     WEBCORE_EXPORT void addHTTPHeaderField(HTTPHeaderName, const String& value);
104     WEBCORE_EXPORT void addHTTPHeaderField(const String& name, const String& value);
105     WEBCORE_EXPORT void addHTTPHeaderFieldIfNotPresent(HTTPHeaderName, const String&);
106
107     WEBCORE_EXPORT bool hasHTTPHeaderField(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 httpHeaderField(const char (&)[length]) const = delete;
111     template<size_t length> void setHTTPHeaderField(const char (&)[length], const String&) = delete;
112     template<size_t length> void addHTTPHeaderField(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 hasHTTPHeader(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 m_httpHeaderFields;
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 equalIgnoringHeaderFields(const ResourceRequestBase&, const ResourceRequestBase&);
260
261 // FIXME: Find a better place for these functions.
262 inline String toRegistrableDomain(const URL& a)
263 {
264     auto host = a.host().toString();
265     auto registrableDomain = ResourceRequestBase::partitionName(host);
266     // Fall back to the host if we cannot determine the registrable domain.
267     return registrableDomain.isEmpty() ? host : registrableDomain;
268 }
269
270 inline bool registrableDomainsAreEqual(const URL& a, const URL& b)
271 {
272     return toRegistrableDomain(a) == toRegistrableDomain(b);
273 }
274 inline bool registrableDomainsAreEqual(const URL& a, const String& registrableDomain)
275 {
276     return toRegistrableDomain(a) == registrableDomain;
277 }
278
279 inline bool operator==(const ResourceRequest& a, const ResourceRequest& b) { return ResourceRequestBase::equal(a, b); }
280 inline bool operator!=(ResourceRequest& a, const ResourceRequest& b) { return !(a == b); }
281
282 WEBCORE_EXPORT unsigned initializeMaximumHTTPConnectionCountPerHost();
283 #if PLATFORM(IOS_FAMILY)
284 WEBCORE_EXPORT void initializeHTTPConnectionSettingsOnStartup();
285 #endif
286
287 template<class Encoder>
288 ALWAYS_INLINE void ResourceRequestBase::encodeBase(Encoder& encoder) const
289 {
290     encoder << m_url;
291     encoder << m_timeoutInterval;
292     encoder << m_firstPartyForCookies.string();
293     encoder << m_httpMethod;
294     encoder << m_httpHeaderFields;
295     encoder << m_responseContentDispositionEncodingFallbackArray;
296     encoder.encodeEnum(m_cachePolicy);
297     encoder << m_allowCookies;
298     encoder.encodeEnum(m_sameSiteDisposition);
299     encoder << m_isTopSite;
300     encoder.encodeEnum(m_priority);
301     encoder.encodeEnum(m_requester);
302 }
303
304 template<class Decoder>
305 ALWAYS_INLINE bool ResourceRequestBase::decodeBase(Decoder& decoder)
306 {
307     if (!decoder.decode(m_url))
308         return false;
309
310     if (!decoder.decode(m_timeoutInterval))
311         return false;
312
313     String firstPartyForCookies;
314     if (!decoder.decode(firstPartyForCookies))
315         return false;
316     m_firstPartyForCookies = URL({ }, firstPartyForCookies);
317
318     if (!decoder.decode(m_httpMethod))
319         return false;
320
321     if (!decoder.decode(m_httpHeaderFields))
322         return false;
323
324     if (!decoder.decode(m_responseContentDispositionEncodingFallbackArray))
325         return false;
326
327     ResourceRequestCachePolicy cachePolicy;
328     if (!decoder.decodeEnum(cachePolicy))
329         return false;
330     m_cachePolicy = cachePolicy;
331
332     bool allowCookies;
333     if (!decoder.decode(allowCookies))
334         return false;
335     m_allowCookies = allowCookies;
336
337     SameSiteDisposition sameSiteDisposition;
338     if (!decoder.decodeEnum(sameSiteDisposition))
339         return false;
340     m_sameSiteDisposition = sameSiteDisposition;
341
342     bool isTopSite;
343     if (!decoder.decode(isTopSite))
344         return false;
345     m_isTopSite = isTopSite;
346
347     ResourceLoadPriority priority;
348     if (!decoder.decodeEnum(priority))
349         return false;
350     m_priority = priority;
351
352     if (!decoder.decodeEnum(m_requester))
353         return false;
354
355     return true;
356 }
357
358 template<class Encoder>
359 void ResourceRequestBase::encodeWithoutPlatformData(Encoder& encoder) const
360 {
361     ASSERT(!m_httpBody);
362     ASSERT(!m_platformRequestUpdated);
363     encodeBase(encoder);
364 }
365
366 template<class Decoder>
367 bool ResourceRequestBase::decodeWithoutPlatformData(Decoder& decoder)
368 {
369     return decodeBase(decoder);
370 }
371
372 } // namespace WebCore
373
374 #endif // ResourceRequestBase_h