[GTK] Epiphany (GNOME Web) says "Error downloading: Service Unavailable." when trying...
[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 "URL.h"
34 #include "ResourceLoadPriority.h"
35
36 namespace WebCore {
37
38 enum ResourceRequestCachePolicy {
39     UseProtocolCachePolicy, // normal load, equivalent to fetch "default" cache mode.
40     ReloadIgnoringCacheData, // reload, equivalent to fetch "reload"cache mode.
41     ReturnCacheDataElseLoad, // back/forward or encoding change - allow stale data, equivalent to fetch "force-cache" cache mode.
42     ReturnCacheDataDontLoad, // results of a post - allow stale data and only use cache, equivalent to fetch "only-if-cached" cache mode.
43     DoNotUseAnyCache, // Bypass the cache entirely, equivalent to fetch "no-store" cache mode.
44     RefreshAnyCacheData, // Serve cache data only if revalidated, equivalent to fetch "no-cache" mode.
45 };
46
47 enum HTTPBodyUpdatePolicy {
48     DoNotUpdateHTTPBody,
49     UpdateHTTPBody
50 };
51
52 class ResourceRequest;
53 class ResourceResponse;
54
55 // Do not use this type directly.  Use ResourceRequest instead.
56 class ResourceRequestBase {
57     WTF_MAKE_FAST_ALLOCATED;
58 public:
59     ResourceRequest isolatedCopy() const;
60     WEBCORE_EXPORT void setAsIsolatedCopy(const ResourceRequest&);
61
62     WEBCORE_EXPORT bool isNull() const;
63     WEBCORE_EXPORT bool isEmpty() const;
64
65     WEBCORE_EXPORT const URL& url() const;
66     WEBCORE_EXPORT void setURL(const URL& url);
67
68     WEBCORE_EXPORT ResourceRequest redirectedRequest(const ResourceResponse&, bool shouldClearReferrerOnHTTPSToHTTPRedirect) const;
69
70     WEBCORE_EXPORT void removeCredentials();
71
72     WEBCORE_EXPORT ResourceRequestCachePolicy cachePolicy() const;
73     WEBCORE_EXPORT void setCachePolicy(ResourceRequestCachePolicy cachePolicy);
74     
75     double timeoutInterval() const; // May return 0 when using platform default.
76     void setTimeoutInterval(double timeoutInterval);
77     
78     WEBCORE_EXPORT const URL& firstPartyForCookies() const;
79     WEBCORE_EXPORT void setFirstPartyForCookies(const URL&);
80
81     // Same-Site cookies; see <https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-2.1>
82     // and <https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-5.2>.
83     // FIXME: For some reason the main resource request may be updated more than once. We start off as Unspecified
84     // to detect if we need to compute the same-site and top-site state or not. See FIXME in DocumentLoader::startLoadingMainResource().
85     enum class SameSiteDisposition { Unspecified, SameSite, CrossSite };
86     bool isSameSiteUnspecified() const { return m_sameSiteDisposition == SameSiteDisposition::Unspecified; }
87     WEBCORE_EXPORT bool isSameSite() const; // Whether this request's registrable domain matches the request's initiator's "site for cookies".
88     WEBCORE_EXPORT void setIsSameSite(bool);
89     WEBCORE_EXPORT bool isTopSite() const; // Whether this request is for a top-level navigation.
90     WEBCORE_EXPORT void setIsTopSite(bool);
91
92     WEBCORE_EXPORT const String& httpMethod() const;
93     WEBCORE_EXPORT void setHTTPMethod(const String& httpMethod);
94     
95     WEBCORE_EXPORT const HTTPHeaderMap& httpHeaderFields() const;
96     WEBCORE_EXPORT void setHTTPHeaderFields(HTTPHeaderMap);
97
98     WEBCORE_EXPORT String httpHeaderField(const String& name) const;
99     WEBCORE_EXPORT String httpHeaderField(HTTPHeaderName) const;
100     WEBCORE_EXPORT void setHTTPHeaderField(const String& name, const String& value);
101     WEBCORE_EXPORT void setHTTPHeaderField(HTTPHeaderName, const String& value);
102     WEBCORE_EXPORT void addHTTPHeaderField(HTTPHeaderName, const String& value);
103     WEBCORE_EXPORT void addHTTPHeaderField(const String& name, const String& value);
104     WEBCORE_EXPORT void addHTTPHeaderFieldIfNotPresent(HTTPHeaderName, const String&);
105
106     WEBCORE_EXPORT bool hasHTTPHeaderField(HTTPHeaderName) const;
107
108     // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead.
109     template<size_t length> String httpHeaderField(const char (&)[length]) const = delete;
110     template<size_t length> void setHTTPHeaderField(const char (&)[length], const String&) = delete;
111     template<size_t length> void addHTTPHeaderField(const char (&)[length], const String&) = delete;
112
113     WEBCORE_EXPORT void clearHTTPAuthorization();
114
115     WEBCORE_EXPORT String httpContentType() const;
116     WEBCORE_EXPORT void setHTTPContentType(const String&);
117     WEBCORE_EXPORT void clearHTTPContentType();
118
119     bool hasHTTPHeader(HTTPHeaderName) const;
120
121     WEBCORE_EXPORT String httpReferrer() const;
122     bool hasHTTPReferrer() const;
123     WEBCORE_EXPORT void setHTTPReferrer(const String&);
124     WEBCORE_EXPORT void setExistingHTTPReferrerToOriginString();
125     WEBCORE_EXPORT void clearHTTPReferrer();
126
127     WEBCORE_EXPORT String httpOrigin() const;
128     bool hasHTTPOrigin() const;
129     void setHTTPOrigin(const String&);
130     WEBCORE_EXPORT void clearHTTPOrigin();
131
132     WEBCORE_EXPORT String httpUserAgent() const;
133     WEBCORE_EXPORT void setHTTPUserAgent(const String&);
134     void clearHTTPUserAgent();
135
136     String httpAccept() const;
137     void setHTTPAccept(const String&);
138     void clearHTTPAccept();
139
140     void clearHTTPAcceptEncoding();
141
142     const Vector<String>& responseContentDispositionEncodingFallbackArray() const { return m_responseContentDispositionEncodingFallbackArray; }
143     WEBCORE_EXPORT void setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2 = String(), const String& encoding3 = String());
144
145     WEBCORE_EXPORT FormData* httpBody() const;
146     WEBCORE_EXPORT void setHTTPBody(RefPtr<FormData>&&);
147
148     bool allowCookies() const;
149     void setAllowCookies(bool allowCookies);
150
151     WEBCORE_EXPORT ResourceLoadPriority priority() const;
152     WEBCORE_EXPORT void setPriority(ResourceLoadPriority);
153
154     WEBCORE_EXPORT static String partitionName(const String& domain);
155     const String& cachePartition() const { return m_cachePartition; }
156     WEBCORE_EXPORT void setCachePartition(const String&);
157     void setDomainForCachePartition(const String& domain) { setCachePartition(partitionName(domain)); }
158
159     WEBCORE_EXPORT bool isConditional() const;
160     WEBCORE_EXPORT void makeUnconditional();
161
162     // Whether this request should be hidden from the Inspector.
163     bool hiddenFromInspector() const { return m_hiddenFromInspector; }
164     void setHiddenFromInspector(bool hiddenFromInspector) { m_hiddenFromInspector = hiddenFromInspector; }
165
166     enum class Requester { Unspecified, Main, XHR, Fetch, Media };
167     Requester requester() const { return m_requester; }
168     void setRequester(Requester requester) { m_requester = requester; }
169
170     // Who initiated the request so the Inspector can associate it with a context. E.g. a Web Worker.
171     String initiatorIdentifier() const { return m_initiatorIdentifier; }
172     void setInitiatorIdentifier(const String& identifier) { m_initiatorIdentifier = identifier; }
173
174 #if !PLATFORM(COCOA)
175     bool encodingRequiresPlatformData() const { return true; }
176 #endif
177     template<class Encoder> void encodeWithoutPlatformData(Encoder&) const;
178     template<class Decoder> bool decodeWithoutPlatformData(Decoder&);
179
180     WEBCORE_EXPORT static double defaultTimeoutInterval(); // May return 0 when using platform default.
181     WEBCORE_EXPORT static void setDefaultTimeoutInterval(double);
182
183     WEBCORE_EXPORT static bool equal(const ResourceRequest&, const ResourceRequest&);
184
185 protected:
186     // Used when ResourceRequest is initialized from a platform representation of the request
187     ResourceRequestBase()
188         : m_platformRequestUpdated(true)
189         , m_platformRequestBodyUpdated(true)
190     {
191     }
192
193     ResourceRequestBase(const URL& url, ResourceRequestCachePolicy policy)
194         : m_url(url)
195         , m_timeoutInterval(s_defaultTimeoutInterval)
196         , m_httpMethod(ASCIILiteral("GET"))
197         , m_cachePolicy(policy)
198         , m_allowCookies(true)
199         , m_resourceRequestUpdated(true)
200         , m_resourceRequestBodyUpdated(true)
201     {
202     }
203
204     void updatePlatformRequest(HTTPBodyUpdatePolicy = DoNotUpdateHTTPBody) const;
205     void updateResourceRequest(HTTPBodyUpdatePolicy = DoNotUpdateHTTPBody) const;
206
207     template<class Encoder> void encodeBase(Encoder&) const;
208     template<class Decoder> bool decodeBase(Decoder&);
209
210     // The ResourceRequest subclass may "shadow" this method to compare platform specific fields
211     static bool platformCompare(const ResourceRequest&, const ResourceRequest&) { return true; }
212
213     URL m_url;
214     double m_timeoutInterval; // 0 is a magic value for platform default on platforms that have one.
215     URL m_firstPartyForCookies;
216     String m_httpMethod;
217     HTTPHeaderMap m_httpHeaderFields;
218     Vector<String> m_responseContentDispositionEncodingFallbackArray;
219     RefPtr<FormData> m_httpBody;
220     ResourceRequestCachePolicy m_cachePolicy { UseProtocolCachePolicy };
221     bool m_allowCookies { false };
222     mutable bool m_resourceRequestUpdated { false };
223     mutable bool m_platformRequestUpdated { false };
224     mutable bool m_resourceRequestBodyUpdated { false };
225     mutable bool m_platformRequestBodyUpdated { false };
226     bool m_hiddenFromInspector { false };
227     SameSiteDisposition m_sameSiteDisposition { SameSiteDisposition::Unspecified };
228     bool m_isTopSite { false };
229     ResourceLoadPriority m_priority { ResourceLoadPriority::Low };
230     Requester m_requester { Requester::Unspecified };
231     String m_initiatorIdentifier;
232     String m_cachePartition { emptyString() };
233
234 private:
235     const ResourceRequest& asResourceRequest() const;
236
237     WEBCORE_EXPORT static double s_defaultTimeoutInterval;
238 };
239
240 bool equalIgnoringHeaderFields(const ResourceRequestBase&, const ResourceRequestBase&);
241
242 // FIXME: Find a better place for these functions.
243 inline bool registrableDomainsAreEqual(const URL& a, const URL& b)
244 {
245     return ResourceRequestBase::partitionName(a.host()) == ResourceRequestBase::partitionName(b.host());
246 }
247 inline bool registrableDomainsAreEqual(const URL& a, const String& registrableDomain)
248 {
249     return ResourceRequestBase::partitionName(a.host()) == registrableDomain;
250 }
251
252 inline bool operator==(const ResourceRequest& a, const ResourceRequest& b) { return ResourceRequestBase::equal(a, b); }
253 inline bool operator!=(ResourceRequest& a, const ResourceRequest& b) { return !(a == b); }
254
255 WEBCORE_EXPORT unsigned initializeMaximumHTTPConnectionCountPerHost();
256 #if PLATFORM(IOS)
257 WEBCORE_EXPORT void initializeHTTPConnectionSettingsOnStartup();
258 #endif
259
260 template<class Encoder>
261 ALWAYS_INLINE void ResourceRequestBase::encodeBase(Encoder& encoder) const
262 {
263     encoder << m_url;
264     encoder << m_timeoutInterval;
265     encoder << m_firstPartyForCookies.string();
266     encoder << m_httpMethod;
267     encoder << m_httpHeaderFields;
268     encoder << m_responseContentDispositionEncodingFallbackArray;
269     encoder.encodeEnum(m_cachePolicy);
270     encoder << m_allowCookies;
271     encoder.encodeEnum(m_sameSiteDisposition);
272     encoder << m_isTopSite;
273     encoder.encodeEnum(m_priority);
274     encoder.encodeEnum(m_requester);
275 }
276
277 template<class Decoder>
278 ALWAYS_INLINE bool ResourceRequestBase::decodeBase(Decoder& decoder)
279 {
280     if (!decoder.decode(m_url))
281         return false;
282
283     if (!decoder.decode(m_timeoutInterval))
284         return false;
285
286     String firstPartyForCookies;
287     if (!decoder.decode(firstPartyForCookies))
288         return false;
289     m_firstPartyForCookies = URL(ParsedURLString, firstPartyForCookies);
290
291     if (!decoder.decode(m_httpMethod))
292         return false;
293
294     if (!decoder.decode(m_httpHeaderFields))
295         return false;
296
297     if (!decoder.decode(m_responseContentDispositionEncodingFallbackArray))
298         return false;
299
300     ResourceRequestCachePolicy cachePolicy;
301     if (!decoder.decodeEnum(cachePolicy))
302         return false;
303     m_cachePolicy = cachePolicy;
304
305     bool allowCookies;
306     if (!decoder.decode(allowCookies))
307         return false;
308     m_allowCookies = allowCookies;
309
310     SameSiteDisposition sameSiteDisposition;
311     if (!decoder.decodeEnum(sameSiteDisposition))
312         return false;
313     m_sameSiteDisposition = sameSiteDisposition;
314
315     bool isTopSite;
316     if (!decoder.decode(isTopSite))
317         return false;
318     m_isTopSite = isTopSite;
319
320     ResourceLoadPriority priority;
321     if (!decoder.decodeEnum(priority))
322         return false;
323     m_priority = priority;
324
325     if (!decoder.decodeEnum(m_requester))
326         return false;
327
328     return true;
329 }
330
331 template<class Encoder>
332 void ResourceRequestBase::encodeWithoutPlatformData(Encoder& encoder) const
333 {
334     ASSERT(!m_httpBody);
335     ASSERT(!m_platformRequestUpdated);
336     encodeBase(encoder);
337 }
338
339 template<class Decoder>
340 bool ResourceRequestBase::decodeWithoutPlatformData(Decoder& decoder)
341 {
342     return decodeBase(decoder);
343 }
344
345 } // namespace WebCore
346
347 #endif // ResourceRequestBase_h