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 // |response_destination_|. Return true if the write has been | 195 // |fetcher_->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 | |
271 static base::LazyInstance<Registry> g_registry; | 268 static base::LazyInstance<Registry> g_registry; |
272 | 269 |
273 friend class URLFetcher; | 270 friend class URLFetcher; |
274 DISALLOW_COPY_AND_ASSIGN(Core); | 271 DISALLOW_COPY_AND_ASSIGN(Core); |
275 }; | 272 }; |
276 | 273 |
277 URLFetcher::Core::Registry::Registry() {} | 274 URLFetcher::Core::Registry::Registry() {} |
278 URLFetcher::Core::Registry::~Registry() {} | 275 URLFetcher::Core::Registry::~Registry() {} |
279 | 276 |
280 void URLFetcher::Core::Registry::AddURLFetcherCore(Core* core) { | 277 void URLFetcher::Core::Registry::AddURLFetcherCore(Core* core) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 // TODO(skerner): This default implementation will be removed, and the | 459 // TODO(skerner): This default implementation will be removed, and the |
463 // method made pure virtual, once all users of URLFetcher are updated | 460 // method made pure virtual, once all users of URLFetcher are updated |
464 // to not expect response data as a string argument. Once this is removed, | 461 // to not expect response data as a string argument. Once this is removed, |
465 // the method URLFetcher::GetResponseStringRef() can be removed as well. | 462 // the method URLFetcher::GetResponseStringRef() can be removed as well. |
466 // crbug.com/83592 tracks this. | 463 // crbug.com/83592 tracks this. |
467 void URLFetcher::Delegate::OnURLFetchComplete(const URLFetcher* source) { | 464 void URLFetcher::Delegate::OnURLFetchComplete(const URLFetcher* source) { |
468 // A delegate that did not override this method is using the old | 465 // A delegate that did not override this method is using the old |
469 // parameter list to OnURLFetchComplete(). If a user asked to save | 466 // parameter list to OnURLFetchComplete(). If a user asked to save |
470 // the response to a file, they must use the new parameter list, | 467 // the response to a file, they must use the new parameter list, |
471 // in which case we can not get here. | 468 // in which case we can not get here. |
| 469 CHECK(source->response_destination_ == STRING); |
| 470 |
472 // To avoid updating all callers, thunk to the old prototype for now. | 471 // To avoid updating all callers, thunk to the old prototype for now. |
473 OnURLFetchComplete(source, | 472 OnURLFetchComplete(source, |
474 source->url(), | 473 source->url(), |
475 source->status(), | 474 source->status(), |
476 source->response_code(), | 475 source->response_code(), |
477 source->cookies(), | 476 source->cookies(), |
478 source->GetResponseStringRef()); | 477 source->GetResponseStringRef()); |
479 } | 478 } |
480 | 479 |
481 // static | 480 // static |
482 bool URLFetcher::g_interception_enabled = false; | 481 bool URLFetcher::g_interception_enabled = false; |
483 | 482 |
484 URLFetcher::URLFetcher(const GURL& url, | 483 URLFetcher::URLFetcher(const GURL& url, |
485 RequestType request_type, | 484 RequestType request_type, |
486 Delegate* d) | 485 Delegate* d) |
487 : ALLOW_THIS_IN_INITIALIZER_LIST( | 486 : ALLOW_THIS_IN_INITIALIZER_LIST( |
488 core_(new Core(this, url, request_type, d))), | 487 core_(new Core(this, url, request_type, d))), |
489 automatically_retry_on_5xx_(true), | 488 automatically_retry_on_5xx_(true), |
490 max_retries_(0) { | 489 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) { | |
522 } | 521 } |
523 | 522 |
524 URLFetcher::Core::~Core() { | 523 URLFetcher::Core::~Core() { |
525 // |request_| should be NULL. If not, it's unsafe to delete it here since we | 524 // |request_| should be NULL. If not, it's unsafe to delete it here since we |
526 // may not be on the IO thread. | 525 // may not be on the IO thread. |
527 DCHECK(!request_.get()); | 526 DCHECK(!request_.get()); |
528 } | 527 } |
529 | 528 |
530 void URLFetcher::Core::Start() { | 529 void URLFetcher::Core::Start() { |
531 DCHECK(delegate_loop_proxy_); | 530 DCHECK(delegate_loop_proxy_); |
532 CHECK(request_context_getter_) << "We need an URLRequestContext!"; | 531 CHECK(request_context_getter_) << "We need an URLRequestContext!"; |
533 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); | 532 io_message_loop_proxy_ = request_context_getter_->GetIOMessageLoopProxy(); |
534 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; | 533 CHECK(io_message_loop_proxy_.get()) << "We need an IO message loop proxy"; |
535 | 534 |
536 switch (response_destination_) { | 535 switch (fetcher_->response_destination_) { |
537 case STRING: | 536 case STRING: |
538 io_message_loop_proxy_->PostTask( | 537 io_message_loop_proxy_->PostTask( |
539 FROM_HERE, | 538 FROM_HERE, |
540 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); | 539 NewRunnableMethod(this, &Core::StartURLRequestWhenAppropriate)); |
541 break; | 540 break; |
542 | 541 |
543 case TEMP_FILE: | 542 case TEMP_FILE: |
544 CHECK(file_message_loop_proxy_.get()) | 543 CHECK(file_message_loop_proxy_.get()) |
545 << "Need to set the file message loop proxy."; | 544 << "Need to set the file message loop proxy."; |
546 temp_file_writer_.reset( | 545 temp_file_writer_.reset( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 FROM_HERE, | 607 FROM_HERE, |
609 NewRunnableMethod(this, &Core::CompleteAddingUploadDataChunk, content, | 608 NewRunnableMethod(this, &Core::CompleteAddingUploadDataChunk, content, |
610 is_last_chunk)); | 609 is_last_chunk)); |
611 } | 610 } |
612 | 611 |
613 // Return true if the write was done and reading may continue. | 612 // Return true if the write was done and reading may continue. |
614 // Return false if the write is pending, and the next read will | 613 // Return false if the write is pending, and the next read will |
615 // be done later. | 614 // be done later. |
616 bool URLFetcher::Core::WriteBuffer(int num_bytes) { | 615 bool URLFetcher::Core::WriteBuffer(int num_bytes) { |
617 bool write_complete = false; | 616 bool write_complete = false; |
618 switch (response_destination_) { | 617 switch (fetcher_->response_destination_) { |
619 case STRING: | 618 case STRING: |
620 data_.append(buffer_->data(), num_bytes); | 619 data_.append(buffer_->data(), num_bytes); |
621 write_complete = true; | 620 write_complete = true; |
622 break; | 621 break; |
623 | 622 |
624 case TEMP_FILE: | 623 case TEMP_FILE: |
625 temp_file_writer_->WriteBuffer(num_bytes); | 624 temp_file_writer_->WriteBuffer(num_bytes); |
626 // WriteBuffer() sends a request the file thread. | 625 // WriteBuffer() sends a request the file thread. |
627 // The write is not done yet. | 626 // The write is not done yet. |
628 write_complete = false; | 627 write_complete = false; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 core_->request_context_getter_ = request_context_getter; | 906 core_->request_context_getter_ = request_context_getter; |
908 } | 907 } |
909 | 908 |
910 void URLFetcher::set_automatically_retry_on_5xx(bool retry) { | 909 void URLFetcher::set_automatically_retry_on_5xx(bool retry) { |
911 automatically_retry_on_5xx_ = retry; | 910 automatically_retry_on_5xx_ = retry; |
912 } | 911 } |
913 | 912 |
914 void URLFetcher::SaveResponseToTemporaryFile( | 913 void URLFetcher::SaveResponseToTemporaryFile( |
915 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { | 914 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy) { |
916 core_->file_message_loop_proxy_ = file_message_loop_proxy; | 915 core_->file_message_loop_proxy_ = file_message_loop_proxy; |
917 core_->response_destination_ = TEMP_FILE; | 916 response_destination_ = TEMP_FILE; |
918 } | 917 } |
919 | 918 |
920 net::HttpResponseHeaders* URLFetcher::response_headers() const { | 919 net::HttpResponseHeaders* URLFetcher::response_headers() const { |
921 return core_->response_headers_; | 920 return core_->response_headers_; |
922 } | 921 } |
923 | 922 |
924 // TODO(panayiotis): socket_address_ is written in the IO thread, | 923 // TODO(panayiotis): socket_address_ is written in the IO thread, |
925 // if this is accessed in the UI thread, this could result in a race. | 924 // if this is accessed in the UI thread, this could result in a race. |
926 // Same for response_headers_ above and was_fetched_via_proxy_ below. | 925 // Same for response_headers_ above and was_fetched_via_proxy_ below. |
927 net::HostPortPair URLFetcher::socket_address() const { | 926 net::HostPortPair URLFetcher::socket_address() const { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 | 965 |
967 *out_error_code = error_code; | 966 *out_error_code = error_code; |
968 return true; | 967 return true; |
969 } | 968 } |
970 | 969 |
971 void URLFetcher::ReceivedContentWasMalformed() { | 970 void URLFetcher::ReceivedContentWasMalformed() { |
972 core_->ReceivedContentWasMalformed(); | 971 core_->ReceivedContentWasMalformed(); |
973 } | 972 } |
974 | 973 |
975 bool URLFetcher::GetResponseAsString(std::string* out_response_string) const { | 974 bool URLFetcher::GetResponseAsString(std::string* out_response_string) const { |
976 if (core_->response_destination_ != STRING) | 975 if (response_destination_ != STRING) |
977 return false; | 976 return false; |
978 | 977 |
979 *out_response_string = core_->data_; | 978 *out_response_string = core_->data_; |
980 return true; | 979 return true; |
981 } | 980 } |
982 | 981 |
983 const std::string& URLFetcher::GetResponseStringRef() const { | 982 const std::string& URLFetcher::GetResponseStringRef() const { |
984 CHECK(core_->response_destination_ == STRING); | 983 CHECK(response_destination_ == STRING); |
985 return core_->data_; | 984 return core_->data_; |
986 } | 985 } |
987 | 986 |
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 | |
998 bool URLFetcher::GetResponseAsFilePath(bool take_ownership, | 987 bool URLFetcher::GetResponseAsFilePath(bool take_ownership, |
999 FilePath* out_response_path) const { | 988 FilePath* out_response_path) const { |
1000 if (core_->response_destination_ != TEMP_FILE || | 989 if (response_destination_ != TEMP_FILE || !core_->temp_file_writer_.get()) |
1001 !core_->temp_file_writer_.get()) | |
1002 return false; | 990 return false; |
1003 | 991 |
1004 *out_response_path = core_->temp_file_writer_->temp_file(); | 992 *out_response_path = core_->temp_file_writer_->temp_file(); |
1005 | 993 |
1006 if (take_ownership) | 994 if (take_ownership) |
1007 core_->temp_file_writer_->DisownTempFile(); | 995 core_->temp_file_writer_->DisownTempFile(); |
1008 | 996 |
1009 return true; | 997 return true; |
1010 } | 998 } |
1011 | 999 |
1012 // static | 1000 // static |
1013 void URLFetcher::CancelAll() { | 1001 void URLFetcher::CancelAll() { |
1014 Core::CancelAll(); | 1002 Core::CancelAll(); |
1015 } | 1003 } |
1016 | 1004 |
1017 // static | 1005 // static |
1018 int URLFetcher::GetNumFetcherCores() { | 1006 int URLFetcher::GetNumFetcherCores() { |
1019 return Core::g_registry.Get().size(); | 1007 return Core::g_registry.Get().size(); |
1020 } | 1008 } |
1021 | 1009 |
1022 URLFetcher::Delegate* URLFetcher::delegate() const { | 1010 URLFetcher::Delegate* URLFetcher::delegate() const { |
1023 return core_->delegate(); | 1011 return core_->delegate(); |
1024 } | 1012 } |
OLD | NEW |