• 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_JOB_H_
6 #define NET_URL_REQUEST_URL_REQUEST_JOB_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/memory/raw_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "net/base/completion_once_callback.h"
17 #include "net/base/completion_repeating_callback.h"
18 #include "net/base/ip_endpoint.h"
19 #include "net/base/load_states.h"
20 #include "net/base/net_error_details.h"
21 #include "net/base/net_export.h"
22 #include "net/base/privacy_mode.h"
23 #include "net/base/request_priority.h"
24 #include "net/cookies/canonical_cookie.h"
25 #include "net/cookies/cookie_setting_override.h"
26 #include "net/filter/source_stream.h"
27 #include "net/http/http_raw_request_headers.h"
28 #include "net/http/http_response_headers.h"
29 #include "net/socket/connection_attempts.h"
30 #include "net/url_request/redirect_info.h"
31 #include "net/url_request/referrer_policy.h"
32 #include "net/url_request/url_request.h"
33 #include "third_party/abseil-cpp/absl/types/optional.h"
34 #include "url/gurl.h"
35 
36 namespace net {
37 
38 class AuthChallengeInfo;
39 class AuthCredentials;
40 class CookieOptions;
41 class HttpRequestHeaders;
42 class HttpResponseInfo;
43 class IOBuffer;
44 struct LoadTimingInfo;
45 class ProxyServer;
46 class SSLCertRequestInfo;
47 class SSLInfo;
48 class SSLPrivateKey;
49 struct TransportInfo;
50 class UploadDataStream;
51 class X509Certificate;
52 
53 class NET_EXPORT URLRequestJob {
54  public:
55   explicit URLRequestJob(URLRequest* request);
56 
57   URLRequestJob(const URLRequestJob&) = delete;
58   URLRequestJob& operator=(const URLRequestJob&) = delete;
59 
60   virtual ~URLRequestJob();
61 
62   // Returns the request that owns this job.
request()63   URLRequest* request() const {
64     return request_;
65   }
66 
67   // Sets the upload data, most requests have no upload data, so this is a NOP.
68   // Job types supporting upload data will override this.
69   virtual void SetUpload(UploadDataStream* upload_data_stream);
70 
71   // Sets extra request headers for Job types that support request
72   // headers. Called once before Start() is called.
73   virtual void SetExtraRequestHeaders(const HttpRequestHeaders& headers);
74 
75   // Sets the priority of the job. Called once before Start() is
76   // called, but also when the priority of the parent request changes.
77   virtual void SetPriority(RequestPriority priority);
78 
79   // If any error occurs while starting the Job, NotifyStartError should be
80   // called asynchronously.
81   // This helps ensure that all errors follow more similar notification code
82   // paths, which should simplify testing.
83   virtual void Start() = 0;
84 
85   // This function MUST somehow call NotifyDone/NotifyCanceled or some requests
86   // will get leaked. Certain callers use that message to know when they can
87   // delete their URLRequest object, even when doing a cancel. The default
88   // Kill implementation calls NotifyCanceled, so it is recommended that
89   // subclasses call URLRequestJob::Kill() after doing any additional work.
90   //
91   // The job should endeavor to stop working as soon as is convenient, but must
92   // not send and complete notifications from inside this function. Instead,
93   // complete notifications (including "canceled") should be sent from a
94   // callback run from the message loop.
95   //
96   // The job is not obliged to immediately stop sending data in response to
97   // this call, nor is it obliged to fail with "canceled" unless not all data
98   // was sent as a result. A typical case would be where the job is almost
99   // complete and can succeed before the canceled notification can be
100   // dispatched (from the message loop).
101   //
102   // The job should be prepared to receive multiple calls to kill it, but only
103   // one notification must be issued.
104   virtual void Kill();
105 
106   // Called to read post-filtered data from this Job, returning the number of
107   // bytes read, 0 when there is no more data, or net error if there was an
108   // error. This is just the backend for URLRequest::Read, see that function for
109   // more info.
110   int Read(IOBuffer* buf, int buf_size);
111 
112   // Get the number of bytes received from network. The values returned by this
113   // will never decrease over the lifetime of the URLRequestJob.
114   virtual int64_t GetTotalReceivedBytes() const;
115 
116   // Get the number of bytes sent over the network. The values returned by this
117   // will never decrease over the lifetime of the URLRequestJob.
118   virtual int64_t GetTotalSentBytes() const;
119 
120   // Called to fetch the current load state for the job.
121   virtual LoadState GetLoadState() const;
122 
123   // Called to fetch the charset for this request.  Only makes sense for some
124   // types of requests. Returns true on success.  Calling this on a type that
125   // doesn't have a charset will return false.
126   virtual bool GetCharset(std::string* charset);
127 
128   // Called to get response info.
129   virtual void GetResponseInfo(HttpResponseInfo* info);
130 
131   // This returns the times when events actually occurred, rather than the time
132   // each event blocked the request.  See FixupLoadTimingInfo in url_request.h
133   // for more information on the difference.
134   virtual void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
135 
136   // Gets the remote endpoint that the network stack is currently fetching the
137   // URL from. Returns true and fills in |endpoint| if it is available; returns
138   // false and leaves |endpoint| unchanged if it is unavailable.
139   virtual bool GetTransactionRemoteEndpoint(IPEndPoint* endpoint) const;
140 
141   // Populates the network error details of the most recent origin that the
142   // network stack makes the request to.
143   virtual void PopulateNetErrorDetails(NetErrorDetails* details) const;
144 
145   // Called to determine if this response is a redirect.  Only makes sense
146   // for some types of requests.  This method returns true if the response
147   // is a redirect, and fills in the location param with the URL of the
148   // redirect.  The HTTP status code (e.g., 302) is filled into
149   // |*http_status_code| to signify the type of redirect.
150   // |*insecure_scheme_was_upgraded| is set to true if the scheme of this
151   // request was upgraded to HTTPS due to an 'upgrade-insecure-requests'
152   // policy.
153   //
154   // The caller is responsible for following the redirect by setting up an
155   // appropriate replacement Job. Note that the redirected location may be
156   // invalid, the caller should be sure it can handle this.
157   //
158   // The default implementation inspects the response_info_.
159   virtual bool IsRedirectResponse(GURL* location,
160                                   int* http_status_code,
161                                   bool* insecure_scheme_was_upgraded);
162 
163   // Called to determine if it is okay to copy the reference fragment from the
164   // original URL (if existent) to the redirection target when the redirection
165   // target has no reference fragment.
166   //
167   // The default implementation returns true.
168   virtual bool CopyFragmentOnRedirect(const GURL& location) const;
169 
170   // Called to determine if it is okay to redirect this job to the specified
171   // location.  This may be used to implement protocol-specific restrictions.
172   // If this function returns false, then the URLRequest will fail
173   // reporting ERR_UNSAFE_REDIRECT.
174   virtual bool IsSafeRedirect(const GURL& location);
175 
176   // Called to determine if this response is asking for authentication.  Only
177   // makes sense for some types of requests.  The caller is responsible for
178   // obtaining the credentials passing them to SetAuth.
179   virtual bool NeedsAuth();
180 
181   // Returns a copy of the authentication challenge that came with the server's
182   // response.
183   virtual std::unique_ptr<AuthChallengeInfo> GetAuthChallengeInfo();
184 
185   // Resend the request with authentication credentials.
186   virtual void SetAuth(const AuthCredentials& credentials);
187 
188   // Display the error page without asking for credentials again.
189   virtual void CancelAuth();
190 
191   virtual void ContinueWithCertificate(
192       scoped_refptr<X509Certificate> client_cert,
193       scoped_refptr<SSLPrivateKey> client_private_key);
194 
195   // Continue processing the request ignoring the last error.
196   virtual void ContinueDespiteLastError();
197 
198   void FollowDeferredRedirect(
199       const absl::optional<std::vector<std::string>>& removed_headers,
200       const absl::optional<net::HttpRequestHeaders>& modified_headers);
201 
202   // Returns true if the Job is done producing response data and has called
203   // NotifyDone on the request.
is_done()204   bool is_done() const { return done_; }
205 
206   // Get/Set expected content size
expected_content_size()207   int64_t expected_content_size() const { return expected_content_size_; }
set_expected_content_size(const int64_t & size)208   void set_expected_content_size(const int64_t& size) {
209     expected_content_size_ = size;
210   }
211 
212   // Whether we have processed the response for that request yet.
has_response_started()213   bool has_response_started() const { return has_handled_response_; }
214 
215   // The number of bytes read before passing to the filter. This value reflects
216   // bytes read even when there is no filter.
217   // TODO(caseq): this is only virtual because of StreamURLRequestJob.
218   // Consider removing virtual when StreamURLRequestJob is gone.
219   virtual int64_t prefilter_bytes_read() const;
220 
221   // These methods are not applicable to all connections.
222   virtual bool GetMimeType(std::string* mime_type) const;
223   virtual int GetResponseCode() const;
224 
225   // Returns the socket address for the connection.
226   // See url_request.h for details.
227   virtual IPEndPoint GetResponseRemoteEndpoint() const;
228 
229   // Called after a NetworkDelegate has been informed that the URLRequest
230   // will be destroyed. This is used to track that no pending callbacks
231   // exist at destruction time of the URLRequestJob, unless they have been
232   // canceled by an explicit NetworkDelegate::NotifyURLRequestDestroyed() call.
233   virtual void NotifyURLRequestDestroyed();
234 
235   // Returns the connection attempts made at the socket layer in the course of
236   // executing the URLRequestJob. Should be called after the job has failed or
237   // the response headers have been received.
238   virtual ConnectionAttempts GetConnectionAttempts() const;
239 
240   // Sets a callback that will be invoked each time the request is about to
241   // be actually sent and will receive actual request headers that are about
242   // to hit the wire, including SPDY/QUIC internal headers.
SetRequestHeadersCallback(RequestHeadersCallback callback)243   virtual void SetRequestHeadersCallback(RequestHeadersCallback callback) {}
244 
245   // Sets a callback that will be invoked each time the response is received
246   // from the remote party with the actual response headers received.
SetResponseHeadersCallback(ResponseHeadersCallback callback)247   virtual void SetResponseHeadersCallback(ResponseHeadersCallback callback) {}
248 
249   // Sets a callback that will be invoked each time a 103 Early Hints response
250   // is received from the remote party with the actual response headers
251   // received.
SetEarlyResponseHeadersCallback(ResponseHeadersCallback callback)252   virtual void SetEarlyResponseHeadersCallback(
253       ResponseHeadersCallback callback) {}
254 
255   // Causes the current transaction always close its active socket on
256   // destruction. Does not close H2/H3 sessions.
257   virtual void CloseConnectionOnDestruction();
258 
259   // Given |policy|, |original_referrer|, and |destination|, returns the
260   // referrer URL mandated by |request|'s referrer policy.
261   //
262   // If |same_origin_out_for_metrics| is non-null, saves to
263   // |*same_origin_out_for_metrics| whether |original_referrer| and
264   // |destination| are cross-origin.
265   // (This allows reporting in a UMA whether the request is same-origin, without
266   // recomputing that information.)
267   static GURL ComputeReferrerForPolicy(
268       ReferrerPolicy policy,
269       const GURL& original_referrer,
270       const GURL& destination,
271       bool* same_origin_out_for_metrics = nullptr);
272 
273  protected:
274   // Notifies the job that we are connected.
275   int NotifyConnected(const TransportInfo& info,
276                       CompletionOnceCallback callback);
277 
278   // Notifies the job that a certificate is requested.
279   void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info);
280 
281   // Notifies the job about an SSL certificate error.
282   void NotifySSLCertificateError(int net_error,
283                                  const SSLInfo& ssl_info,
284                                  bool fatal);
285 
286   // Delegates to URLRequest.
287   bool CanSetCookie(const net::CanonicalCookie& cookie,
288                     CookieOptions* options) const;
289 
290   // Notifies the job that headers have been received.
291   void NotifyHeadersComplete();
292 
293   // Called when the final set headers have been received (no more redirects to
294   // follow, and no more auth challenges that will be responded to).
295   void NotifyFinalHeadersReceived();
296 
297   // Notifies the request that a start error has occurred.
298   // NOTE: Must not be called synchronously from |Start|.
299   void NotifyStartError(int net_error);
300 
301   // Used as an asynchronous callback for Kill to notify the URLRequest
302   // that we were canceled.
303   void NotifyCanceled();
304 
305   // See corresponding functions in url_request.h.
306   void OnCallToDelegate(NetLogEventType type);
307   void OnCallToDelegateComplete();
308 
309   // Called to read raw (pre-filtered) data from this Job. Reads at most
310   // |buf_size| bytes into |buf|.
311   // Possible return values:
312   //   >= 0: Read completed synchronously. Return value is the number of bytes
313   //         read. 0 means eof.
314   //   ERR_IO_PENDING: Read pending asynchronously.
315   //                   When the read completes, |ReadRawDataComplete| should be
316   //                   called.
317   //   Any other negative number: Read failed synchronously. Return value is a
318   //                   network error code.
319   // This method might hold onto a reference to |buf| (by incrementing the
320   // refcount) until the method completes or is cancelled.
321   virtual int ReadRawData(IOBuffer* buf, int buf_size);
322 
323   // Called to tell the job that a filter has successfully reached the end of
324   // the stream.
325   virtual void DoneReading();
326 
327   // Called to tell the job that the body won't be read because it's a redirect.
328   // This is needed so that redirect headers can be cached even though their
329   // bodies are never read.
330   virtual void DoneReadingRedirectResponse();
331 
332   // Called to set up a SourceStream chain for this request.
333   // Subclasses should return the appropriate last SourceStream of the chain,
334   // or nullptr on error.
335   virtual std::unique_ptr<SourceStream> SetUpSourceStream();
336 
337   // Set the proxy server that was used, if any.
338   void SetProxyServer(const ProxyServer& proxy_server);
339 
340   // The number of bytes read after passing through the filter. This value
341   // reflects bytes read even when there is no filter.
postfilter_bytes_read()342   int64_t postfilter_bytes_read() const { return postfilter_bytes_read_; }
343 
344   // Turns an integer result code into an Error and a count of bytes read.
345   // The semantics are:
346   //   |result| >= 0: |*error| == OK, |*count| == |result|
347   //   |result| < 0: |*error| = |result|, |*count| == 0
348   static void ConvertResultToError(int result, Error* error, int* count);
349 
350   // Completion callback for raw reads. See |ReadRawData| for details.
351   // |bytes_read| is either >= 0 to indicate a successful read and count of
352   // bytes read, or < 0 to indicate an error.
353   // On return, |this| may be deleted.
354   void ReadRawDataComplete(int bytes_read);
355 
request_initiator_site()356   const absl::optional<net::SchemefulSite>& request_initiator_site() const {
357     return request_initiator_site_;
358   }
359 
360   // The request that initiated this job. This value will never be nullptr.
361   const raw_ptr<URLRequest> request_;
362 
363  private:
364   class URLRequestJobSourceStream;
365 
366   // Helper method used to perform tasks after reading from |source_stream_| is
367   // completed. |synchronous| true if the read completed synchronously.
368   // See the documentation for |Read| above for the contract of this method.
369   void SourceStreamReadComplete(bool synchronous, int result);
370 
371   // Invokes ReadRawData and records bytes read if the read completes
372   // synchronously.
373   int ReadRawDataHelper(IOBuffer* buf,
374                         int buf_size,
375                         CompletionOnceCallback callback);
376 
377   // Returns OK if |new_url| is a valid redirect target and an error code
378   // otherwise.
379   int CanFollowRedirect(const GURL& new_url);
380 
381   // Called in response to a redirect that was not canceled to follow the
382   // redirect. The current job will be replaced with a new job loading the
383   // given redirect destination.
384   void FollowRedirect(
385       const RedirectInfo& redirect_info,
386       const absl::optional<std::vector<std::string>>& removed_headers,
387       const absl::optional<net::HttpRequestHeaders>& modified_headers);
388 
389   // Called after every raw read. If |bytes_read| is > 0, this indicates
390   // a successful read of |bytes_read| unfiltered bytes. If |bytes_read|
391   // is 0, this indicates that there is no additional data to read.
392   // If |bytes_read| is negative, no bytes were read.
393   void GatherRawReadStats(int bytes_read);
394 
395   // Updates the profiling info and notifies observers that an additional
396   // |bytes_read| unfiltered bytes have been read for this job.
397   void RecordBytesRead(int bytes_read);
398 
399   // OnDone marks that request is done. It is really a glorified
400   // set_status, but also does internal state checking and job tracking. It
401   // should be called once per request, when the job is finished doing all IO.
402   //
403   // If |notify_done| is true, will notify the URLRequest if there was an error
404   // asynchronously.  Otherwise, the caller will need to do this itself,
405   // possibly through a synchronous return value.
406   // TODO(mmenke):  Remove |notify_done|, and make caller handle notification.
407   void OnDone(int net_error, bool notify_done);
408 
409   // Takes care of the notification initiated by OnDone() to avoid re-entering
410   // the URLRequest::Delegate.
411   void NotifyDone();
412 
413   // Indicates that the job is done producing data, either it has completed
414   // all the data or an error has been encountered. Set exclusively by
415   // NotifyDone so that it is kept in sync with the request.
416   bool done_ = false;
417 
418   // Number of raw network bytes read from job subclass.
419   int64_t prefilter_bytes_read_ = 0;
420 
421   // Number of bytes after applying |source_stream_| filters.
422   int64_t postfilter_bytes_read_ = 0;
423 
424   // The first SourceStream of the SourceStream chain used.
425   std::unique_ptr<SourceStream> source_stream_;
426 
427   // Keep a reference to the buffer passed in via URLRequestJob::Read() so it
428   // doesn't get destroyed when the read has not completed.
429   scoped_refptr<IOBuffer> pending_read_buffer_;
430 
431   // We keep a pointer to the read buffer while asynchronous reads are
432   // in progress, so we are able to pass those bytes to job observers.
433   scoped_refptr<IOBuffer> raw_read_buffer_;
434 
435   // Used by HandleResponseIfNecessary to track whether we've sent the
436   // OnResponseStarted callback and potentially redirect callbacks as well.
437   bool has_handled_response_ = false;
438 
439   // Expected content size
440   int64_t expected_content_size_ = -1;
441 
442   // Set when a redirect is deferred. Redirects are deferred after validity
443   // checks are performed, so this field must not be modified.
444   absl::optional<RedirectInfo> deferred_redirect_info_;
445 
446   // The request's initiator never changes, so we store it in format of
447   // SchemefulSite so that we don't recompute (including looking up the
448   // registrable domain) it during every redirect.
449   absl::optional<net::SchemefulSite> request_initiator_site_;
450 
451   // Non-null if ReadRawData() returned ERR_IO_PENDING, and the read has not
452   // completed.
453   CompletionOnceCallback read_raw_callback_;
454 
455   base::WeakPtrFactory<URLRequestJob> weak_factory_{this};
456 };
457 
458 }  // namespace net
459 
460 #endif  // NET_URL_REQUEST_URL_REQUEST_JOB_H_
461