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_TEST_JOB_H_ 6 #define NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_ 7 8 #include <string> 9 10 #include "base/memory/weak_ptr.h" 11 #include "net/base/load_timing_info.h" 12 #include "net/url_request/url_request.h" 13 #include "net/url_request/url_request_job.h" 14 #include "net/url_request/url_request_job_factory.h" 15 16 namespace net { 17 18 // This job type is designed to help with simple unit tests. To use, you 19 // probably want to inherit from it to set up the state you want. Then install 20 // it as the protocol handler for the "test" scheme. 21 // 22 // It will respond to several URLs, which you can retrieve using the test_url* 23 // getters, which will in turn respond with the corresponding responses returned 24 // by test_data*. Any other URLs that begin with "test:" will return an error, 25 // which might also be useful, you can use test_url_error() to retreive a 26 // standard one. 27 // 28 // You can override the known URLs or the response data by overriding Start(). 29 // 30 // Optionally, you can also construct test jobs to return a headers and data 31 // provided to the contstructor in response to any request url. 32 // 33 // When a job is created, it gets put on a queue of pending test jobs. To 34 // process jobs on this queue, use ProcessOnePendingMessage, which will process 35 // one step of the next job. If the job is incomplete, it will be added to the 36 // end of the queue. 37 // 38 // Optionally, you can also construct test jobs that advance automatically 39 // without having to call ProcessOnePendingMessage. 40 class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob { 41 public: 42 // Constructs a job to return one of the canned responses depending on the 43 // request url, with auto advance disabled. 44 URLRequestTestJob(URLRequest* request, NetworkDelegate* network_delegate); 45 46 // Constructs a job to return one of the canned responses depending on the 47 // request url, optionally with auto advance enabled. 48 URLRequestTestJob(URLRequest* request, 49 NetworkDelegate* network_delegate, 50 bool auto_advance); 51 52 // Constructs a job to return the given response regardless of the request 53 // url. The headers should include the HTTP status line and be formatted as 54 // expected by HttpResponseHeaders. 55 URLRequestTestJob(URLRequest* request, 56 net::NetworkDelegate* network_delegate, 57 const std::string& response_headers, 58 const std::string& response_data, 59 bool auto_advance); 60 61 // The canned URLs this handler will respond to without having been 62 // explicitly initialized with response headers and data. 63 // FIXME(brettw): we should probably also have a redirect one 64 static GURL test_url_1(); 65 static GURL test_url_2(); 66 static GURL test_url_3(); 67 static GURL test_url_4(); 68 static GURL test_url_error(); 69 static GURL test_url_redirect_to_url_2(); 70 71 // The data that corresponds to each of the URLs above 72 static std::string test_data_1(); 73 static std::string test_data_2(); 74 static std::string test_data_3(); 75 static std::string test_data_4(); 76 77 // The headers that correspond to each of the URLs above 78 static std::string test_headers(); 79 80 // The headers for a redirect response 81 static std::string test_redirect_headers(); 82 83 // The headers for a redirect response to the second test url. 84 static std::string test_redirect_to_url_2_headers(); 85 86 // The headers for a server error response 87 static std::string test_error_headers(); 88 89 // Processes one pending message from the stack, returning true if any 90 // message was processed, or false if there are no more pending request 91 // notifications to send. This is not applicable when using auto_advance. 92 static bool ProcessOnePendingMessage(); 93 94 // With auto advance enabled, the job will advance thru the stages without 95 // the caller having to call ProcessOnePendingMessage. Auto advance depends 96 // on having a message loop running. The default is to not auto advance. 97 // Should not be altered after the job has started. auto_advance()98 bool auto_advance() { return auto_advance_; } set_auto_advance(bool auto_advance)99 void set_auto_advance(bool auto_advance) { auto_advance_ = auto_advance; } 100 set_load_timing_info(const LoadTimingInfo & load_timing_info)101 void set_load_timing_info(const LoadTimingInfo& load_timing_info) { 102 load_timing_info_ = load_timing_info; 103 } 104 priority()105 RequestPriority priority() const { return priority_; } 106 107 // Create a protocol handler for callers that don't subclass. 108 static URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler(); 109 110 // Job functions 111 virtual void SetPriority(RequestPriority priority) OVERRIDE; 112 virtual void Start() OVERRIDE; 113 virtual bool ReadRawData(IOBuffer* buf, 114 int buf_size, 115 int *bytes_read) OVERRIDE; 116 virtual void Kill() OVERRIDE; 117 virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; 118 virtual void GetResponseInfo(HttpResponseInfo* info) OVERRIDE; 119 virtual void GetLoadTimingInfo( 120 LoadTimingInfo* load_timing_info) const OVERRIDE; 121 virtual int GetResponseCode() const OVERRIDE; 122 virtual bool IsRedirectResponse(GURL* location, 123 int* http_status_code) OVERRIDE; 124 125 protected: 126 // Override to specify whether the next read done from this job will 127 // return IO pending. This controls whether or not the WAITING state will 128 // transition back to WAITING or to DATA_AVAILABLE after an asynchronous 129 // read is processed. 130 virtual bool NextReadAsync(); 131 132 // This is what operation we are going to do next when this job is handled. 133 // When the stage is DONE, this job will not be put on the queue. 134 enum Stage { WAITING, DATA_AVAILABLE, ALL_DATA, DONE }; 135 136 virtual ~URLRequestTestJob(); 137 138 // Call to process the next opeation, usually sending a notification, and 139 // advancing the stage if necessary. THIS MAY DELETE THE OBJECT. 140 void ProcessNextOperation(); 141 142 // Call to move the job along to the next operation. 143 void AdvanceJob(); 144 145 // Called via InvokeLater to cause callbacks to occur after Start() returns. 146 virtual void StartAsync(); 147 148 bool auto_advance_; 149 150 Stage stage_; 151 152 RequestPriority priority_; 153 154 // The headers the job should return, will be set in Start() if not provided 155 // in the explicit ctor. 156 scoped_refptr<HttpResponseHeaders> response_headers_; 157 158 // The data to send, will be set in Start() if not provided in the explicit 159 // ctor. 160 std::string response_data_; 161 162 // current offset within response_data_ 163 int offset_; 164 165 // Holds the buffer for an asynchronous ReadRawData call 166 IOBuffer* async_buf_; 167 int async_buf_size_; 168 169 LoadTimingInfo load_timing_info_; 170 171 base::WeakPtrFactory<URLRequestTestJob> weak_factory_; 172 }; 173 174 } // namespace net 175 176 #endif // NET_URL_REQUEST_URL_REQUEST_TEST_JOB_H_ 177