1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ 6 #define NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <optional> 13 #include <string> 14 #include <vector> 15 16 #include "base/compiler_specific.h" 17 #include "base/gtest_prod_util.h" 18 #include "base/memory/raw_ptr.h" 19 #include "base/memory/weak_ptr.h" 20 #include "base/time/time.h" 21 #include "net/base/auth.h" 22 #include "net/base/ip_endpoint.h" 23 #include "net/base/net_error_details.h" 24 #include "net/base/net_export.h" 25 #include "net/base/privacy_mode.h" 26 #include "net/cookies/cookie_inclusion_status.h" 27 #include "net/cookies/cookie_util.h" 28 #include "net/first_party_sets/first_party_set_metadata.h" 29 #include "net/first_party_sets/first_party_sets_cache_filter.h" 30 #include "net/http/http_request_info.h" 31 #include "net/socket/connection_attempts.h" 32 #include "net/url_request/url_request_job.h" 33 34 namespace net { 35 36 class HttpRequestHeaders; 37 class HttpResponseHeaders; 38 class HttpResponseInfo; 39 class HttpTransaction; 40 class HttpUserAgentSettings; 41 class SSLPrivateKey; 42 struct TransportInfo; 43 class UploadDataStream; 44 45 // A URLRequestJob subclass that is built on top of HttpTransaction. It 46 // provides an implementation for both HTTP and HTTPS. 47 class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob { 48 public: 49 // Creates URLRequestJob for the specified HTTP, HTTPS, WS, or WSS URL. 50 // Returns a job that returns a redirect in the case of HSTS, and returns a 51 // job that fails for unencrypted requests if current settings dont allow 52 // them. Never returns nullptr. 53 static std::unique_ptr<URLRequestJob> Create(URLRequest* request); 54 55 URLRequestHttpJob(const URLRequestHttpJob&) = delete; 56 URLRequestHttpJob& operator=(const URLRequestHttpJob&) = delete; 57 58 void SetRequestHeadersCallback(RequestHeadersCallback callback) override; 59 void SetEarlyResponseHeadersCallback( 60 ResponseHeadersCallback callback) override; 61 void SetResponseHeadersCallback(ResponseHeadersCallback callback) override; 62 void SetIsSharedDictionaryReadAllowedCallback( 63 base::RepeatingCallback<bool()> callback) override; 64 65 // An enumeration of the results of a request with respect to IP Protection. 66 // These values are persisted to logs. Entries should not be renumbered and 67 // numeric values should never be reused. 68 enum class IpProtectionJobResult { 69 // Request was not IP Protected. 70 kProtectionNotAttempted = 0, 71 // Request was IP Protected and carried via IP Protection proxies or, if 72 // the direct-only parameter is true, made directly. 73 kProtectionSuccess = 1, 74 // Request was IP Protected, but fell back to direct. 75 kDirectFallback = 2, 76 kMaxValue = kDirectFallback, 77 }; 78 79 protected: 80 URLRequestHttpJob(URLRequest* request, 81 const HttpUserAgentSettings* http_user_agent_settings); 82 83 ~URLRequestHttpJob() override; 84 85 // Overridden from URLRequestJob: 86 void SetPriority(RequestPriority priority) override; 87 void Start() override; 88 void Kill() override; 89 ConnectionAttempts GetConnectionAttempts() const override; 90 void CloseConnectionOnDestruction() override; 91 std::unique_ptr<SourceStream> SetUpSourceStream() override; 92 priority()93 RequestPriority priority() const { 94 return priority_; 95 } 96 97 private: 98 // For CookieRequestScheme histogram enum. 99 FRIEND_TEST_ALL_PREFIXES(URLRequestHttpJobTest, 100 CookieSchemeRequestSchemeHistogram); 101 102 enum CompletionCause { 103 ABORTED, 104 FINISHED 105 }; 106 107 // Used to indicate which kind of cookies are sent on which kind of requests, 108 // for use in histograms. A (non)secure set cookie means that the cookie was 109 // originally set by a (non)secure url. A (non)secure request means that the 110 // request url is (non)secure. An unset cookie scheme means that the cookie's 111 // source scheme was marked as "Unset" and thus cannot be compared with the 112 // request. 113 // These values are persisted to logs. Entries should not be renumbered and 114 // numeric values should never be reused. 115 enum class CookieRequestScheme { 116 kUnsetCookieScheme = 0, 117 kNonsecureSetNonsecureRequest, 118 kSecureSetSecureRequest, 119 kNonsecureSetSecureRequest, 120 kSecureSetNonsecureRequest, 121 122 kMaxValue = kSecureSetNonsecureRequest // Keep as the last value. 123 }; 124 125 typedef base::RefCountedData<bool> SharedBoolean; 126 127 // Shadows URLRequestJob's version of this method so we can grab cookies. 128 void NotifyHeadersComplete(); 129 130 void DestroyTransaction(); 131 132 // Computes the PrivacyMode that should be associated with this leg of the 133 // request. Must be recomputed on redirects. 134 PrivacyMode DeterminePrivacyMode() const; 135 136 void AddExtraHeaders(); 137 void AddCookieHeaderAndStart(); 138 void AnnotateAndMoveUserBlockedCookies( 139 CookieAccessResultList& maybe_included_cookies, 140 CookieAccessResultList& excluded_cookies) const; 141 void SaveCookiesAndNotifyHeadersComplete(int result); 142 143 #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) 144 // Process the DBSC header, if one exists. 145 void ProcessDeviceBoundSessionsHeader(); 146 #endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) 147 148 // Processes the Strict-Transport-Security header, if one exists. 149 void ProcessStrictTransportSecurityHeader(); 150 151 // |result| should be OK, or the request is canceled. 152 void OnHeadersReceivedCallback(int result); 153 void OnStartCompleted(int result); 154 void OnReadCompleted(int result); 155 void NotifyBeforeStartTransactionCallback( 156 int result, 157 const std::optional<HttpRequestHeaders>& headers); 158 // This just forwards the call to URLRequestJob::NotifyConnected(). 159 // We need it because that method is protected and cannot be bound in a 160 // callback in this class. 161 int NotifyConnectedCallback(const TransportInfo& info, 162 CompletionOnceCallback callback); 163 164 void RestartTransaction(); 165 void RestartTransactionForRefresh(); 166 void RestartTransactionWithAuth(const AuthCredentials& credentials); 167 168 // Overridden from URLRequestJob: 169 void SetUpload(UploadDataStream* upload) override; 170 void SetExtraRequestHeaders(const HttpRequestHeaders& headers) override; 171 LoadState GetLoadState() const override; 172 bool GetMimeType(std::string* mime_type) const override; 173 bool GetCharset(std::string* charset) override; 174 void GetResponseInfo(HttpResponseInfo* info) override; 175 void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 176 bool GetTransactionRemoteEndpoint(IPEndPoint* endpoint) const override; 177 int GetResponseCode() const override; 178 void PopulateNetErrorDetails(NetErrorDetails* details) const override; 179 bool CopyFragmentOnRedirect(const GURL& location) const override; 180 bool IsSafeRedirect(const GURL& location) override; 181 bool NeedsAuth() override; 182 std::unique_ptr<AuthChallengeInfo> GetAuthChallengeInfo() override; 183 void SetAuth(const AuthCredentials& credentials) override; 184 void CancelAuth() override; 185 void ContinueWithCertificate( 186 scoped_refptr<X509Certificate> client_cert, 187 scoped_refptr<SSLPrivateKey> client_private_key) override; 188 void ContinueDespiteLastError() override; 189 int ReadRawData(IOBuffer* buf, int buf_size) override; 190 int64_t GetTotalReceivedBytes() const override; 191 int64_t GetTotalSentBytes() const override; 192 int64_t GetReceivedBodyBytes() const override; 193 void DoneReading() override; 194 void DoneReadingRedirectResponse() override; 195 void DoneReadingRetryResponse() override; 196 bool NeedsRetryWithStorageAccess() override; 197 void SetSharedDictionaryGetter( 198 SharedDictionaryGetter shared_dictionary_getter) override; 199 200 IPEndPoint GetResponseRemoteEndpoint() const override; 201 void NotifyURLRequestDestroyed() override; 202 203 void RecordTimer(); 204 void ResetTimer(); 205 206 // Starts the transaction if extensions using the webrequest API do not 207 // object. 208 void StartTransaction(); 209 // If |result| is OK, calls StartTransactionInternal. Otherwise notifies 210 // cancellation. 211 void MaybeStartTransactionInternal(int result); 212 void StartTransactionInternal(); 213 214 void RecordCompletionHistograms(CompletionCause reason); 215 void DoneWithRequest(CompletionCause reason); 216 217 // Callback functions for Cookie Monster 218 void SetCookieHeaderAndStart(const CookieOptions& options, 219 const CookieAccessResultList& cookie_list, 220 const CookieAccessResultList& excluded_list); 221 222 // Another Cookie Monster callback 223 void OnSetCookieResult(const CookieOptions& options, 224 std::optional<CanonicalCookie> cookie, 225 std::string cookie_string, 226 CookieAccessResult access_result); 227 int num_cookie_lines_left_ = 0; 228 CookieAndLineAccessResultList set_cookie_access_result_list_; 229 230 // Some servers send the body compressed, but specify the content length as 231 // the uncompressed size. If this is the case, we return true in order 232 // to request to work around this non-adherence to the HTTP standard. 233 // |rv| is the standard return value of a read function indicating the number 234 // of bytes read or, if negative, an error code. 235 bool ShouldFixMismatchedContentLength(int rv) const; 236 237 // Returns the effective response headers, considering that they may be 238 // overridden by `override_response_headers_` or 239 // `override_response_info_::headers`. 240 HttpResponseHeaders* GetResponseHeaders() const; 241 242 // Called after getting the FirstPartySetMetadata during Start for this job. 243 void OnGotFirstPartySetMetadata( 244 FirstPartySetMetadata first_party_set_metadata, 245 FirstPartySetsCacheFilter::MatchInfo match_info); 246 247 // Returns true iff this request leg should include the Cookie header. Note 248 // that cookies may still be eventually blocked by the CookieAccessDelegate 249 // even if this method returns true. 250 bool ShouldAddCookieHeader() const; 251 252 // Returns true if we should log how many partitioned cookies are included 253 // in a request. 254 bool ShouldRecordPartitionedCookieUsage() const; 255 256 RequestPriority priority_ = DEFAULT_PRIORITY; 257 258 HttpRequestInfo request_info_; 259 260 // Used for any logic, e.g. DNS-based scheme upgrade, that needs to synthesize 261 // response info to override the real response info. Transaction should be 262 // cleared before setting. 263 std::unique_ptr<HttpResponseInfo> override_response_info_; 264 265 // Auth states for proxy and origin server. 266 AuthState proxy_auth_state_ = AUTH_STATE_DONT_NEED_AUTH; 267 AuthState server_auth_state_ = AUTH_STATE_DONT_NEED_AUTH; 268 AuthCredentials auth_credentials_; 269 270 bool read_in_progress_ = false; 271 272 std::unique_ptr<HttpTransaction> transaction_; 273 274 // This needs to be declared after `transaction_` and 275 // `override_response_info_` because `response_info_` holds a pointer that's 276 // itself owned by one of those, so `response_info_` needs to be destroyed 277 // first. 278 raw_ptr<const HttpResponseInfo> response_info_ = nullptr; 279 280 base::Time request_creation_time_; 281 282 // True when we are done doing work. 283 bool done_ = false; 284 285 // The start time for the job, ignoring re-starts. 286 base::TimeTicks start_time_; 287 288 // When the transaction finished reading the request headers. 289 base::TimeTicks receive_headers_end_; 290 291 // We allow the network delegate to modify a copy of the response headers. 292 // This prevents modifications of headers that are shared with the underlying 293 // layers of the network stack. 294 scoped_refptr<HttpResponseHeaders> override_response_headers_; 295 296 // Ordinarily the original URL's fragment is copied during redirects, unless 297 // the destination URL already has one. However, the NetworkDelegate can 298 // override this behavior by setting |preserve_fragment_on_redirect_url_|: 299 // * If set to std::nullopt, the default behavior is used. 300 // * If the final URL in the redirect chain matches 301 // |preserve_fragment_on_redirect_url_|, its fragment unchanged. So this 302 // is basically a way for the embedder to force a redirect not to copy the 303 // original URL's fragment when the original URL had one. 304 std::optional<GURL> preserve_fragment_on_redirect_url_; 305 306 // Flag used to verify that |this| is not deleted while we are awaiting 307 // a callback from the NetworkDelegate. Used as a fail-fast mechanism. 308 // True if we are waiting a callback and 309 // NetworkDelegate::NotifyURLRequestDestroyed has not been called, yet, 310 // to inform the NetworkDelegate that it may not call back. 311 bool awaiting_callback_ = false; 312 313 raw_ptr<const HttpUserAgentSettings> http_user_agent_settings_; 314 315 // Keeps track of total received bytes over the network from transactions used 316 // by this job that have already been destroyed. 317 int64_t total_received_bytes_from_previous_transactions_ = 0; 318 // Keeps track of total sent bytes over the network from transactions used by 319 // this job that have already been destroyed. 320 int64_t total_sent_bytes_from_previous_transactions_ = 0; 321 322 RequestHeadersCallback request_headers_callback_; 323 ResponseHeadersCallback early_response_headers_callback_; 324 ResponseHeadersCallback response_headers_callback_; 325 326 base::RepeatingCallback<bool()> is_shared_dictionary_read_allowed_callback_; 327 328 // The First-Party Set metadata associated with this job. Set when the job is 329 // started. 330 FirstPartySetMetadata first_party_set_metadata_; 331 332 base::WeakPtrFactory<URLRequestHttpJob> weak_factory_{this}; 333 }; 334 335 } // namespace net 336 337 #endif // NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ 338