OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/net/url_fetcher.h" | 5 #include "chrome/common/net/url_fetcher.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 base::TimeTicks GetBackoffReleaseTime(); | 185 base::TimeTicks GetBackoffReleaseTime(); |
186 | 186 |
187 void CompleteAddingUploadDataChunk(const std::string& data, | 187 void CompleteAddingUploadDataChunk(const std::string& data, |
188 bool is_last_chunk); | 188 bool is_last_chunk); |
189 | 189 |
190 // Adds a block of data to be uploaded in a POST body. This can only be | 190 // Adds a block of data to be uploaded in a POST body. This can only be |
191 // called after Start(). | 191 // called after Start(). |
192 void AppendChunkToUpload(const std::string& data, bool is_last_chunk); | 192 void AppendChunkToUpload(const std::string& data, bool is_last_chunk); |
193 | 193 |
194 // Store the response bytes in |buffer_| in the container indicated by | 194 // Store the response bytes in |buffer_| in the container indicated by |
195 // |fetcher_->response_destination_|. Return true if the write has been | 195 // |response_destination_|. Return true if the write has been |
196 // done, and another read can overwrite |buffer_|. If this function | 196 // done, and another read can overwrite |buffer_|. If this function |
197 // returns false, it will post a task that will read more bytes once the | 197 // returns false, it will post a task that will read more bytes once the |
198 // write is complete. | 198 // write is complete. |
199 bool WriteBuffer(int num_bytes); | 199 bool WriteBuffer(int num_bytes); |
200 | 200 |
201 // Read response bytes from the request. | 201 // Read response bytes from the request. |
202 void ReadResponse(); | 202 void ReadResponse(); |
203 | 203 |
204 URLFetcher* fetcher_; // Corresponding fetcher object | 204 URLFetcher* fetcher_; // Corresponding fetcher object |
205 GURL original_url_; // The URL we were asked to fetch | 205 GURL original_url_; // The URL we were asked to fetch |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 bool was_cancelled_; | 258 bool was_cancelled_; |
259 | 259 |
260 // Since GetBackoffReleaseTime() can only be called on the IO thread, we cache | 260 // Since GetBackoffReleaseTime() can only be called on the IO thread, we cache |
261 // its value to be used by OnCompletedURLRequest on the creating thread. | 261 // its value to be used by OnCompletedURLRequest on the creating thread. |
262 base::TimeTicks backoff_release_time_; | 262 base::TimeTicks backoff_release_time_; |
263 | 263 |
264 // If writing results to a file, |temp_file_writer_| will manage creation, | 264 // If writing results to a file, |temp_file_writer_| will manage creation, |
265 // writing, and destruction of that file. | 265 // writing, and destruction of that file. |
266 scoped_ptr<TempFileWriter> temp_file_writer_; | 266 scoped_ptr<TempFileWriter> temp_file_writer_; |
267 | 267 |
| 268 // Where should responses be saved? |
| 269 ResponseDestinationType response_destination_; |
| 270 |
268 static base::LazyInstance<Registry> g_registry; | 271 static base::LazyInstance<Registry> g_registry; |
269 | 272 |
270 friend class URLFetcher; | 273 friend class URLFetcher; |
271 DISALLOW_COPY_AND_ASSIGN(Core); | 274 DISALLOW_COPY_AND_ASSIGN(Core); |
272 }; | 275 }; |
273 | 276 |
274 URLFetcher::Core::Registry::Registry() {} | 277 URLFetcher::Core::Registry::Registry() {} |
275 URLFetcher::Core::Registry::~Registry() {} | 278 URLFetcher::Core::Registry::~Registry() {} |
276 | 279 |
277 void URLFetcher::Core::Registry::AddURLFetcherCore(Core* core) { | 280 void URLFetcher::Core::Registry::AddURLFetcherCore(Core* core) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 // TODO(skerner): This default implementation will be removed, and the | 462 // TODO(skerner): This default implementation will be removed, and the |
460 // method made pure virtual, once all users of URLFetcher are updated | 463 // method made pure virtual, once all users of URLFetcher are updated |
461 // to not expect response data as a string argument. Once this is removed, | 464 // to not expect response data as a string argument. Once this is removed, |
462 // the method URLFetcher::GetResponseStringRef() can be removed as well. | 465 // the method URLFetcher::GetResponseStringRef() can be removed as well. |
463 // crbug.com/83592 tracks this. | 466 // crbug.com/83592 tracks this. |
464 void URLFetcher::Delegate::OnURLFetchComplete(const URLFetcher* source) { | 467 void URLFetcher::Delegate::OnURLFetchComplete(const URLFetcher* source) { |
465 // A delegate that did not override this method is using the old | 468 // A delegate that did not override this method is using the old |
466 // parameter list to OnURLFetchComplete(). If a user asked to save | 469 // parameter list to OnURLFetchComplete(). If a user asked to save |
467 // the response to a file, they must use the new parameter list, | 470 // the response to a file, they must use the new parameter list, |
468 // in which case we can not get here. | 471 // in which case we can not get here. |
469 CHECK(source->response_destination_ == STRING); | |
470 | |
471 // To avoid updating all callers, thunk to the old prototype for now. | 472 // To avoid updating all callers, thunk to the old prototype for now. |
472 OnURLFetchComplete(source, | 473 OnURLFetchComplete(source, |
473 source->url(), | 474 source->url(), |
474 source->status(), | 475 source->status(), |
475 source->response_code(), | 476 source->response_code(), |
476 source->cookies(), | 477 source->cookies(), |
477 source->GetResponseStringRef()); | 478 source->GetResponseStringRef()); |
478 } | 479 } |
479 | 480 |
480 // static | 481 // static |
481 bool URLFetcher::g_interception_enabled = false; | 482 bool URLFetcher::g_interception_enabled = false; |
482 | 483 |
483 URLFetcher::URLFetcher(const GURL& url, | 484 URLFetcher::URLFetcher(const GURL& url, |
484 RequestType request_type, | 485 RequestType request_type, |
485 Delegate* d) | 486 Delegate* d) |
486 : ALLOW_THIS_IN_INITIALIZER_LIST( | 487 : ALLOW_THIS_IN_INITIALIZER_LIST( |
487 core_(new Core(this, url, request_type, d))), | 488 core_(new Core(this, url, request_type, d))), |
488 automatically_retry_on_5xx_(true), | 489 automatically_retry_on_5xx_(true), |
489 max_retries_(0), | 490 max_retries_(0) { |
490 response_destination_(STRING) { | |
491 } | 491 } |
492 | 492 |
493 URLFetcher::~URLFetcher() { | 493 URLFetcher::~URLFetcher() { |
494 core_->Stop(); | 494 core_->Stop(); |
495 } | 495 } |
496 | 496 |
497 // static | 497 // static |
498 URLFetcher* URLFetcher::Create(int id, const GURL& url, | 498 URLFetcher* URLFetcher::Create(int id, const GURL& url, |
499 RequestType request_type, Delegate* d) { | 499 RequestType request_type, Delegate* d) { |
500 return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) : | 500 return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) : |
501 new URLFetcher(url, request_type, d); | 501 new URLFetcher(url, request_type, d); |
502 } | 502 } |
503 | 503 |
504 URLFetcher::Core::Core(URLFetcher* fetcher, | 504 URLFetcher::Core::Core(URLFetcher* fetcher, |
505 const GURL& original_url, | 505 const GURL& original_url, |
506 RequestType request_type, | 506 RequestType request_type, |
507 URLFetcher::Delegate* d) | 507 URLFetcher::Delegate* d) |
508 : fetcher_(fetcher), | 508 : fetcher_(fetcher), |
509 original_url_(original_url), | 509 original_url_(original_url), |
510 request_type_(request_type), | 510 request_type_(request_type), |
511 delegate_(d), | 511 delegate_(d), |
512 delegate_loop_proxy_( | 512 delegate_loop_proxy_( |
513 base::MessageLoopProxy::CreateForCurrentThread()), | 513 base::MessageLoopProxy::CreateForCurrentThread()), |
514 request_(NULL), | 514 request_(NULL), |
515 load_flags_(net::LOAD_NORMAL), | 515 load_flags_(net::LOAD_NORMAL), |
516 response_code_(URLFetcher::kInvalidHttpResponseCode), | 516 response_code_(URLFetcher::kInvalidHttpResponseCode), |
517 buffer_(new net::IOBuffer(kBufferSize)), | 517 buffer_(new net::IOBuffer(kBufferSize)), |
518 is_chunked_upload_(false), | 518 is_chunked_upload_(false), |
519 num_retries_(0), | 519 num_retries_(0), |
520 was_cancelled_(false) { | 520 was_cancelled_(false), |
| 521 response_destination_(STRING) { |
521 } | 522 } |
522 | 523 |
523 URLFetcher::Core::~Core() { | 524 URLFetcher::Core::~Core() { |
524 // |request_| should be NULL. If not, it's unsafe to delete it here since we | 525 // |request_| should be NULL. If not, it's unsafe to delete it here since we |
525 // may not be on the IO thread. | 526 // may not be on the IO thread. |
526 DCHECK(!request_.get()); | 527 DCHECK(!request_.get()); |
527 } | 528 } |
528 | 529 |
529 void URLFetcher::Core::Start() { | 530 void URLFetcher::Core::Start() { |
530 DCHECK(delegate_loop_proxy_); | 531 DCHECK(delegate_loop_proxy_); |
531 CHECK(request_context_getter_) << "We need an URLRequestContext!"; | 532 CHECK(request_context_getter_) << "We need an URLRequestContext!"; |
532 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); | 533 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); |
533 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; | 534 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; |
534 | 535 |
535 switch (fetcher_->response_destination_) { | 536 switch (response_destination_) { |
536 case STRING: | 537 case STRING: |
537 io_message_loop_proxy_->PostTask( | 538 io_message_loop_proxy_->PostTask( |
538 FROM_HERE, | 539 FROM_HERE, |
539 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); | 540 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); |
540 break; | 541 break; |
541 | 542 |
542 case TEMP_FILE: | 543 case TEMP_FILE: |
543 CHECK(file_message_loop_proxy_.get()) | 544 CHECK(file_message_loop_proxy_.get()) |
544 << "Need to set the file message loop proxy."; | 545 << "Need to set the file message loop proxy."; |
545 temp_file_writer_.reset( | 546 temp_file_writer_.reset( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 FROM_HERE, | 608 FROM_HERE, |
608 NewRunnableMethod(this, &Core::CompleteAddingUploadDataChunk, content, | 609 NewRunnableMethod(this, &Core::CompleteAddingUploadDataChunk, content, |
609 is_last_chunk)); | 610 is_last_chunk)); |
610 } | 611 } |
611 | 612 |
612 // Return true if the write was done and reading may continue. | 613 // Return true if the write was done and reading may continue. |
613 // Return false if the write is pending, and the next read will | 614 // Return false if the write is pending, and the next read will |
614 // be done later. | 615 // be done later. |
615 bool URLFetcher::Core::WriteBuffer(int num_bytes) { | 616 bool URLFetcher::Core::WriteBuffer(int num_bytes) { |
616 bool write_complete = false; | 617 bool write_complete = false; |
617 switch (fetcher_->response_destination_) { | 618 switch (response_destination_) { |
618 case STRING: | 619 case STRING: |
619 data_.append(buffer_->data(), num_bytes); | 620 data_.append(buffer_->data(), num_bytes); |
620 write_complete = true; | 621 write_complete = true; |
621 break; | 622 break; |
622 | 623 |
623 case TEMP_FILE: | 624 case TEMP_FILE: |
624 temp_file_writer_->WriteBuffer(num_bytes); | 625 temp_file_writer_->WriteBuffer(num_bytes); |
625 // WriteBuffer() sends a request the file thread. | 626 // WriteBuffer() sends a request the file thread. |
626 // The write is not done yet. | 627 // The write is not done yet. |
627 write_complete = false; | 628 write_complete = false; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 core_->request_context_getter_ = request_context_getter; | 907 core_->request_context_getter_ = request_context_getter; |
907 } | 908 } |
908 | 909 |
909 void URLFetcher::set_automatically_retry_on_5xx(bool retry) { | 910 void URLFetcher::set_automatically_retry_on_5xx(bool retry) { |
910 automatically_retry_on_5xx_ = retry; | 911 automatically_retry_on_5xx_ = retry; |
911 } | 912 } |
912 | 913 |
913 void URLFetcher::SaveResponseToTemporaryFile( | 914 void URLFetcher::SaveResponseToTemporaryFile( |
914 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { | 915 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { |
915 core_->file_message_loop_proxy_ = file_message_loop_proxy; | 916 core_->file_message_loop_proxy_ = file_message_loop_proxy; |
916 response_destination_ = TEMP_FILE; | 917 core_->response_destination_ = TEMP_FILE; |
917 } | 918 } |
918 | 919 |
919 net::HttpResponseHeaders* URLFetcher::response_headers() const { | 920 net::HttpResponseHeaders* URLFetcher::response_headers() const { |
920 return core_->response_headers_; | 921 return core_->response_headers_; |
921 } | 922 } |
922 | 923 |
923 // TODO(panayiotis): socket_address_ is written in the IO thread, | 924 // TODO(panayiotis): socket_address_ is written in the IO thread, |
924 // if this is accessed in the UI thread, this could result in a race. | 925 // if this is accessed in the UI thread, this could result in a race. |
925 // Same for response_headers_ above and was_fetched_via_proxy_ below. | 926 // Same for response_headers_ above and was_fetched_via_proxy_ below. |
926 net::HostPortPair URLFetcher::socket_address() const { | 927 net::HostPortPair URLFetcher::socket_address() const { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 | 966 |
966 *out_error_code = error_code; | 967 *out_error_code = error_code; |
967 return true; | 968 return true; |
968 } | 969 } |
969 | 970 |
970 void URLFetcher::ReceivedContentWasMalformed() { | 971 void URLFetcher::ReceivedContentWasMalformed() { |
971 core_->ReceivedContentWasMalformed(); | 972 core_->ReceivedContentWasMalformed(); |
972 } | 973 } |
973 | 974 |
974 bool URLFetcher::GetResponseAsString(std::string* out_response_string) const { | 975 bool URLFetcher::GetResponseAsString(std::string* out_response_string) const { |
975 if (response_destination_ != STRING) | 976 if (core_->response_destination_ != STRING) |
976 return false; | 977 return false; |
977 | 978 |
978 *out_response_string = core_->data_; | 979 *out_response_string = core_->data_; |
979 return true; | 980 return true; |
980 } | 981 } |
981 | 982 |
982 const std::string& URLFetcher::GetResponseStringRef() const { | 983 const std::string& URLFetcher::GetResponseStringRef() const { |
983 CHECK(response_destination_ == STRING); | 984 CHECK(core_->response_destination_ == STRING); |
984 return core_->data_; | 985 return core_->data_; |
985 } | 986 } |
986 | 987 |
| 988 void URLFetcher::SetResponseDestinationForTesting( |
| 989 ResponseDestinationType value) { |
| 990 core_->response_destination_ = value; |
| 991 } |
| 992 |
| 993 URLFetcher::ResponseDestinationType |
| 994 URLFetcher::GetResponseDestinationForTesting() const { |
| 995 return core_->response_destination_; |
| 996 } |
| 997 |
987 bool URLFetcher::GetResponseAsFilePath(bool take_ownership, | 998 bool URLFetcher::GetResponseAsFilePath(bool take_ownership, |
988 FilePath* out_response_path) const { | 999 FilePath* out_response_path) const { |
989 if (response_destination_ != TEMP_FILE || !core_->temp_file_writer_.get()) | 1000 if (core_->response_destination_ != TEMP_FILE || |
| 1001 !core_->temp_file_writer_.get()) |
990 return false; | 1002 return false; |
991 | 1003 |
992 *out_response_path = core_->temp_file_writer_->temp_file(); | 1004 *out_response_path = core_->temp_file_writer_->temp_file(); |
993 | 1005 |
994 if (take_ownership) | 1006 if (take_ownership) |
995 core_->temp_file_writer_->DisownTempFile(); | 1007 core_->temp_file_writer_->DisownTempFile(); |
996 | 1008 |
997 return true; | 1009 return true; |
998 } | 1010 } |
999 | 1011 |
1000 // static | 1012 // static |
1001 void URLFetcher::CancelAll() { | 1013 void URLFetcher::CancelAll() { |
1002 Core::CancelAll(); | 1014 Core::CancelAll(); |
1003 } | 1015 } |
1004 | 1016 |
1005 // static | 1017 // static |
1006 int URLFetcher::GetNumFetcherCores() { | 1018 int URLFetcher::GetNumFetcherCores() { |
1007 return Core::g_registry.Get().size(); | 1019 return Core::g_registry.Get().size(); |
1008 } | 1020 } |
1009 | 1021 |
1010 URLFetcher::Delegate* URLFetcher::delegate() const { | 1022 URLFetcher::Delegate* URLFetcher::delegate() const { |
1011 return core_->delegate(); | 1023 return core_->delegate(); |
1012 } | 1024 } |
OLD | NEW |