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