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 #include "net/url_request/test_url_fetcher_factory.h" 6 7 #include <string> 8 9 #include "base/bind.h" 10 #include "base/compiler_specific.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/message_loop/message_loop.h" 13 #include "net/base/host_port_pair.h" 14 #include "net/base/net_errors.h" 15 #include "net/http/http_response_headers.h" 16 #include "net/url_request/url_fetcher_delegate.h" 17 #include "net/url_request/url_fetcher_impl.h" 18 #include "net/url_request/url_fetcher_response_writer.h" 19 #include "net/url_request/url_request_status.h" 20 21 namespace net { 22 23 ScopedURLFetcherFactory::ScopedURLFetcherFactory( 24 URLFetcherFactory* factory) { 25 DCHECK(!URLFetcherImpl::factory()); 26 URLFetcherImpl::set_factory(factory); 27 } 28 29 ScopedURLFetcherFactory::~ScopedURLFetcherFactory() { 30 DCHECK(URLFetcherImpl::factory()); 31 URLFetcherImpl::set_factory(NULL); 32 } 33 34 TestURLFetcher::TestURLFetcher(int id, 35 const GURL& url, 36 URLFetcherDelegate* d) 37 : owner_(NULL), 38 id_(id), 39 original_url_(url), 40 delegate_(d), 41 delegate_for_tests_(NULL), 42 did_receive_last_chunk_(false), 43 fake_load_flags_(0), 44 fake_response_code_(-1), 45 fake_response_destination_(STRING), 46 fake_was_fetched_via_proxy_(false), 47 fake_max_retries_(0) { 48 } 49 50 TestURLFetcher::~TestURLFetcher() { 51 if (delegate_for_tests_) 52 delegate_for_tests_->OnRequestEnd(id_); 53 if (owner_) 54 owner_->RemoveFetcherFromMap(id_); 55 } 56 57 void TestURLFetcher::SetUploadData(const std::string& upload_content_type, 58 const std::string& upload_content) { 59 upload_data_ = upload_content; 60 } 61 62 void TestURLFetcher::SetUploadFilePath( 63 const std::string& upload_content_type, 64 const base::FilePath& file_path, 65 uint64 range_offset, 66 uint64 range_length, 67 scoped_refptr<base::TaskRunner> file_task_runner) { 68 upload_file_path_ = file_path; 69 } 70 71 void TestURLFetcher::SetChunkedUpload(const std::string& upload_content_type) { 72 } 73 74 void TestURLFetcher::AppendChunkToUpload(const std::string& data, 75 bool is_last_chunk) { 76 DCHECK(!did_receive_last_chunk_); 77 did_receive_last_chunk_ = is_last_chunk; 78 chunks_.push_back(data); 79 if (delegate_for_tests_) 80 delegate_for_tests_->OnChunkUpload(id_); 81 } 82 83 void TestURLFetcher::SetLoadFlags(int load_flags) { 84 fake_load_flags_= load_flags; 85 } 86 87 int TestURLFetcher::GetLoadFlags() const { 88 return fake_load_flags_; 89 } 90 91 void TestURLFetcher::SetReferrer(const std::string& referrer) { 92 } 93 94 void TestURLFetcher::SetExtraRequestHeaders( 95 const std::string& extra_request_headers) { 96 fake_extra_request_headers_.Clear(); 97 fake_extra_request_headers_.AddHeadersFromString(extra_request_headers); 98 } 99 100 void TestURLFetcher::AddExtraRequestHeader(const std::string& header_line) { 101 fake_extra_request_headers_.AddHeaderFromString(header_line); 102 } 103 104 void TestURLFetcher::GetExtraRequestHeaders( 105 HttpRequestHeaders* headers) const { 106 *headers = fake_extra_request_headers_; 107 } 108 109 void TestURLFetcher::SetRequestContext( 110 URLRequestContextGetter* request_context_getter) { 111 } 112 113 void TestURLFetcher::SetFirstPartyForCookies( 114 const GURL& first_party_for_cookies) { 115 } 116 117 void TestURLFetcher::SetURLRequestUserData( 118 const void* key, 119 const CreateDataCallback& create_data_callback) { 120 } 121 122 void TestURLFetcher::SetStopOnRedirect(bool stop_on_redirect) { 123 } 124 125 void TestURLFetcher::SetAutomaticallyRetryOn5xx(bool retry) { 126 } 127 128 void TestURLFetcher::SetMaxRetriesOn5xx(int max_retries) { 129 fake_max_retries_ = max_retries; 130 } 131 132 int TestURLFetcher::GetMaxRetriesOn5xx() const { 133 return fake_max_retries_; 134 } 135 136 base::TimeDelta TestURLFetcher::GetBackoffDelay() const { 137 return fake_backoff_delay_; 138 } 139 140 void TestURLFetcher::SetAutomaticallyRetryOnNetworkChanges(int max_retries) { 141 } 142 143 void TestURLFetcher::SaveResponseToFileAtPath( 144 const base::FilePath& file_path, 145 scoped_refptr<base::SequencedTaskRunner> file_task_runner) { 146 } 147 148 void TestURLFetcher::SaveResponseToTemporaryFile( 149 scoped_refptr<base::SequencedTaskRunner> file_task_runner) { 150 } 151 152 void TestURLFetcher::SaveResponseWithWriter( 153 scoped_ptr<URLFetcherResponseWriter> response_writer) { 154 } 155 156 HttpResponseHeaders* TestURLFetcher::GetResponseHeaders() const { 157 return fake_response_headers_.get(); 158 } 159 160 HostPortPair TestURLFetcher::GetSocketAddress() const { 161 NOTIMPLEMENTED(); 162 return HostPortPair(); 163 } 164 165 bool TestURLFetcher::WasFetchedViaProxy() const { 166 return fake_was_fetched_via_proxy_; 167 } 168 169 void TestURLFetcher::Start() { 170 // Overriden to do nothing. It is assumed the caller will notify the delegate. 171 if (delegate_for_tests_) 172 delegate_for_tests_->OnRequestStart(id_); 173 } 174 175 const GURL& TestURLFetcher::GetOriginalURL() const { 176 return original_url_; 177 } 178 179 const GURL& TestURLFetcher::GetURL() const { 180 return fake_url_; 181 } 182 183 const URLRequestStatus& TestURLFetcher::GetStatus() const { 184 return fake_status_; 185 } 186 187 int TestURLFetcher::GetResponseCode() const { 188 return fake_response_code_; 189 } 190 191 const ResponseCookies& TestURLFetcher::GetCookies() const { 192 return fake_cookies_; 193 } 194 195 void TestURLFetcher::ReceivedContentWasMalformed() { 196 } 197 198 bool TestURLFetcher::GetResponseAsString( 199 std::string* out_response_string) const { 200 if (fake_response_destination_ != STRING) 201 return false; 202 203 *out_response_string = fake_response_string_; 204 return true; 205 } 206 207 bool TestURLFetcher::GetResponseAsFilePath( 208 bool take_ownership, base::FilePath* out_response_path) const { 209 if (fake_response_destination_ != TEMP_FILE) 210 return false; 211 212 *out_response_path = fake_response_file_path_; 213 return true; 214 } 215 216 void TestURLFetcher::set_status(const URLRequestStatus& status) { 217 fake_status_ = status; 218 } 219 220 void TestURLFetcher::set_was_fetched_via_proxy(bool flag) { 221 fake_was_fetched_via_proxy_ = flag; 222 } 223 224 void TestURLFetcher::set_response_headers( 225 scoped_refptr<HttpResponseHeaders> headers) { 226 fake_response_headers_ = headers; 227 } 228 229 void TestURLFetcher::set_backoff_delay(base::TimeDelta backoff_delay) { 230 fake_backoff_delay_ = backoff_delay; 231 } 232 233 void TestURLFetcher::SetDelegateForTests(DelegateForTests* delegate_for_tests) { 234 delegate_for_tests_ = delegate_for_tests; 235 } 236 237 void TestURLFetcher::SetResponseString(const std::string& response) { 238 fake_response_destination_ = STRING; 239 fake_response_string_ = response; 240 } 241 242 void TestURLFetcher::SetResponseFilePath(const base::FilePath& path) { 243 fake_response_destination_ = TEMP_FILE; 244 fake_response_file_path_ = path; 245 } 246 247 TestURLFetcherFactory::TestURLFetcherFactory() 248 : ScopedURLFetcherFactory(this), 249 delegate_for_tests_(NULL), 250 remove_fetcher_on_delete_(false) { 251 } 252 253 TestURLFetcherFactory::~TestURLFetcherFactory() {} 254 255 URLFetcher* TestURLFetcherFactory::CreateURLFetcher( 256 int id, 257 const GURL& url, 258 URLFetcher::RequestType request_type, 259 URLFetcherDelegate* d) { 260 TestURLFetcher* fetcher = new TestURLFetcher(id, url, d); 261 if (remove_fetcher_on_delete_) 262 fetcher->set_owner(this); 263 fetcher->SetDelegateForTests(delegate_for_tests_); 264 fetchers_[id] = fetcher; 265 return fetcher; 266 } 267 268 TestURLFetcher* TestURLFetcherFactory::GetFetcherByID(int id) const { 269 Fetchers::const_iterator i = fetchers_.find(id); 270 return i == fetchers_.end() ? NULL : i->second; 271 } 272 273 void TestURLFetcherFactory::RemoveFetcherFromMap(int id) { 274 Fetchers::iterator i = fetchers_.find(id); 275 DCHECK(i != fetchers_.end()); 276 fetchers_.erase(i); 277 } 278 279 void TestURLFetcherFactory::SetDelegateForTests( 280 TestURLFetcherDelegateForTests* delegate_for_tests) { 281 delegate_for_tests_ = delegate_for_tests; 282 } 283 284 FakeURLFetcher::FakeURLFetcher(const GURL& url, 285 URLFetcherDelegate* d, 286 const std::string& response_data, 287 HttpStatusCode response_code, 288 URLRequestStatus::Status status) 289 : TestURLFetcher(0, url, d), 290 weak_factory_(this) { 291 Error error = OK; 292 switch(status) { 293 case URLRequestStatus::SUCCESS: 294 // |error| is initialized to OK. 295 break; 296 case URLRequestStatus::IO_PENDING: 297 error = ERR_IO_PENDING; 298 break; 299 case URLRequestStatus::CANCELED: 300 error = ERR_ABORTED; 301 break; 302 case URLRequestStatus::FAILED: 303 error = ERR_FAILED; 304 break; 305 } 306 set_status(URLRequestStatus(status, error)); 307 set_response_code(response_code); 308 SetResponseString(response_data); 309 } 310 311 FakeURLFetcher::~FakeURLFetcher() {} 312 313 void FakeURLFetcher::Start() { 314 base::MessageLoop::current()->PostTask( 315 FROM_HERE, 316 base::Bind(&FakeURLFetcher::RunDelegate, weak_factory_.GetWeakPtr())); 317 } 318 319 void FakeURLFetcher::RunDelegate() { 320 delegate()->OnURLFetchComplete(this); 321 } 322 323 const GURL& FakeURLFetcher::GetURL() const { 324 return TestURLFetcher::GetOriginalURL(); 325 } 326 327 FakeURLFetcherFactory::FakeURLFetcherFactory( 328 URLFetcherFactory* default_factory) 329 : ScopedURLFetcherFactory(this), 330 creator_(base::Bind(&DefaultFakeURLFetcherCreator)), 331 default_factory_(default_factory) { 332 } 333 334 FakeURLFetcherFactory::FakeURLFetcherFactory( 335 URLFetcherFactory* default_factory, 336 const FakeURLFetcherCreator& creator) 337 : ScopedURLFetcherFactory(this), 338 creator_(creator), 339 default_factory_(default_factory) { 340 } 341 342 scoped_ptr<FakeURLFetcher> FakeURLFetcherFactory::DefaultFakeURLFetcherCreator( 343 const GURL& url, 344 URLFetcherDelegate* delegate, 345 const std::string& response_data, 346 HttpStatusCode response_code, 347 URLRequestStatus::Status status) { 348 return scoped_ptr<FakeURLFetcher>( 349 new FakeURLFetcher(url, delegate, response_data, response_code, status)); 350 } 351 352 FakeURLFetcherFactory::~FakeURLFetcherFactory() {} 353 354 URLFetcher* FakeURLFetcherFactory::CreateURLFetcher( 355 int id, 356 const GURL& url, 357 URLFetcher::RequestType request_type, 358 URLFetcherDelegate* d) { 359 FakeResponseMap::const_iterator it = fake_responses_.find(url); 360 if (it == fake_responses_.end()) { 361 if (default_factory_ == NULL) { 362 // If we don't have a baked response for that URL we return NULL. 363 DLOG(ERROR) << "No baked response for URL: " << url.spec(); 364 return NULL; 365 } else { 366 return default_factory_->CreateURLFetcher(id, url, request_type, d); 367 } 368 } 369 370 scoped_ptr<FakeURLFetcher> fake_fetcher = 371 creator_.Run(url, d, it->second.response_data, 372 it->second.response_code, it->second.status); 373 // TODO: Make URLFetcherFactory::CreateURLFetcher return a scoped_ptr 374 return fake_fetcher.release(); 375 } 376 377 void FakeURLFetcherFactory::SetFakeResponse( 378 const GURL& url, 379 const std::string& response_data, 380 HttpStatusCode response_code, 381 URLRequestStatus::Status status) { 382 // Overwrite existing URL if it already exists. 383 FakeURLResponse response; 384 response.response_data = response_data; 385 response.response_code = response_code; 386 response.status = status; 387 fake_responses_[url] = response; 388 } 389 390 void FakeURLFetcherFactory::ClearFakeResponses() { 391 fake_responses_.clear(); 392 } 393 394 URLFetcherImplFactory::URLFetcherImplFactory() {} 395 396 URLFetcherImplFactory::~URLFetcherImplFactory() {} 397 398 URLFetcher* URLFetcherImplFactory::CreateURLFetcher( 399 int id, 400 const GURL& url, 401 URLFetcher::RequestType request_type, 402 URLFetcherDelegate* d) { 403 return new URLFetcherImpl(url, request_type, d); 404 } 405 406 } // namespace net 407