• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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