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
37namespace WebCore {
38
39enum 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
48enum HTTPBodyUpdatePolicy : uint8_t {
49 DoNotUpdateHTTPBody,
50 UpdateHTTPBody
51};
52
53class ResourceRequest;
54class ResourceResponse;
55
56// Do not use this type directly. Use ResourceRequest instead.
57class ResourceRequestBase {
58 WTF_MAKE_FAST_ALLOCATED;
59public:
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 WEBCORE_EXPORT void clearPurpose();
144
145 const Vector<String>& responseContentDispositionEncodingFallbackArray() const { return m_responseContentDispositionEncodingFallbackArray; }
146 WEBCORE_EXPORT void setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2 = String(), const String& encoding3 = String());
147
148 WEBCORE_EXPORT FormData* httpBody() const;
149 WEBCORE_EXPORT bool hasUpload() const;
150 WEBCORE_EXPORT void setHTTPBody(RefPtr<FormData>&&);
151
152 bool allowCookies() const;
153 void setAllowCookies(bool allowCookies);
154
155 WEBCORE_EXPORT ResourceLoadPriority priority() const;
156 WEBCORE_EXPORT void setPriority(ResourceLoadPriority);
157
158 WEBCORE_EXPORT static String partitionName(const String& domain);
159 const String& cachePartition() const { return m_cachePartition; }
160 WEBCORE_EXPORT void setCachePartition(const String&);
161 void setDomainForCachePartition(const String& domain) { setCachePartition(partitionName(domain)); }
162
163 WEBCORE_EXPORT bool isConditional() const;
164 WEBCORE_EXPORT void makeUnconditional();
165
166 // Whether this request should be hidden from the Inspector.
167 bool hiddenFromInspector() const { return m_hiddenFromInspector; }
168 void setHiddenFromInspector(bool hiddenFromInspector) { m_hiddenFromInspector = hiddenFromInspector; }
169
170 enum class Requester : uint8_t { Unspecified, Main, XHR, Fetch, Media, ImportScripts };
171 Requester requester() const { return m_requester; }
172 void setRequester(Requester requester) { m_requester = requester; }
173
174 // Who initiated the request so the Inspector can associate it with a context. E.g. a Web Worker.
175 String initiatorIdentifier() const { return m_initiatorIdentifier; }
176 void setInitiatorIdentifier(const String& identifier) { m_initiatorIdentifier = identifier; }
177
178 // Additional information for the Inspector to be able to identify the node that initiated this request.
179 const Optional<int>& inspectorInitiatorNodeIdentifier() const { return m_inspectorInitiatorNodeIdentifier; }
180 void setInspectorInitiatorNodeIdentifier(int inspectorInitiatorNodeIdentifier) { m_inspectorInitiatorNodeIdentifier = inspectorInitiatorNodeIdentifier; }
181
182#if USE(SYSTEM_PREVIEW)
183 WEBCORE_EXPORT bool isSystemPreview() const;
184 WEBCORE_EXPORT void setSystemPreview(bool);
185
186 WEBCORE_EXPORT const IntRect& systemPreviewRect() const;
187 WEBCORE_EXPORT void setSystemPreviewRect(const IntRect&);
188#endif
189
190#if !PLATFORM(COCOA)
191 bool encodingRequiresPlatformData() const { return true; }
192#endif
193 template<class Encoder> void encodeWithoutPlatformData(Encoder&) const;
194 template<class Decoder> bool decodeWithoutPlatformData(Decoder&);
195
196 WEBCORE_EXPORT static double defaultTimeoutInterval(); // May return 0 when using platform default.
197 WEBCORE_EXPORT static void setDefaultTimeoutInterval(double);
198
199 WEBCORE_EXPORT static bool equal(const ResourceRequest&, const ResourceRequest&);
200
201protected:
202 // Used when ResourceRequest is initialized from a platform representation of the request
203 ResourceRequestBase()
204 : m_platformRequestUpdated(true)
205 , m_platformRequestBodyUpdated(true)
206 {
207 }
208
209 ResourceRequestBase(const URL& url, ResourceRequestCachePolicy policy)
210 : m_url(url)
211 , m_timeoutInterval(s_defaultTimeoutInterval)
212 , m_httpMethod("GET"_s)
213 , m_cachePolicy(policy)
214 , m_allowCookies(true)
215 , m_resourceRequestUpdated(true)
216 , m_resourceRequestBodyUpdated(true)
217 {
218 }
219
220 void updatePlatformRequest(HTTPBodyUpdatePolicy = HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody) const;
221 void updateResourceRequest(HTTPBodyUpdatePolicy = HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody) const;
222
223 template<class Encoder> void encodeBase(Encoder&) const;
224 template<class Decoder> bool decodeBase(Decoder&);
225
226 // The ResourceRequest subclass may "shadow" this method to compare platform specific fields
227 static bool platformCompare(const ResourceRequest&, const ResourceRequest&) { return true; }
228
229 URL m_url;
230 double m_timeoutInterval; // 0 is a magic value for platform default on platforms that have one.
231 URL m_firstPartyForCookies;
232 String m_httpMethod;
233 String m_initiatorIdentifier;
234 String m_cachePartition { emptyString() };
235 HTTPHeaderMap m_httpHeaderFields;
236 Vector<String> m_responseContentDispositionEncodingFallbackArray;
237 RefPtr<FormData> m_httpBody;
238 ResourceRequestCachePolicy m_cachePolicy { ResourceRequestCachePolicy::UseProtocolCachePolicy };
239 SameSiteDisposition m_sameSiteDisposition { SameSiteDisposition::Unspecified };
240 ResourceLoadPriority m_priority { ResourceLoadPriority::Low };
241 Requester m_requester { Requester::Unspecified };
242 Optional<int> m_inspectorInitiatorNodeIdentifier;
243 bool m_allowCookies { false };
244 mutable bool m_resourceRequestUpdated { false };
245 mutable bool m_platformRequestUpdated { false };
246 mutable bool m_resourceRequestBodyUpdated { false };
247 mutable bool m_platformRequestBodyUpdated { false };
248 bool m_hiddenFromInspector { false };
249 bool m_isTopSite { false };
250#if USE(SYSTEM_PREVIEW)
251 bool m_isSystemPreview { false };
252 IntRect m_systemPreviewRect;
253#endif
254
255private:
256 const ResourceRequest& asResourceRequest() const;
257
258 WEBCORE_EXPORT static double s_defaultTimeoutInterval;
259};
260
261bool equalIgnoringHeaderFields(const ResourceRequestBase&, const ResourceRequestBase&);
262
263inline bool operator==(const ResourceRequest& a, const ResourceRequest& b) { return ResourceRequestBase::equal(a, b); }
264inline bool operator!=(ResourceRequest& a, const ResourceRequest& b) { return !(a == b); }
265
266WEBCORE_EXPORT unsigned initializeMaximumHTTPConnectionCountPerHost();
267#if PLATFORM(IOS_FAMILY)
268WEBCORE_EXPORT void initializeHTTPConnectionSettingsOnStartup();
269#endif
270
271template<class Encoder>
272ALWAYS_INLINE void ResourceRequestBase::encodeBase(Encoder& encoder) const
273{
274 encoder << m_url;
275 encoder << m_timeoutInterval;
276 encoder << m_firstPartyForCookies.string();
277 encoder << m_httpMethod;
278 encoder << m_httpHeaderFields;
279 encoder << m_responseContentDispositionEncodingFallbackArray;
280 encoder.encodeEnum(m_cachePolicy);
281 encoder << m_allowCookies;
282 encoder.encodeEnum(m_sameSiteDisposition);
283 encoder << m_isTopSite;
284 encoder.encodeEnum(m_priority);
285 encoder.encodeEnum(m_requester);
286}
287
288template<class Decoder>
289ALWAYS_INLINE bool ResourceRequestBase::decodeBase(Decoder& decoder)
290{
291 if (!decoder.decode(m_url))
292 return false;
293
294 if (!decoder.decode(m_timeoutInterval))
295 return false;
296
297 String firstPartyForCookies;
298 if (!decoder.decode(firstPartyForCookies))
299 return false;
300 m_firstPartyForCookies = URL({ }, firstPartyForCookies);
301
302 if (!decoder.decode(m_httpMethod))
303 return false;
304
305 if (!decoder.decode(m_httpHeaderFields))
306 return false;
307
308 if (!decoder.decode(m_responseContentDispositionEncodingFallbackArray))
309 return false;
310
311 ResourceRequestCachePolicy cachePolicy;
312 if (!decoder.decodeEnum(cachePolicy))
313 return false;
314 m_cachePolicy = cachePolicy;
315
316 bool allowCookies;
317 if (!decoder.decode(allowCookies))
318 return false;
319 m_allowCookies = allowCookies;
320
321 SameSiteDisposition sameSiteDisposition;
322 if (!decoder.decodeEnum(sameSiteDisposition))
323 return false;
324 m_sameSiteDisposition = sameSiteDisposition;
325
326 bool isTopSite;
327 if (!decoder.decode(isTopSite))
328 return false;
329 m_isTopSite = isTopSite;
330
331 ResourceLoadPriority priority;
332 if (!decoder.decodeEnum(priority))
333 return false;
334 m_priority = priority;
335
336 if (!decoder.decodeEnum(m_requester))
337 return false;
338
339 return true;
340}
341
342template<class Encoder>
343void ResourceRequestBase::encodeWithoutPlatformData(Encoder& encoder) const
344{
345 ASSERT(!m_httpBody);
346 ASSERT(!m_platformRequestUpdated);
347 encodeBase(encoder);
348}
349
350template<class Decoder>
351bool ResourceRequestBase::decodeWithoutPlatformData(Decoder& decoder)
352{
353 return decodeBase(decoder);
354}
355
356} // namespace WebCore
357
358#endif // ResourceRequestBase_h
359