|  | // 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_TEST_JOB_H_ | 
|  | #define NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_ | 
|  |  | 
|  | #include <string> | 
|  |  | 
|  | #include "base/memory/weak_ptr.h" | 
|  | #include "net/base/load_timing_info.h" | 
|  | #include "net/base/net_export.h" | 
|  | #include "net/url_request/url_request.h" | 
|  | #include "net/url_request/url_request_job.h" | 
|  | #include "net/url_request/url_request_job_factory.h" | 
|  |  | 
|  | namespace net { | 
|  |  | 
|  | // This job type is designed to help with simple unit tests. To use, you | 
|  | // probably want to inherit from it to set up the state you want. Then install | 
|  | // it as the protocol handler for the "test" scheme. | 
|  | // | 
|  | // It will respond to several URLs, which you can retrieve using the test_url* | 
|  | // getters, which will in turn respond with the corresponding responses returned | 
|  | // by test_data*. Any other URLs that begin with "test:" will return an error, | 
|  | // which might also be useful, you can use test_url_error() to retrieve a | 
|  | // standard one. | 
|  | // | 
|  | // You can override the known URLs or the response data by overriding Start(). | 
|  | // | 
|  | // Optionally, you can also construct test jobs to return a headers and data | 
|  | // provided to the contstructor in response to any request url. | 
|  | // | 
|  | // When a job is created, it gets put on a queue of pending test jobs. To | 
|  | // process jobs on this queue, use ProcessOnePendingMessage, which will process | 
|  | // one step of the next job. If the job is incomplete, it will be added to the | 
|  | // end of the queue. | 
|  | // | 
|  | // Optionally, you can also construct test jobs that advance automatically | 
|  | // without having to call ProcessOnePendingMessage. | 
|  | class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob { | 
|  | public: | 
|  | // Constructs a job to return one of the canned responses depending on the | 
|  | // request url, with auto advance disabled. | 
|  | URLRequestTestJob(URLRequest* request, NetworkDelegate* network_delegate); | 
|  |  | 
|  | // Constructs a job to return one of the canned responses depending on the | 
|  | // request url, optionally with auto advance enabled. | 
|  | URLRequestTestJob(URLRequest* request, | 
|  | NetworkDelegate* network_delegate, | 
|  | bool auto_advance); | 
|  |  | 
|  | // Constructs a job to return the given response regardless of the request | 
|  | // url. The headers should include the HTTP status line and use CRLF/LF as the | 
|  | // line separator. | 
|  | URLRequestTestJob(URLRequest* request, | 
|  | NetworkDelegate* network_delegate, | 
|  | const std::string& response_headers, | 
|  | const std::string& response_data, | 
|  | bool auto_advance); | 
|  |  | 
|  | ~URLRequestTestJob() override; | 
|  |  | 
|  | // The canned URLs this handler will respond to without having been | 
|  | // explicitly initialized with response headers and data. | 
|  |  | 
|  | // URL that, by default, automatically advances through each state.  Reads | 
|  | // complete synchronously. | 
|  | static GURL test_url_1(); | 
|  |  | 
|  | // URLs that, by default, must be manually advanced through each state. | 
|  | static GURL test_url_2(); | 
|  | static GURL test_url_3(); | 
|  | static GURL test_url_4(); | 
|  |  | 
|  | // URL that, by default, automatically advances through each state.  Reads | 
|  | // complete asynchronously. Has same response body as test_url_1(), which is | 
|  | // (test_data_1()). | 
|  | static GURL test_url_auto_advance_async_reads_1(); | 
|  |  | 
|  | // URL that fails with ERR_INVALID_URL. | 
|  | static GURL test_url_error(); | 
|  |  | 
|  | // Redirects to test_url_1(). | 
|  | static GURL test_url_redirect_to_url_1(); | 
|  |  | 
|  | // Redirects to test_url_2(). | 
|  | static GURL test_url_redirect_to_url_2(); | 
|  |  | 
|  | // The data that corresponds to each of the URLs above | 
|  | static std::string test_data_1(); | 
|  | static std::string test_data_2(); | 
|  | static std::string test_data_3(); | 
|  | static std::string test_data_4(); | 
|  |  | 
|  | // The headers that correspond to each of the URLs above | 
|  | static std::string test_headers(); | 
|  |  | 
|  | // The headers for a redirect response | 
|  | static std::string test_redirect_headers(); | 
|  |  | 
|  | // The headers for a redirect response to the first test url. | 
|  | static std::string test_redirect_to_url_1_headers(); | 
|  |  | 
|  | // The headers for a redirect response to the second test url. | 
|  | static std::string test_redirect_to_url_2_headers(); | 
|  |  | 
|  | // The headers for a server error response | 
|  | static std::string test_error_headers(); | 
|  |  | 
|  | // Processes one pending message from the stack, returning true if any | 
|  | // message was processed, or false if there are no more pending request | 
|  | // notifications to send. This is not applicable when using auto_advance. | 
|  | static bool ProcessOnePendingMessage(); | 
|  |  | 
|  | // With auto advance enabled, the job will advance thru the stages without | 
|  | // the caller having to call ProcessOnePendingMessage. Auto advance depends | 
|  | // on having a message loop running. The default is to not auto advance. | 
|  | // Should not be altered after the job has started. | 
|  | bool auto_advance() { return auto_advance_; } | 
|  | void set_auto_advance(bool auto_advance) { auto_advance_ = auto_advance; } | 
|  |  | 
|  | void set_load_timing_info(const LoadTimingInfo& load_timing_info) { | 
|  | load_timing_info_ = load_timing_info; | 
|  | } | 
|  |  | 
|  | RequestPriority priority() const { return priority_; } | 
|  |  | 
|  | // Create a protocol handler for callers that don't subclass. | 
|  | static std::unique_ptr<URLRequestJobFactory::ProtocolHandler> | 
|  | CreateProtocolHandler(); | 
|  |  | 
|  | // Job functions | 
|  | void SetPriority(RequestPriority priority) override; | 
|  | void Start() override; | 
|  | int ReadRawData(IOBuffer* buf, int buf_size) override; | 
|  | void Kill() override; | 
|  | bool GetMimeType(std::string* mime_type) const override; | 
|  | void GetResponseInfo(HttpResponseInfo* info) override; | 
|  | void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; | 
|  | int64_t GetTotalReceivedBytes() const override; | 
|  | bool IsRedirectResponse(GURL* location, | 
|  | int* http_status_code, | 
|  | bool* insecure_scheme_was_upgraded) override; | 
|  |  | 
|  | protected: | 
|  | // Override to specify whether the next read done from this job will | 
|  | // return IO pending.  This controls whether or not the WAITING state will | 
|  | // transition back to WAITING or to DATA_AVAILABLE after an asynchronous | 
|  | // read is processed. | 
|  | virtual bool NextReadAsync(); | 
|  |  | 
|  | // This is what operation we are going to do next when this job is handled. | 
|  | // When the stage is DONE, this job will not be put on the queue. | 
|  | enum Stage { WAITING, DATA_AVAILABLE, ALL_DATA, DONE }; | 
|  |  | 
|  | // Call to process the next opeation, usually sending a notification, and | 
|  | // advancing the stage if necessary. THIS MAY DELETE THE OBJECT. | 
|  | void ProcessNextOperation(); | 
|  |  | 
|  | // Call to move the job along to the next operation. | 
|  | void AdvanceJob(); | 
|  |  | 
|  | // Called via InvokeLater to cause callbacks to occur after Start() returns. | 
|  | virtual void StartAsync(); | 
|  |  | 
|  | // Assigns |response_headers_| and |response_headers_length_|. | 
|  | void SetResponseHeaders(const std::string& response_headers); | 
|  |  | 
|  | // Copies as much of the response body as will into |buf|, and returns number | 
|  | // of bytes written. | 
|  | int CopyDataForRead(IOBuffer* buf, int buf_size); | 
|  |  | 
|  | bool auto_advance_; | 
|  |  | 
|  | Stage stage_; | 
|  |  | 
|  | RequestPriority priority_; | 
|  |  | 
|  | // The data to send, will be set in Start() if not provided in the explicit | 
|  | // ctor. | 
|  | std::string response_data_; | 
|  |  | 
|  | // current offset within response_data_ | 
|  | int offset_; | 
|  |  | 
|  | // Holds the buffer for an asynchronous ReadRawData call | 
|  | IOBuffer* async_buf_; | 
|  | int async_buf_size_; | 
|  |  | 
|  | LoadTimingInfo load_timing_info_; | 
|  |  | 
|  | private: | 
|  | // The headers the job should return, will be set in Start() if not provided | 
|  | // in the explicit ctor. | 
|  | scoped_refptr<HttpResponseHeaders> response_headers_; | 
|  |  | 
|  | // Original size in bytes of the response headers before decoding. | 
|  | int response_headers_length_; | 
|  |  | 
|  | bool async_reads_; | 
|  |  | 
|  | base::WeakPtrFactory<URLRequestTestJob> weak_factory_; | 
|  | }; | 
|  |  | 
|  | }  // namespace net | 
|  |  | 
|  | #endif  // NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_ |