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