Home | History | Annotate | Download | only in url_request
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      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 <string>
      9 #include <vector>
     10 
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/message_loop/message_loop.h"
     15 #include "base/power_monitor/power_observer.h"
     16 #include "net/base/filter.h"
     17 #include "net/base/host_port_pair.h"
     18 #include "net/base/load_states.h"
     19 #include "net/base/net_export.h"
     20 #include "net/base/request_priority.h"
     21 #include "net/base/upload_progress.h"
     22 #include "net/cookies/canonical_cookie.h"
     23 #include "url/gurl.h"
     24 
     25 namespace net {
     26 
     27 class AuthChallengeInfo;
     28 class AuthCredentials;
     29 class CookieOptions;
     30 class HttpRequestHeaders;
     31 class HttpResponseInfo;
     32 class IOBuffer;
     33 struct LoadTimingInfo;
     34 class NetworkDelegate;
     35 class SSLCertRequestInfo;
     36 class SSLInfo;
     37 class URLRequest;
     38 class UploadDataStream;
     39 class URLRequestStatus;
     40 class X509Certificate;
     41 
     42 class NET_EXPORT URLRequestJob
     43     : public base::RefCounted<URLRequestJob>,
     44       public base::PowerObserver {
     45  public:
     46   explicit URLRequestJob(URLRequest* request,
     47                          NetworkDelegate* network_delegate);
     48 
     49   // Returns the request that owns this job. THIS POINTER MAY BE NULL if the
     50   // request was destroyed.
     51   URLRequest* request() const {
     52     return request_;
     53   }
     54 
     55   // Sets the upload data, most requests have no upload data, so this is a NOP.
     56   // Job types supporting upload data will override this.
     57   virtual void SetUpload(UploadDataStream* upload_data_stream);
     58 
     59   // Sets extra request headers for Job types that support request
     60   // headers. Called once before Start() is called.
     61   virtual void SetExtraRequestHeaders(const HttpRequestHeaders& headers);
     62 
     63   // Sets the priority of the job. Called once before Start() is
     64   // called, but also when the priority of the parent request changes.
     65   virtual void SetPriority(RequestPriority priority);
     66 
     67   // If any error occurs while starting the Job, NotifyStartError should be
     68   // called.
     69   // This helps ensure that all errors follow more similar notification code
     70   // paths, which should simplify testing.
     71   virtual void Start() = 0;
     72 
     73   // This function MUST somehow call NotifyDone/NotifyCanceled or some requests
     74   // will get leaked. Certain callers use that message to know when they can
     75   // delete their URLRequest object, even when doing a cancel. The default
     76   // Kill implementation calls NotifyCanceled, so it is recommended that
     77   // subclasses call URLRequestJob::Kill() after doing any additional work.
     78   //
     79   // The job should endeavor to stop working as soon as is convenient, but must
     80   // not send and complete notifications from inside this function. Instead,
     81   // complete notifications (including "canceled") should be sent from a
     82   // callback run from the message loop.
     83   //
     84   // The job is not obliged to immediately stop sending data in response to
     85   // this call, nor is it obliged to fail with "canceled" unless not all data
     86   // was sent as a result. A typical case would be where the job is almost
     87   // complete and can succeed before the canceled notification can be
     88   // dispatched (from the message loop).
     89   //
     90   // The job should be prepared to receive multiple calls to kill it, but only
     91   // one notification must be issued.
     92   virtual void Kill();
     93 
     94   // Called to detach the request from this Job.  Results in the Job being
     95   // killed off eventually. The job must not use the request pointer any more.
     96   void DetachRequest();
     97 
     98   // Called to read post-filtered data from this Job, returning the number of
     99   // bytes read, 0 when there is no more data, or -1 if there was an error.
    100   // This is just the backend for URLRequest::Read, see that function for
    101   // more info.
    102   bool Read(IOBuffer* buf, int buf_size, int* bytes_read);
    103 
    104   // Stops further caching of this request, if any. For more info, see
    105   // URLRequest::StopCaching().
    106   virtual void StopCaching();
    107 
    108   virtual bool GetFullRequestHeaders(HttpRequestHeaders* headers) const;
    109 
    110   // Called to fetch the current load state for the job.
    111   virtual LoadState GetLoadState() const;
    112 
    113   // Called to get the upload progress in bytes.
    114   virtual UploadProgress GetUploadProgress() const;
    115 
    116   // Called to fetch the charset for this request.  Only makes sense for some
    117   // types of requests. Returns true on success.  Calling this on a type that
    118   // doesn't have a charset will return false.
    119   virtual bool GetCharset(std::string* charset);
    120 
    121   // Called to get response info.
    122   virtual void GetResponseInfo(HttpResponseInfo* info);
    123 
    124   // This returns the times when events actually occurred, rather than the time
    125   // each event blocked the request.  See FixupLoadTimingInfo in url_request.h
    126   // for more information on the difference.
    127   virtual void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
    128 
    129   // Returns the cookie values included in the response, if applicable.
    130   // Returns true if applicable.
    131   // NOTE: This removes the cookies from the job, so it will only return
    132   //       useful results once per job.
    133   virtual bool GetResponseCookies(std::vector<std::string>* cookies);
    134 
    135   // Called to setup a stream filter for this request. An example of filter is
    136   // content encoding/decoding.
    137   // Subclasses should return the appropriate Filter, or NULL for no Filter.
    138   // This class takes ownership of the returned Filter.
    139   //
    140   // The default implementation returns NULL.
    141   virtual Filter* SetupFilter() const;
    142 
    143   // Called to determine if this response is a redirect.  Only makes sense
    144   // for some types of requests.  This method returns true if the response
    145   // is a redirect, and fills in the location param with the URL of the
    146   // redirect.  The HTTP status code (e.g., 302) is filled into
    147   // |*http_status_code| to signify the type of redirect.
    148   //
    149   // The caller is responsible for following the redirect by setting up an
    150   // appropriate replacement Job. Note that the redirected location may be
    151   // invalid, the caller should be sure it can handle this.
    152   //
    153   // The default implementation inspects the response_info_.
    154   virtual bool IsRedirectResponse(GURL* location, int* http_status_code);
    155 
    156   // Called to determine if it is okay to redirect this job to the specified
    157   // location.  This may be used to implement protocol-specific restrictions.
    158   // If this function returns false, then the URLRequest will fail
    159   // reporting ERR_UNSAFE_REDIRECT.
    160   virtual bool IsSafeRedirect(const GURL& location);
    161 
    162   // Called to determine if this response is asking for authentication.  Only
    163   // makes sense for some types of requests.  The caller is responsible for
    164   // obtaining the credentials passing them to SetAuth.
    165   virtual bool NeedsAuth();
    166 
    167   // Fills the authentication info with the server's response.
    168   virtual void GetAuthChallengeInfo(
    169       scoped_refptr<AuthChallengeInfo>* auth_info);
    170 
    171   // Resend the request with authentication credentials.
    172   virtual void SetAuth(const AuthCredentials& credentials);
    173 
    174   // Display the error page without asking for credentials again.
    175   virtual void CancelAuth();
    176 
    177   virtual void ContinueWithCertificate(X509Certificate* client_cert);
    178 
    179   // Continue processing the request ignoring the last error.
    180   virtual void ContinueDespiteLastError();
    181 
    182   void FollowDeferredRedirect();
    183 
    184   // Returns true if the Job is done producing response data and has called
    185   // NotifyDone on the request.
    186   bool is_done() const { return done_; }
    187 
    188   // Get/Set expected content size
    189   int64 expected_content_size() const { return expected_content_size_; }
    190   void set_expected_content_size(const int64& size) {
    191     expected_content_size_ = size;
    192   }
    193 
    194   // Whether we have processed the response for that request yet.
    195   bool has_response_started() const { return has_handled_response_; }
    196 
    197   // These methods are not applicable to all connections.
    198   virtual bool GetMimeType(std::string* mime_type) const;
    199   virtual int GetResponseCode() const;
    200 
    201   // Returns the socket address for the connection.
    202   // See url_request.h for details.
    203   virtual HostPortPair GetSocketAddress() const;
    204 
    205   // base::PowerObserver methods:
    206   // We invoke URLRequestJob::Kill on suspend (crbug.com/4606).
    207   virtual void OnSuspend() OVERRIDE;
    208 
    209   // Called after a NetworkDelegate has been informed that the URLRequest
    210   // will be destroyed. This is used to track that no pending callbacks
    211   // exist at destruction time of the URLRequestJob, unless they have been
    212   // canceled by an explicit NetworkDelegate::NotifyURLRequestDestroyed() call.
    213   virtual void NotifyURLRequestDestroyed();
    214 
    215  protected:
    216   friend class base::RefCounted<URLRequestJob>;
    217   virtual ~URLRequestJob();
    218 
    219   // Notifies the job that a certificate is requested.
    220   void NotifyCertificateRequested(SSLCertRequestInfo* cert_request_info);
    221 
    222   // Notifies the job about an SSL certificate error.
    223   void NotifySSLCertificateError(const SSLInfo& ssl_info, bool fatal);
    224 
    225   // Delegates to URLRequest::Delegate.
    226   bool CanGetCookies(const CookieList& cookie_list) const;
    227 
    228   // Delegates to URLRequest::Delegate.
    229   bool CanSetCookie(const std::string& cookie_line,
    230                     CookieOptions* options) const;
    231 
    232   // Delegates to URLRequest::Delegate.
    233   bool CanEnablePrivacyMode() const;
    234 
    235   // Notifies the job that headers have been received.
    236   void NotifyHeadersComplete();
    237 
    238   // Notifies the request that the job has completed a Read operation.
    239   void NotifyReadComplete(int bytes_read);
    240 
    241   // Notifies the request that a start error has occurred.
    242   void NotifyStartError(const URLRequestStatus& status);
    243 
    244   // NotifyDone marks when we are done with a request.  It is really
    245   // a glorified set_status, but also does internal state checking and
    246   // job tracking.  It should be called once per request, when the job is
    247   // finished doing all IO.
    248   void NotifyDone(const URLRequestStatus& status);
    249 
    250   // Some work performed by NotifyDone must be completed on a separate task
    251   // so as to avoid re-entering the delegate.  This method exists to perform
    252   // that work.
    253   void CompleteNotifyDone();
    254 
    255   // Used as an asynchronous callback for Kill to notify the URLRequest
    256   // that we were canceled.
    257   void NotifyCanceled();
    258 
    259   // Notifies the job the request should be restarted.
    260   // Should only be called if the job has not started a resposne.
    261   void NotifyRestartRequired();
    262 
    263   // Called when the network delegate blocks or unblocks this request when
    264   // intercepting certain requests.
    265   void SetBlockedOnDelegate();
    266   void SetUnblockedOnDelegate();
    267 
    268   // Called to read raw (pre-filtered) data from this Job.
    269   // If returning true, data was read from the job.  buf will contain
    270   // the data, and bytes_read will receive the number of bytes read.
    271   // If returning true, and bytes_read is returned as 0, there is no
    272   // additional data to be read.
    273   // If returning false, an error occurred or an async IO is now pending.
    274   // If async IO is pending, the status of the request will be
    275   // URLRequestStatus::IO_PENDING, and buf must remain available until the
    276   // operation is completed.  See comments on URLRequest::Read for more
    277   // info.
    278   virtual bool ReadRawData(IOBuffer* buf, int buf_size, int *bytes_read);
    279 
    280   // Called to tell the job that a filter has successfully reached the end of
    281   // the stream.
    282   virtual void DoneReading();
    283 
    284   // Informs the filter that data has been read into its buffer
    285   void FilteredDataRead(int bytes_read);
    286 
    287   // Reads filtered data from the request.  Returns true if successful,
    288   // false otherwise.  Note, if there is not enough data received to
    289   // return data, this call can issue a new async IO request under
    290   // the hood.
    291   bool ReadFilteredData(int *bytes_read);
    292 
    293   // Whether the response is being filtered in this job.
    294   // Only valid after NotifyHeadersComplete() has been called.
    295   bool HasFilter() { return filter_ != NULL; }
    296 
    297   // At or near destruction time, a derived class may request that the filters
    298   // be destroyed so that statistics can be gathered while the derived class is
    299   // still present to assist in calculations.  This is used by URLRequestHttpJob
    300   // to get SDCH to emit stats.
    301   void DestroyFilters() { filter_.reset(); }
    302 
    303   // Provides derived classes with access to the request's network delegate.
    304   NetworkDelegate* network_delegate() { return network_delegate_; }
    305 
    306   // The status of the job.
    307   const URLRequestStatus GetStatus();
    308 
    309   // Set the status of the job.
    310   void SetStatus(const URLRequestStatus& status);
    311 
    312   // The number of bytes read before passing to the filter.
    313   int prefilter_bytes_read() const { return prefilter_bytes_read_; }
    314 
    315   // The number of bytes read after passing through the filter.
    316   int postfilter_bytes_read() const { return postfilter_bytes_read_; }
    317 
    318   // Total number of bytes read from network (or cache) and typically handed
    319   // to filter to process.  Used to histogram compression ratios, and error
    320   // recovery scenarios in filters.
    321   int64 filter_input_byte_count() const { return filter_input_byte_count_; }
    322 
    323   // The request that initiated this job. This value MAY BE NULL if the
    324   // request was released by DetachRequest().
    325   URLRequest* request_;
    326 
    327  private:
    328   // When data filtering is enabled, this function is used to read data
    329   // for the filter.  Returns true if raw data was read.  Returns false if
    330   // an error occurred (or we are waiting for IO to complete).
    331   bool ReadRawDataForFilter(int *bytes_read);
    332 
    333   // Invokes ReadRawData and records bytes read if the read completes
    334   // synchronously.
    335   bool ReadRawDataHelper(IOBuffer* buf, int buf_size, int* bytes_read);
    336 
    337   // Called in response to a redirect that was not canceled to follow the
    338   // redirect. The current job will be replaced with a new job loading the
    339   // given redirect destination.
    340   void FollowRedirect(const GURL& location, int http_status_code);
    341 
    342   // Called after every raw read. If |bytes_read| is > 0, this indicates
    343   // a successful read of |bytes_read| unfiltered bytes. If |bytes_read|
    344   // is 0, this indicates that there is no additional data to read. If
    345   // |bytes_read| is < 0, an error occurred and no bytes were read.
    346   void OnRawReadComplete(int bytes_read);
    347 
    348   // Updates the profiling info and notifies observers that an additional
    349   // |bytes_read| unfiltered bytes have been read for this job.
    350   void RecordBytesRead(int bytes_read);
    351 
    352   // Called to query whether there is data available in the filter to be read
    353   // out.
    354   bool FilterHasData();
    355 
    356   // Subclasses may implement this method to record packet arrival times.
    357   // The default implementation does nothing.
    358   virtual void UpdatePacketReadTimes();
    359 
    360   // Custom handler for derived classes when the request is detached.
    361   virtual void OnDetachRequest() {}
    362 
    363   // Indicates that the job is done producing data, either it has completed
    364   // all the data or an error has been encountered. Set exclusively by
    365   // NotifyDone so that it is kept in sync with the request.
    366   bool done_;
    367 
    368   int prefilter_bytes_read_;
    369   int postfilter_bytes_read_;
    370   int64 filter_input_byte_count_;
    371 
    372   // The data stream filter which is enabled on demand.
    373   scoped_ptr<Filter> filter_;
    374 
    375   // If the filter filled its output buffer, then there is a change that it
    376   // still has internal data to emit, and this flag is set.
    377   bool filter_needs_more_output_space_;
    378 
    379   // When we filter data, we receive data into the filter buffers.  After
    380   // processing the filtered data, we return the data in the caller's buffer.
    381   // While the async IO is in progress, we save the user buffer here, and
    382   // when the IO completes, we fill this in.
    383   scoped_refptr<IOBuffer> filtered_read_buffer_;
    384   int filtered_read_buffer_len_;
    385 
    386   // We keep a pointer to the read buffer while asynchronous reads are
    387   // in progress, so we are able to pass those bytes to job observers.
    388   scoped_refptr<IOBuffer> raw_read_buffer_;
    389 
    390   // Used by HandleResponseIfNecessary to track whether we've sent the
    391   // OnResponseStarted callback and potentially redirect callbacks as well.
    392   bool has_handled_response_;
    393 
    394   // Expected content size
    395   int64 expected_content_size_;
    396 
    397   // Set when a redirect is deferred.
    398   GURL deferred_redirect_url_;
    399   int deferred_redirect_status_code_;
    400 
    401   // The network delegate to use with this request, if any.
    402   NetworkDelegate* network_delegate_;
    403 
    404   base::WeakPtrFactory<URLRequestJob> weak_factory_;
    405 
    406   DISALLOW_COPY_AND_ASSIGN(URLRequestJob);
    407 };
    408 
    409 }  // namespace net
    410 
    411 #endif  // NET_URL_REQUEST_URL_REQUEST_JOB_H_
    412