|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef NET_URL_REQUEST_URL_REQUEST_JOB_H_ | 
|  | #define NET_URL_REQUEST_URL_REQUEST_JOB_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/macros.h" | 
|  | #include "base/memory/weak_ptr.h" | 
|  | #include "base/optional.h" | 
|  | #include "base/power_monitor/power_observer.h" | 
|  | #include "net/base/completion_once_callback.h" | 
|  | #include "net/base/host_port_pair.h" | 
|  | #include "net/base/load_states.h" | 
|  | #include "net/base/net_error_details.h" | 
|  | #include "net/base/net_export.h" | 
|  | #include "net/base/request_priority.h" | 
|  | #include "net/cookies/canonical_cookie.h" | 
|  | #include "net/filter/source_stream.h" | 
|  | #include "net/http/http_raw_request_headers.h" | 
|  | #include "net/http/http_response_headers.h" | 
|  | #include "net/socket/connection_attempts.h" | 
|  | #include "net/url_request/redirect_info.h" | 
|  | #include "net/url_request/url_request.h" | 
|  | #include "starboard/types.h" | 
|  | #include "url/gurl.h" | 
|  |  | 
|  | namespace net { | 
|  |  | 
|  | class AuthChallengeInfo; | 
|  | class AuthCredentials; | 
|  | class CookieOptions; | 
|  | class HttpRequestHeaders; | 
|  | class HttpResponseInfo; | 
|  | class IOBuffer; | 
|  | struct LoadTimingInfo; | 
|  | class NetworkDelegate; | 
|  | class ProxyServer; | 
|  | class SSLCertRequestInfo; | 
|  | class SSLInfo; | 
|  | class SSLPrivateKey; | 
|  | class UploadDataStream; | 
|  | class URLRequestStatus; | 
|  | class X509Certificate; | 
|  |  | 
|  | class NET_EXPORT URLRequestJob : public base::PowerObserver { | 
|  | public: | 
|  | explicit URLRequestJob(URLRequest* request, | 
|  | NetworkDelegate* network_delegate); | 
|  | ~URLRequestJob() override; | 
|  |  | 
|  | // Returns the request that owns this job. | 
|  | URLRequest* request() const { | 
|  | return request_; | 
|  | } | 
|  |  | 
|  | // Sets the upload data, most requests have no upload data, so this is a NOP. | 
|  | // Job types supporting upload data will override this. | 
|  | virtual void SetUpload(UploadDataStream* upload_data_stream); | 
|  |  | 
|  | // Sets extra request headers for Job types that support request | 
|  | // headers. Called once before Start() is called. | 
|  | virtual void SetExtraRequestHeaders(const HttpRequestHeaders& headers); | 
|  |  | 
|  | // Sets the priority of the job. Called once before Start() is | 
|  | // called, but also when the priority of the parent request changes. | 
|  | virtual void SetPriority(RequestPriority priority); | 
|  |  | 
|  | // If any error occurs while starting the Job, NotifyStartError should be | 
|  | // called. | 
|  | // This helps ensure that all errors follow more similar notification code | 
|  | // paths, which should simplify testing. | 
|  | virtual void Start() = 0; | 
|  |  | 
|  | // This function MUST somehow call NotifyDone/NotifyCanceled or some requests | 
|  | // will get leaked. Certain callers use that message to know when they can | 
|  | // delete their URLRequest object, even when doing a cancel. The default | 
|  | // Kill implementation calls NotifyCanceled, so it is recommended that | 
|  | // subclasses call URLRequestJob::Kill() after doing any additional work. | 
|  | // | 
|  | // The job should endeavor to stop working as soon as is convenient, but must | 
|  | // not send and complete notifications from inside this function. Instead, | 
|  | // complete notifications (including "canceled") should be sent from a | 
|  | // callback run from the message loop. | 
|  | // | 
|  | // The job is not obliged to immediately stop sending data in response to | 
|  | // this call, nor is it obliged to fail with "canceled" unless not all data | 
|  | // was sent as a result. A typical case would be where the job is almost | 
|  | // complete and can succeed before the canceled notification can be | 
|  | // dispatched (from the message loop). | 
|  | // | 
|  | // The job should be prepared to receive multiple calls to kill it, but only | 
|  | // one notification must be issued. | 
|  | virtual void Kill(); | 
|  |  | 
|  | // Called to read post-filtered data from this Job, returning the number of | 
|  | // bytes read, 0 when there is no more data, or net error if there was an | 
|  | // error. This is just the backend for URLRequest::Read, see that function for | 
|  | // more info. | 
|  | int Read(IOBuffer* buf, int buf_size); | 
|  |  | 
|  | // Stops further caching of this request, if any. For more info, see | 
|  | // URLRequest::StopCaching(). | 
|  | virtual void StopCaching(); | 
|  |  | 
|  | virtual bool GetFullRequestHeaders(HttpRequestHeaders* headers) const; | 
|  |  | 
|  | // Get the number of bytes received from network. The values returned by this | 
|  | // will never decrease over the lifetime of the URLRequestJob. | 
|  | virtual int64_t GetTotalReceivedBytes() const; | 
|  |  | 
|  | // Get the number of bytes sent over the network. The values returned by this | 
|  | // will never decrease over the lifetime of the URLRequestJob. | 
|  | virtual int64_t GetTotalSentBytes() const; | 
|  |  | 
|  | // Called to fetch the current load state for the job. | 
|  | virtual LoadState GetLoadState() const; | 
|  |  | 
|  | // Called to fetch the charset for this request.  Only makes sense for some | 
|  | // types of requests. Returns true on success.  Calling this on a type that | 
|  | // doesn't have a charset will return false. | 
|  | virtual bool GetCharset(std::string* charset); | 
|  |  | 
|  | // Called to get response info. | 
|  | virtual void GetResponseInfo(HttpResponseInfo* info); | 
|  |  | 
|  | // This returns the times when events actually occurred, rather than the time | 
|  | // each event blocked the request.  See FixupLoadTimingInfo in url_request.h | 
|  | // for more information on the difference. | 
|  | virtual void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; | 
|  |  | 
|  | // Gets the remote endpoint that the network stack is currently fetching the | 
|  | // URL from. Returns true and fills in |endpoint| if it is available; returns | 
|  | // false and leaves |endpoint| unchanged if it is unavailable. | 
|  | virtual bool GetRemoteEndpoint(IPEndPoint* endpoint) const; | 
|  |  | 
|  | // Populates the network error details of the most recent origin that the | 
|  | // network stack makes the request to. | 
|  | virtual void PopulateNetErrorDetails(NetErrorDetails* details) const; | 
|  |  | 
|  | // Called to determine if this response is a redirect.  Only makes sense | 
|  | // for some types of requests.  This method returns true if the response | 
|  | // is a redirect, and fills in the location param with the URL of the | 
|  | // redirect.  The HTTP status code (e.g., 302) is filled into | 
|  | // |*http_status_code| to signify the type of redirect. | 
|  | // |*insecure_scheme_was_upgraded| is set to true if the scheme of this | 
|  | // request was upgraded to HTTPS due to an 'upgrade-insecure-requests' | 
|  | // policy. | 
|  | // | 
|  | // The caller is responsible for following the redirect by setting up an | 
|  | // appropriate replacement Job. Note that the redirected location may be | 
|  | // invalid, the caller should be sure it can handle this. | 
|  | // | 
|  | // The default implementation inspects the response_info_. | 
|  | virtual bool IsRedirectResponse(GURL* location, | 
|  | int* http_status_code, | 
|  | bool* insecure_scheme_was_upgraded); | 
|  |  | 
|  | // Called to determine if it is okay to copy the reference fragment from the | 
|  | // original URL (if existent) to the redirection target when the redirection | 
|  | // target has no reference fragment. | 
|  | // | 
|  | // The default implementation returns true. | 
|  | virtual bool CopyFragmentOnRedirect(const GURL& location) const; | 
|  |  | 
|  | // Called to determine if it is okay to redirect this job to the specified | 
|  | // location.  This may be used to implement protocol-specific restrictions. | 
|  | // If this function returns false, then the URLRequest will fail | 
|  | // reporting ERR_UNSAFE_REDIRECT. | 
|  | virtual bool IsSafeRedirect(const GURL& location); | 
|  |  | 
|  | // Called to determine if this response is asking for authentication.  Only | 
|  | // makes sense for some types of requests.  The caller is responsible for | 
|  | // obtaining the credentials passing them to SetAuth. | 
|  | virtual bool NeedsAuth(); | 
|  |  | 
|  | // Fills the authentication info with the server's response. | 
|  | virtual void GetAuthChallengeInfo( | 
|  | scoped_refptr<AuthChallengeInfo>* auth_info); | 
|  |  | 
|  | // Resend the request with authentication credentials. | 
|  | virtual void SetAuth(const AuthCredentials& credentials); | 
|  |  | 
|  | // Display the error page without asking for credentials again. | 
|  | virtual void CancelAuth(); | 
|  |  | 
|  | virtual void ContinueWithCertificate( | 
|  | scoped_refptr<X509Certificate> client_cert, | 
|  | scoped_refptr<SSLPrivateKey> client_private_key); | 
|  |  | 
|  | // Continue processing the request ignoring the last error. | 
|  | virtual void ContinueDespiteLastError(); | 
|  |  | 
|  | void FollowDeferredRedirect( | 
|  | const base::Optional<net::HttpRequestHeaders>& modified_request_headers); | 
|  |  | 
|  | // Returns true if the Job is done producing response data and has called | 
|  | // NotifyDone on the request. | 
|  | bool is_done() const { return done_; } | 
|  |  | 
|  | // Get/Set expected content size | 
|  | int64_t expected_content_size() const { return expected_content_size_; } | 
|  | void set_expected_content_size(const int64_t& size) { | 
|  | expected_content_size_ = size; | 
|  | } | 
|  |  | 
|  | // Whether we have processed the response for that request yet. | 
|  | bool has_response_started() const { return has_handled_response_; } | 
|  |  | 
|  | // The number of bytes read before passing to the filter. This value reflects | 
|  | // bytes read even when there is no filter. | 
|  | // TODO(caseq): this is only virtual because of StreamURLRequestJob. | 
|  | // Consider removing virtual when StreamURLRequestJob is gone. | 
|  | virtual int64_t prefilter_bytes_read() const; | 
|  |  | 
|  | // These methods are not applicable to all connections. | 
|  | virtual bool GetMimeType(std::string* mime_type) const; | 
|  | virtual int GetResponseCode() const; | 
|  |  | 
|  | // Returns the socket address for the connection. | 
|  | // See url_request.h for details. | 
|  | virtual HostPortPair GetSocketAddress() const; | 
|  |  | 
|  | // base::PowerObserver methods: | 
|  | // We invoke URLRequestJob::Kill on suspend (crbug.com/4606). | 
|  | void OnSuspend() override; | 
|  |  | 
|  | // Called after a NetworkDelegate has been informed that the URLRequest | 
|  | // will be destroyed. This is used to track that no pending callbacks | 
|  | // exist at destruction time of the URLRequestJob, unless they have been | 
|  | // canceled by an explicit NetworkDelegate::NotifyURLRequestDestroyed() call. | 
|  | virtual void NotifyURLRequestDestroyed(); | 
|  |  | 
|  | // Populates |out| with the connection attempts made at the socket layer in | 
|  | // the course of executing the URLRequestJob. Should be called after the job | 
|  | // has failed or the response headers have been received. | 
|  | virtual void GetConnectionAttempts(ConnectionAttempts* out) const; | 
|  |  | 
|  | // Sets a callback that will be invoked each time the request is about to | 
|  | // be actually sent and will receive actual request headers that are about | 
|  | // to hit the wire, including SPDY/QUIC internal headers and any additional | 
|  | // request headers set via BeforeSendHeaders hooks. | 
|  | virtual void SetRequestHeadersCallback(RequestHeadersCallback callback) {} | 
|  |  | 
|  | // Sets a callback that will be invoked each time the response is received | 
|  | // from the remote party with the actual response headers recieved. | 
|  | virtual void SetResponseHeadersCallback(ResponseHeadersCallback callback) {} | 
|  |  | 
|  | // Given |policy|, |referrer|, and |destination|, returns the | 
|  | // referrer URL mandated by |request|'s referrer policy. | 
|  | static GURL ComputeReferrerForPolicy(URLRequest::ReferrerPolicy policy, | 
|  | const GURL& original_referrer, | 
|  | const GURL& destination); | 
|  |  | 
|  | protected: | 
|  | // Notifies the job that a certificate is requested. | 
|  | void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info); | 
|  |  | 
|  | // Notifies the job about an SSL certificate error. | 
|  | void NotifySSLCertificateError(const SSLInfo& ssl_info, bool fatal); | 
|  |  | 
|  | // Delegates to URLRequest::Delegate. | 
|  | bool CanGetCookies(const CookieList& cookie_list) const; | 
|  |  | 
|  | // Delegates to URLRequest::Delegate. | 
|  | bool CanSetCookie(const net::CanonicalCookie& cookie, | 
|  | CookieOptions* options) const; | 
|  |  | 
|  | // Delegates to URLRequest::Delegate. | 
|  | bool CanEnablePrivacyMode() const; | 
|  |  | 
|  | // Notifies the job that headers have been received. | 
|  | void NotifyHeadersComplete(); | 
|  |  | 
|  | // Notifies the request that a start error has occurred. | 
|  | void NotifyStartError(const URLRequestStatus& status); | 
|  |  | 
|  | // Used as an asynchronous callback for Kill to notify the URLRequest | 
|  | // that we were canceled. | 
|  | void NotifyCanceled(); | 
|  |  | 
|  | // Notifies the job the request should be restarted. | 
|  | // Should only be called if the job has not started a response. | 
|  | void NotifyRestartRequired(); | 
|  |  | 
|  | // See corresponding functions in url_request.h. | 
|  | void OnCallToDelegate(NetLogEventType type); | 
|  | void OnCallToDelegateComplete(); | 
|  |  | 
|  | // Called to read raw (pre-filtered) data from this Job. Reads at most | 
|  | // |buf_size| bytes into |buf|. | 
|  | // Possible return values: | 
|  | //   >= 0: Read completed synchronously. Return value is the number of bytes | 
|  | //         read. 0 means eof. | 
|  | //   ERR_IO_PENDING: Read pending asynchronously. | 
|  | //                   When the read completes, |ReadRawDataComplete| should be | 
|  | //                   called. | 
|  | //   Any other negative number: Read failed synchronously. Return value is a | 
|  | //                   network error code. | 
|  | // This method might hold onto a reference to |buf| (by incrementing the | 
|  | // refcount) until the method completes or is cancelled. | 
|  | virtual int ReadRawData(IOBuffer* buf, int buf_size); | 
|  |  | 
|  | // Called to tell the job that a filter has successfully reached the end of | 
|  | // the stream. | 
|  | virtual void DoneReading(); | 
|  |  | 
|  | // Called to tell the job that the body won't be read because it's a redirect. | 
|  | // This is needed so that redirect headers can be cached even though their | 
|  | // bodies are never read. | 
|  | virtual void DoneReadingRedirectResponse(); | 
|  |  | 
|  | // Called to set up a SourceStream chain for this request. | 
|  | // Subclasses should return the appropriate last SourceStream of the chain, | 
|  | // or nullptr on error. | 
|  | virtual std::unique_ptr<SourceStream> SetUpSourceStream(); | 
|  |  | 
|  | // Provides derived classes with access to the request's network delegate. | 
|  | NetworkDelegate* network_delegate() { return network_delegate_; } | 
|  |  | 
|  | // The status of the job. | 
|  | const URLRequestStatus GetStatus(); | 
|  |  | 
|  | // Set the proxy server that was used, if any. | 
|  | void SetProxyServer(const ProxyServer& proxy_server); | 
|  |  | 
|  | // The number of bytes read after passing through the filter. This value | 
|  | // reflects bytes read even when there is no filter. | 
|  | int64_t postfilter_bytes_read() const { return postfilter_bytes_read_; } | 
|  |  | 
|  | // Turns an integer result code into an Error and a count of bytes read. | 
|  | // The semantics are: | 
|  | //   |result| >= 0: |*error| == OK, |*count| == |result| | 
|  | //   |result| < 0: |*error| = |result|, |*count| == 0 | 
|  | static void ConvertResultToError(int result, Error* error, int* count); | 
|  |  | 
|  | // Completion callback for raw reads. See |ReadRawData| for details. | 
|  | // |bytes_read| is either >= 0 to indicate a successful read and count of | 
|  | // bytes read, or < 0 to indicate an error. | 
|  | // On return, |this| may be deleted. | 
|  | void ReadRawDataComplete(int bytes_read); | 
|  |  | 
|  | // The request that initiated this job. This value will never be nullptr. | 
|  | URLRequest* const request_; | 
|  |  | 
|  | private: | 
|  | class URLRequestJobSourceStream; | 
|  |  | 
|  | // Helper method used to perform tasks after reading from |source_stream_| is | 
|  | // completed. |synchronous| true if the read completed synchronously. | 
|  | // See the documentation for |Read| above for the contract of this method. | 
|  | void SourceStreamReadComplete(bool synchronous, int result); | 
|  |  | 
|  | // Invokes ReadRawData and records bytes read if the read completes | 
|  | // synchronously. | 
|  | int ReadRawDataHelper(IOBuffer* buf, | 
|  | int buf_size, | 
|  | CompletionOnceCallback callback); | 
|  |  | 
|  | // Returns OK if |new_url| is a valid redirect target and an error code | 
|  | // otherwise. | 
|  | int CanFollowRedirect(const GURL& new_url); | 
|  |  | 
|  | // Called in response to a redirect that was not canceled to follow the | 
|  | // redirect. The current job will be replaced with a new job loading the | 
|  | // given redirect destination. | 
|  | void FollowRedirect( | 
|  | const RedirectInfo& redirect_info, | 
|  | const base::Optional<net::HttpRequestHeaders>& modified_request_headers); | 
|  |  | 
|  | // Called after every raw read. If |bytes_read| is > 0, this indicates | 
|  | // a successful read of |bytes_read| unfiltered bytes. If |bytes_read| | 
|  | // is 0, this indicates that there is no additional data to read. | 
|  | // If |bytes_read| is negative, no bytes were read. | 
|  | void GatherRawReadStats(int bytes_read); | 
|  |  | 
|  | // Updates the profiling info and notifies observers that an additional | 
|  | // |bytes_read| unfiltered bytes have been read for this job. | 
|  | void RecordBytesRead(int bytes_read); | 
|  |  | 
|  | // OnDone marks that request is done. It is really a glorified | 
|  | // set_status, but also does internal state checking and job tracking. It | 
|  | // should be called once per request, when the job is finished doing all IO. | 
|  | // | 
|  | // If |notify_done| is true, will notify the URLRequest if there was an error | 
|  | // asynchronously.  Otherwise, the caller will need to do this itself, | 
|  | // possibly through a synchronous return value. | 
|  | // TODO(mmenke):  Remove |notify_done|, and make caller handle notification. | 
|  | void OnDone(const URLRequestStatus& status, bool notify_done); | 
|  |  | 
|  | // Takes care of the notification initiated by OnDone() to avoid re-entering | 
|  | // the URLRequest::Delegate. | 
|  | void NotifyDone(); | 
|  |  | 
|  | // Subclasses may implement this method to record packet arrival times. | 
|  | // The default implementation does nothing.  Only invoked when bytes have been | 
|  | // read since the last invocation. | 
|  | virtual void UpdatePacketReadTimes(); | 
|  |  | 
|  |  | 
|  | // Notify the network delegate that more bytes have been received or sent over | 
|  | // the network, if bytes have been received or sent since the previous | 
|  | // notification. | 
|  | void MaybeNotifyNetworkBytes(); | 
|  |  | 
|  | // Indicates that the job is done producing data, either it has completed | 
|  | // all the data or an error has been encountered. Set exclusively by | 
|  | // NotifyDone so that it is kept in sync with the request. | 
|  | bool done_; | 
|  |  | 
|  | // Number of raw network bytes read from job subclass. | 
|  | int64_t prefilter_bytes_read_; | 
|  |  | 
|  | // Number of bytes after applying |source_stream_| filters. | 
|  | int64_t postfilter_bytes_read_; | 
|  |  | 
|  | // The first SourceStream of the SourceStream chain used. | 
|  | std::unique_ptr<SourceStream> source_stream_; | 
|  |  | 
|  | // Keep a reference to the buffer passed in via URLRequestJob::Read() so it | 
|  | // doesn't get destroyed when the read has not completed. | 
|  | scoped_refptr<IOBuffer> pending_read_buffer_; | 
|  |  | 
|  | // We keep a pointer to the read buffer while asynchronous reads are | 
|  | // in progress, so we are able to pass those bytes to job observers. | 
|  | scoped_refptr<IOBuffer> raw_read_buffer_; | 
|  |  | 
|  | // Used by HandleResponseIfNecessary to track whether we've sent the | 
|  | // OnResponseStarted callback and potentially redirect callbacks as well. | 
|  | bool has_handled_response_; | 
|  |  | 
|  | // Expected content size | 
|  | int64_t expected_content_size_; | 
|  |  | 
|  | // Set when a redirect is deferred. Redirects are deferred after validity | 
|  | // checks are performed, so this field must not be modified. | 
|  | base::Optional<RedirectInfo> deferred_redirect_info_; | 
|  |  | 
|  | // The network delegate to use with this request, if any. | 
|  | NetworkDelegate* network_delegate_; | 
|  |  | 
|  | // The value from GetTotalReceivedBytes() the last time | 
|  | // MaybeNotifyNetworkBytes() was called. Used to calculate how bytes have been | 
|  | // newly received since the last notification. | 
|  | int64_t last_notified_total_received_bytes_; | 
|  |  | 
|  | // The value from GetTotalSentBytes() the last time MaybeNotifyNetworkBytes() | 
|  | // was called. Used to calculate how bytes have been newly sent since the last | 
|  | // notification. | 
|  | int64_t last_notified_total_sent_bytes_; | 
|  |  | 
|  | // Non-null if ReadRawData() returned ERR_IO_PENDING, and the read has not | 
|  | // completed. | 
|  | CompletionOnceCallback read_raw_callback_; | 
|  |  | 
|  | base::WeakPtrFactory<URLRequestJob> weak_factory_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(URLRequestJob); | 
|  | }; | 
|  |  | 
|  | }  // namespace net | 
|  |  | 
|  | #endif  // NET_URL_REQUEST_URL_REQUEST_JOB_H_ |