| 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 | |