| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "net/url_request/url_request.h" | 5 #include "net/url_request/url_request.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 #include "base/trace_event/trace_event.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/debug/stack_trace.h" | 13 #include "base/debug/stack_trace.h" |
| 14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 15 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/profiler/scoped_tracker.h" | 17 #include "base/profiler/scoped_tracker.h" |
| 18 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 } | 162 } |
| 163 | 163 |
| 164 void URLRequest::Delegate::OnBeforeNetworkStart(URLRequest* request, | 164 void URLRequest::Delegate::OnBeforeNetworkStart(URLRequest* request, |
| 165 bool* defer) { | 165 bool* defer) { |
| 166 } | 166 } |
| 167 | 167 |
| 168 /////////////////////////////////////////////////////////////////////////////// | 168 /////////////////////////////////////////////////////////////////////////////// |
| 169 // URLRequest | 169 // URLRequest |
| 170 | 170 |
| 171 URLRequest::~URLRequest() { | 171 URLRequest::~URLRequest() { |
| 172 TRACE_EVENT0("toplevel", "URLRequest::~URLRequest"); |
| 172 Cancel(); | 173 Cancel(); |
| 173 | 174 |
| 174 if (network_delegate_) { | 175 if (network_delegate_) { |
| 176 TRACE_EVENT0("toplevel", "NetworkDelegate::NotifyURLRequestDestroyed"); |
| 175 network_delegate_->NotifyURLRequestDestroyed(this); | 177 network_delegate_->NotifyURLRequestDestroyed(this); |
| 176 if (job_.get()) | 178 if (job_.get()) |
| 177 job_->NotifyURLRequestDestroyed(); | 179 job_->NotifyURLRequestDestroyed(); |
| 178 } | 180 } |
| 179 | 181 |
| 180 if (job_.get()) | 182 if (job_.get()) |
| 181 OrphanJob(); | 183 OrphanJob(); |
| 182 | 184 |
| 183 int deleted = context_->url_requests()->erase(this); | 185 int deleted = context_->url_requests()->erase(this); |
| 184 CHECK_EQ(1, deleted); | 186 CHECK_EQ(1, deleted); |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 referrer_policy_ = referrer_policy; | 499 referrer_policy_ = referrer_policy; |
| 498 } | 500 } |
| 499 | 501 |
| 500 void URLRequest::set_delegate(Delegate* delegate) { | 502 void URLRequest::set_delegate(Delegate* delegate) { |
| 501 DCHECK(!delegate_); | 503 DCHECK(!delegate_); |
| 502 DCHECK(delegate); | 504 DCHECK(delegate); |
| 503 delegate_ = delegate; | 505 delegate_ = delegate; |
| 504 } | 506 } |
| 505 | 507 |
| 506 void URLRequest::Start() { | 508 void URLRequest::Start() { |
| 509 TRACE_EVENT0("toplevel", "URLRequest::Start"); |
| 507 DCHECK(delegate_); | 510 DCHECK(delegate_); |
| 508 | 511 |
| 509 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed. | 512 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456327 is fixed. |
| 510 tracked_objects::ScopedTracker tracking_profile( | 513 tracked_objects::ScopedTracker tracking_profile( |
| 511 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start")); | 514 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start")); |
| 512 | 515 |
| 513 // Some values can be NULL, but the job factory must not be. | 516 // Some values can be NULL, but the job factory must not be. |
| 514 DCHECK(context_->job_factory()); | 517 DCHECK(context_->job_factory()); |
| 515 | 518 |
| 516 // Anything that sets |blocked_by_| before start should have cleaned up after | 519 // Anything that sets |blocked_by_| before start should have cleaned up after |
| 517 // itself. | 520 // itself. |
| 518 DCHECK(blocked_by_.empty()); | 521 DCHECK(blocked_by_.empty()); |
| 519 | 522 |
| 520 g_url_requests_started = true; | 523 g_url_requests_started = true; |
| 521 response_info_.request_time = base::Time::Now(); | 524 response_info_.request_time = base::Time::Now(); |
| 522 | 525 |
| 523 load_timing_info_ = LoadTimingInfo(); | 526 load_timing_info_ = LoadTimingInfo(); |
| 524 load_timing_info_.request_start_time = response_info_.request_time; | 527 load_timing_info_.request_start_time = response_info_.request_time; |
| 525 load_timing_info_.request_start = base::TimeTicks::Now(); | 528 load_timing_info_.request_start = base::TimeTicks::Now(); |
| 526 | 529 |
| 527 // Only notify the delegate for the initial request. | 530 // Only notify the delegate for the initial request. |
| 528 if (network_delegate_) { | 531 if (network_delegate_) { |
| 529 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed. | 532 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed. |
| 530 tracked_objects::ScopedTracker tracking_profile25( | 533 tracked_objects::ScopedTracker tracking_profile25( |
| 531 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start 2.5")); | 534 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start 2.5")); |
| 532 | 535 |
| 533 OnCallToDelegate(); | 536 OnCallToDelegate(); |
| 534 int error = network_delegate_->NotifyBeforeURLRequest( | 537 int error; |
| 535 this, before_request_callback_, &delegate_redirect_url_); | 538 { |
| 539 TRACE_EVENT0("toplevel", "NetworkDelegate::NotifyBeforeURLRequest"); |
| 540 error = network_delegate_->NotifyBeforeURLRequest( |
| 541 this, before_request_callback_, &delegate_redirect_url_); |
| 542 } |
| 536 // If ERR_IO_PENDING is returned, the delegate will invoke | 543 // If ERR_IO_PENDING is returned, the delegate will invoke |
| 537 // |before_request_callback_| later. | 544 // |before_request_callback_| later. |
| 538 if (error != ERR_IO_PENDING) | 545 if (error != ERR_IO_PENDING) |
| 539 BeforeRequestComplete(error); | 546 BeforeRequestComplete(error); |
| 540 return; | 547 return; |
| 541 } | 548 } |
| 542 | 549 |
| 543 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed. | 550 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed. |
| 544 tracked_objects::ScopedTracker tracking_profile2( | 551 tracked_objects::ScopedTracker tracking_profile2( |
| 545 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start 2")); | 552 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::Start 2")); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 notified_before_network_start_(false) { | 588 notified_before_network_start_(false) { |
| 582 // Sanity check out environment. | 589 // Sanity check out environment. |
| 583 DCHECK(base::MessageLoop::current()) | 590 DCHECK(base::MessageLoop::current()) |
| 584 << "The current base::MessageLoop must exist"; | 591 << "The current base::MessageLoop must exist"; |
| 585 | 592 |
| 586 context->url_requests()->insert(this); | 593 context->url_requests()->insert(this); |
| 587 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE); | 594 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE); |
| 588 } | 595 } |
| 589 | 596 |
| 590 void URLRequest::BeforeRequestComplete(int error) { | 597 void URLRequest::BeforeRequestComplete(int error) { |
| 598 TRACE_EVENT0("toplevel", "NetworkDelegate::BeforeRequestComplete"); |
| 591 DCHECK(!job_.get()); | 599 DCHECK(!job_.get()); |
| 592 DCHECK_NE(ERR_IO_PENDING, error); | 600 DCHECK_NE(ERR_IO_PENDING, error); |
| 593 | 601 |
| 594 // Check that there are no callbacks to already canceled requests. | 602 // Check that there are no callbacks to already canceled requests. |
| 595 DCHECK_NE(URLRequestStatus::CANCELED, status_.status()); | 603 DCHECK_NE(URLRequestStatus::CANCELED, status_.status()); |
| 596 | 604 |
| 597 OnCallToDelegateComplete(); | 605 OnCallToDelegateComplete(); |
| 598 | 606 |
| 599 if (error != OK) { | 607 if (error != OK) { |
| 600 std::string source("delegate"); | 608 std::string source("delegate"); |
| 601 net_log_.AddEvent(NetLog::TYPE_CANCELLED, | 609 net_log_.AddEvent(NetLog::TYPE_CANCELLED, |
| 602 NetLog::StringCallback("source", &source)); | 610 NetLog::StringCallback("source", &source)); |
| 603 StartJob(new URLRequestErrorJob(this, network_delegate_, error)); | 611 StartJob(new URLRequestErrorJob(this, network_delegate_, error)); |
| 604 } else if (!delegate_redirect_url_.is_empty()) { | 612 } else if (!delegate_redirect_url_.is_empty()) { |
| 605 GURL new_url; | 613 GURL new_url; |
| 606 new_url.Swap(&delegate_redirect_url_); | 614 new_url.Swap(&delegate_redirect_url_); |
| 607 | 615 |
| 608 URLRequestRedirectJob* job = new URLRequestRedirectJob( | 616 URLRequestRedirectJob* job = new URLRequestRedirectJob( |
| 609 this, network_delegate_, new_url, | 617 this, network_delegate_, new_url, |
| 610 // Use status code 307 to preserve the method, so POST requests work. | 618 // Use status code 307 to preserve the method, so POST requests work. |
| 611 URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "Delegate"); | 619 URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "Delegate"); |
| 612 StartJob(job); | 620 StartJob(job); |
| 613 } else { | 621 } else { |
| 614 StartJob(URLRequestJobManager::GetInstance()->CreateJob( | 622 StartJob(URLRequestJobManager::GetInstance()->CreateJob( |
| 615 this, network_delegate_)); | 623 this, network_delegate_)); |
| 616 } | 624 } |
| 617 } | 625 } |
| 618 | 626 |
| 619 void URLRequest::StartJob(URLRequestJob* job) { | 627 void URLRequest::StartJob(URLRequestJob* job) { |
| 628 TRACE_EVENT0("toplevel", "URLRequest::StartJob"); |
| 620 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed. | 629 // TODO(mmenke): Remove ScopedTracker below once crbug.com/456327 is fixed. |
| 621 tracked_objects::ScopedTracker tracking_profile( | 630 tracked_objects::ScopedTracker tracking_profile( |
| 622 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::StartJob")); | 631 FROM_HERE_WITH_EXPLICIT_FUNCTION("456327 URLRequest::StartJob")); |
| 623 | 632 |
| 624 DCHECK(!is_pending_); | 633 DCHECK(!is_pending_); |
| 625 DCHECK(!job_.get()); | 634 DCHECK(!job_.get()); |
| 626 | 635 |
| 627 net_log_.BeginEvent( | 636 net_log_.BeginEvent( |
| 628 NetLog::TYPE_URL_REQUEST_START_JOB, | 637 NetLog::TYPE_URL_REQUEST_START_JOB, |
| 629 base::Bind(&NetLogURLRequestStartCallback, | 638 base::Bind(&NetLogURLRequestStartCallback, |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 // Job sends an asynchronous notification but by the time this is processed, | 739 // Job sends an asynchronous notification but by the time this is processed, |
| 731 // our |context_| is NULL. | 740 // our |context_| is NULL. |
| 732 NotifyRequestCompleted(); | 741 NotifyRequestCompleted(); |
| 733 | 742 |
| 734 // The Job will call our NotifyDone method asynchronously. This is done so | 743 // The Job will call our NotifyDone method asynchronously. This is done so |
| 735 // that the Delegate implementation can call Cancel without having to worry | 744 // that the Delegate implementation can call Cancel without having to worry |
| 736 // about being called recursively. | 745 // about being called recursively. |
| 737 } | 746 } |
| 738 | 747 |
| 739 bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) { | 748 bool URLRequest::Read(IOBuffer* dest, int dest_size, int* bytes_read) { |
| 749 TRACE_EVENT0("toplevel", "URLRequest::Read"); |
| 750 |
| 740 DCHECK(job_.get()); | 751 DCHECK(job_.get()); |
| 741 DCHECK(bytes_read); | 752 DCHECK(bytes_read); |
| 742 *bytes_read = 0; | 753 *bytes_read = 0; |
| 743 | 754 |
| 744 // If this is the first read, end the delegate call that may have started in | 755 // If this is the first read, end the delegate call that may have started in |
| 745 // OnResponseStarted. | 756 // OnResponseStarted. |
| 746 OnCallToDelegateComplete(); | 757 OnCallToDelegateComplete(); |
| 747 | 758 |
| 748 // This handles a cancel that happens while paused. | 759 // This handles a cancel that happens while paused. |
| 749 // TODO(ahendrickson): DCHECK() that it is not done after | 760 // TODO(ahendrickson): DCHECK() that it is not done after |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 | 816 |
| 806 void URLRequest::ResumeNetworkStart() { | 817 void URLRequest::ResumeNetworkStart() { |
| 807 DCHECK(job_.get()); | 818 DCHECK(job_.get()); |
| 808 DCHECK(notified_before_network_start_); | 819 DCHECK(notified_before_network_start_); |
| 809 | 820 |
| 810 OnCallToDelegateComplete(); | 821 OnCallToDelegateComplete(); |
| 811 job_->ResumeNetworkStart(); | 822 job_->ResumeNetworkStart(); |
| 812 } | 823 } |
| 813 | 824 |
| 814 void URLRequest::NotifyResponseStarted() { | 825 void URLRequest::NotifyResponseStarted() { |
| 826 TRACE_EVENT0("toplevel", "URLRequest::NotifyResponseStarted"); |
| 815 int net_error = OK; | 827 int net_error = OK; |
| 816 if (!status_.is_success()) | 828 if (!status_.is_success()) |
| 817 net_error = status_.error(); | 829 net_error = status_.error(); |
| 818 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_URL_REQUEST_START_JOB, | 830 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_URL_REQUEST_START_JOB, |
| 819 net_error); | 831 net_error); |
| 820 | 832 |
| 821 URLRequestJob* job = | 833 URLRequestJob* job = |
| 822 URLRequestJobManager::GetInstance()->MaybeInterceptResponse( | 834 URLRequestJobManager::GetInstance()->MaybeInterceptResponse( |
| 823 this, network_delegate_); | 835 this, network_delegate_); |
| 824 if (job) { | 836 if (job) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 load_timing_info_ = LoadTimingInfo(); | 908 load_timing_info_ = LoadTimingInfo(); |
| 897 load_timing_info_.request_start_time = response_info_.request_time; | 909 load_timing_info_.request_start_time = response_info_.request_time; |
| 898 load_timing_info_.request_start = base::TimeTicks::Now(); | 910 load_timing_info_.request_start = base::TimeTicks::Now(); |
| 899 | 911 |
| 900 status_ = URLRequestStatus(); | 912 status_ = URLRequestStatus(); |
| 901 is_pending_ = false; | 913 is_pending_ = false; |
| 902 proxy_server_ = HostPortPair(); | 914 proxy_server_ = HostPortPair(); |
| 903 } | 915 } |
| 904 | 916 |
| 905 void URLRequest::OrphanJob() { | 917 void URLRequest::OrphanJob() { |
| 918 TRACE_EVENT0("toplevel", "URLRequest::OrphanJob"); |
| 906 // When calling this function, please check that URLRequestHttpJob is | 919 // When calling this function, please check that URLRequestHttpJob is |
| 907 // not in between calling NetworkDelegate::NotifyHeadersReceived receiving | 920 // not in between calling NetworkDelegate::NotifyHeadersReceived receiving |
| 908 // the call back. This is currently guaranteed by the following strategies: | 921 // the call back. This is currently guaranteed by the following strategies: |
| 909 // - OrphanJob is called on JobRestart, in this case the URLRequestJob cannot | 922 // - OrphanJob is called on JobRestart, in this case the URLRequestJob cannot |
| 910 // be receiving any headers at that time. | 923 // be receiving any headers at that time. |
| 911 // - OrphanJob is called in ~URLRequest, in this case | 924 // - OrphanJob is called in ~URLRequest, in this case |
| 912 // NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate | 925 // NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate |
| 913 // that the callback becomes invalid. | 926 // that the callback becomes invalid. |
| 914 job_->Kill(); | 927 job_->Kill(); |
| 915 job_ = NULL; | 928 job_ = NULL; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1108 delegate_->OnCertificateRequested(this, cert_request_info); | 1121 delegate_->OnCertificateRequested(this, cert_request_info); |
| 1109 } | 1122 } |
| 1110 | 1123 |
| 1111 void URLRequest::NotifySSLCertificateError(const SSLInfo& ssl_info, | 1124 void URLRequest::NotifySSLCertificateError(const SSLInfo& ssl_info, |
| 1112 bool fatal) { | 1125 bool fatal) { |
| 1113 status_ = URLRequestStatus(); | 1126 status_ = URLRequestStatus(); |
| 1114 delegate_->OnSSLCertificateError(this, ssl_info, fatal); | 1127 delegate_->OnSSLCertificateError(this, ssl_info, fatal); |
| 1115 } | 1128 } |
| 1116 | 1129 |
| 1117 bool URLRequest::CanGetCookies(const CookieList& cookie_list) const { | 1130 bool URLRequest::CanGetCookies(const CookieList& cookie_list) const { |
| 1131 TRACE_EVENT0("toplevel", "URLRequest::CanGetCookies"); |
| 1118 DCHECK(!(load_flags_ & LOAD_DO_NOT_SEND_COOKIES)); | 1132 DCHECK(!(load_flags_ & LOAD_DO_NOT_SEND_COOKIES)); |
| 1119 if (network_delegate_) { | 1133 if (network_delegate_) { |
| 1120 return network_delegate_->CanGetCookies(*this, cookie_list); | 1134 return network_delegate_->CanGetCookies(*this, cookie_list); |
| 1121 } | 1135 } |
| 1122 return g_default_can_use_cookies; | 1136 return g_default_can_use_cookies; |
| 1123 } | 1137 } |
| 1124 | 1138 |
| 1125 bool URLRequest::CanSetCookie(const std::string& cookie_line, | 1139 bool URLRequest::CanSetCookie(const std::string& cookie_line, |
| 1126 CookieOptions* options) const { | 1140 CookieOptions* options) const { |
| 1127 DCHECK(!(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES)); | 1141 DCHECK(!(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 job_->GetLoadTimingInfo(&load_timing_info_); | 1186 job_->GetLoadTimingInfo(&load_timing_info_); |
| 1173 | 1187 |
| 1174 load_timing_info_.request_start = request_start; | 1188 load_timing_info_.request_start = request_start; |
| 1175 load_timing_info_.request_start_time = request_start_time; | 1189 load_timing_info_.request_start_time = request_start_time; |
| 1176 | 1190 |
| 1177 ConvertRealLoadTimesToBlockingTimes(&load_timing_info_); | 1191 ConvertRealLoadTimesToBlockingTimes(&load_timing_info_); |
| 1178 } | 1192 } |
| 1179 } | 1193 } |
| 1180 | 1194 |
| 1181 void URLRequest::NotifyRequestCompleted() { | 1195 void URLRequest::NotifyRequestCompleted() { |
| 1196 TRACE_EVENT0("toplevel", "URLRequest::NotifyRequestCompleted"); |
| 1182 // TODO(battre): Get rid of this check, according to willchan it should | 1197 // TODO(battre): Get rid of this check, according to willchan it should |
| 1183 // not be needed. | 1198 // not be needed. |
| 1184 if (has_notified_completion_) | 1199 if (has_notified_completion_) |
| 1185 return; | 1200 return; |
| 1186 | 1201 |
| 1187 is_pending_ = false; | 1202 is_pending_ = false; |
| 1188 is_redirecting_ = false; | 1203 is_redirecting_ = false; |
| 1189 has_notified_completion_ = true; | 1204 has_notified_completion_ = true; |
| 1190 if (network_delegate_) | 1205 if (network_delegate_) |
| 1191 network_delegate_->NotifyCompleted(this, job_.get() != NULL); | 1206 network_delegate_->NotifyCompleted(this, job_.get() != NULL); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1216 } | 1231 } |
| 1217 | 1232 |
| 1218 void URLRequest::GetConnectionAttempts(ConnectionAttempts* out) const { | 1233 void URLRequest::GetConnectionAttempts(ConnectionAttempts* out) const { |
| 1219 if (job_) | 1234 if (job_) |
| 1220 job_->GetConnectionAttempts(out); | 1235 job_->GetConnectionAttempts(out); |
| 1221 else | 1236 else |
| 1222 out->clear(); | 1237 out->clear(); |
| 1223 } | 1238 } |
| 1224 | 1239 |
| 1225 } // namespace net | 1240 } // namespace net |
| OLD | NEW |