| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "net/base/load_flags.h" | 23 #include "net/base/load_flags.h" |
| 24 #include "net/base/load_timing_info.h" | 24 #include "net/base/load_timing_info.h" |
| 25 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
| 26 #include "net/base/net_log.h" | 26 #include "net/base/net_log.h" |
| 27 #include "net/base/network_change_notifier.h" | 27 #include "net/base/network_change_notifier.h" |
| 28 #include "net/base/network_delegate.h" | 28 #include "net/base/network_delegate.h" |
| 29 #include "net/base/upload_data_stream.h" | 29 #include "net/base/upload_data_stream.h" |
| 30 #include "net/http/http_response_headers.h" | 30 #include "net/http/http_response_headers.h" |
| 31 #include "net/http/http_util.h" | 31 #include "net/http/http_util.h" |
| 32 #include "net/ssl/ssl_cert_request_info.h" | 32 #include "net/ssl/ssl_cert_request_info.h" |
| 33 #include "net/url_request/redirect_info.h" |
| 33 #include "net/url_request/url_request_context.h" | 34 #include "net/url_request/url_request_context.h" |
| 34 #include "net/url_request/url_request_error_job.h" | 35 #include "net/url_request/url_request_error_job.h" |
| 35 #include "net/url_request/url_request_job.h" | 36 #include "net/url_request/url_request_job.h" |
| 36 #include "net/url_request/url_request_job_manager.h" | 37 #include "net/url_request/url_request_job_manager.h" |
| 37 #include "net/url_request/url_request_netlog_params.h" | 38 #include "net/url_request/url_request_netlog_params.h" |
| 38 #include "net/url_request/url_request_redirect_job.h" | 39 #include "net/url_request/url_request_redirect_job.h" |
| 39 | 40 |
| 40 using base::Time; | 41 using base::Time; |
| 41 using std::string; | 42 using std::string; |
| 42 | 43 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 | 163 |
| 163 URLRequestJob* URLRequest::Interceptor::MaybeInterceptResponse( | 164 URLRequestJob* URLRequest::Interceptor::MaybeInterceptResponse( |
| 164 URLRequest* request, NetworkDelegate* network_delegate) { | 165 URLRequest* request, NetworkDelegate* network_delegate) { |
| 165 return NULL; | 166 return NULL; |
| 166 } | 167 } |
| 167 | 168 |
| 168 /////////////////////////////////////////////////////////////////////////////// | 169 /////////////////////////////////////////////////////////////////////////////// |
| 169 // URLRequest::Delegate | 170 // URLRequest::Delegate |
| 170 | 171 |
| 171 void URLRequest::Delegate::OnReceivedRedirect(URLRequest* request, | 172 void URLRequest::Delegate::OnReceivedRedirect(URLRequest* request, |
| 172 const GURL& new_url, | 173 const RedirectInfo& redirect_info, |
| 173 bool* defer_redirect) { | 174 bool* defer_redirect) { |
| 174 } | 175 } |
| 175 | 176 |
| 176 void URLRequest::Delegate::OnAuthRequired(URLRequest* request, | 177 void URLRequest::Delegate::OnAuthRequired(URLRequest* request, |
| 177 AuthChallengeInfo* auth_info) { | 178 AuthChallengeInfo* auth_info) { |
| 178 request->CancelAuth(); | 179 request->CancelAuth(); |
| 179 } | 180 } |
| 180 | 181 |
| 181 void URLRequest::Delegate::OnCertificateRequested( | 182 void URLRequest::Delegate::OnCertificateRequested( |
| 182 URLRequest* request, | 183 URLRequest* request, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 RequestPriority priority, | 253 RequestPriority priority, |
| 253 Delegate* delegate, | 254 Delegate* delegate, |
| 254 const URLRequestContext* context, | 255 const URLRequestContext* context, |
| 255 CookieStore* cookie_store) { | 256 CookieStore* cookie_store) { |
| 256 context_ = context; | 257 context_ = context; |
| 257 network_delegate_ = context->network_delegate(); | 258 network_delegate_ = context->network_delegate(); |
| 258 net_log_ = BoundNetLog::Make(context->net_log(), NetLog::SOURCE_URL_REQUEST); | 259 net_log_ = BoundNetLog::Make(context->net_log(), NetLog::SOURCE_URL_REQUEST); |
| 259 url_chain_.push_back(url); | 260 url_chain_.push_back(url); |
| 260 method_ = "GET"; | 261 method_ = "GET"; |
| 261 referrer_policy_ = CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE; | 262 referrer_policy_ = CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE; |
| 263 first_party_url_policy_ = NEVER_CHANGE_FIRST_PARTY_URL; |
| 262 load_flags_ = LOAD_NORMAL; | 264 load_flags_ = LOAD_NORMAL; |
| 263 delegate_ = delegate; | 265 delegate_ = delegate; |
| 264 is_pending_ = false; | 266 is_pending_ = false; |
| 265 is_redirecting_ = false; | 267 is_redirecting_ = false; |
| 266 redirect_limit_ = kMaxRedirects; | 268 redirect_limit_ = kMaxRedirects; |
| 267 priority_ = priority; | 269 priority_ = priority; |
| 268 calling_delegate_ = false; | 270 calling_delegate_ = false; |
| 269 use_blocked_by_as_load_param_ =false; | 271 use_blocked_by_as_load_param_ =false; |
| 270 before_request_callback_ = base::Bind(&URLRequest::BeforeRequestComplete, | 272 before_request_callback_ = base::Bind(&URLRequest::BeforeRequestComplete, |
| 271 base::Unretained(this)); | 273 base::Unretained(this)); |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 if (!url.is_valid()) { | 558 if (!url.is_valid()) { |
| 557 // We handle error cases. | 559 // We handle error cases. |
| 558 return true; | 560 return true; |
| 559 } | 561 } |
| 560 | 562 |
| 561 return IsHandledProtocol(url.scheme()); | 563 return IsHandledProtocol(url.scheme()); |
| 562 } | 564 } |
| 563 | 565 |
| 564 void URLRequest::set_first_party_for_cookies( | 566 void URLRequest::set_first_party_for_cookies( |
| 565 const GURL& first_party_for_cookies) { | 567 const GURL& first_party_for_cookies) { |
| 568 DCHECK(!is_pending_); |
| 566 first_party_for_cookies_ = first_party_for_cookies; | 569 first_party_for_cookies_ = first_party_for_cookies; |
| 567 } | 570 } |
| 568 | 571 |
| 572 void URLRequest::set_first_party_url_policy( |
| 573 FirstPartyURLPolicy first_party_url_policy) { |
| 574 DCHECK(!is_pending_); |
| 575 first_party_url_policy_ = first_party_url_policy; |
| 576 } |
| 577 |
| 569 void URLRequest::set_method(const std::string& method) { | 578 void URLRequest::set_method(const std::string& method) { |
| 570 DCHECK(!is_pending_); | 579 DCHECK(!is_pending_); |
| 571 method_ = method; | 580 method_ = method; |
| 572 } | 581 } |
| 573 | 582 |
| 574 // static | 583 // static |
| 575 std::string URLRequest::ComputeMethodForRedirect( | 584 std::string URLRequest::ComputeMethodForRedirect( |
| 576 const std::string& method, | 585 const std::string& method, |
| 577 int http_status_code) { | 586 int http_status_code) { |
| 578 // For 303 redirects, all request methods except HEAD are converted to GET, | 587 // For 303 redirects, all request methods except HEAD are converted to GET, |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 if (rv && *bytes_read <= 0 && status_.is_success()) | 824 if (rv && *bytes_read <= 0 && status_.is_success()) |
| 816 NotifyRequestCompleted(); | 825 NotifyRequestCompleted(); |
| 817 return rv; | 826 return rv; |
| 818 } | 827 } |
| 819 | 828 |
| 820 void URLRequest::StopCaching() { | 829 void URLRequest::StopCaching() { |
| 821 DCHECK(job_.get()); | 830 DCHECK(job_.get()); |
| 822 job_->StopCaching(); | 831 job_->StopCaching(); |
| 823 } | 832 } |
| 824 | 833 |
| 825 void URLRequest::NotifyReceivedRedirect(const GURL& location, | 834 void URLRequest::NotifyReceivedRedirect(const RedirectInfo& redirect_info, |
| 826 bool* defer_redirect) { | 835 bool* defer_redirect) { |
| 827 is_redirecting_ = true; | 836 is_redirecting_ = true; |
| 828 | 837 |
| 838 // TODO(davidben): Pass the full RedirectInfo down to MaybeInterceptRedirect? |
| 829 URLRequestJob* job = | 839 URLRequestJob* job = |
| 830 URLRequestJobManager::GetInstance()->MaybeInterceptRedirect( | 840 URLRequestJobManager::GetInstance()->MaybeInterceptRedirect( |
| 831 this, network_delegate_, location); | 841 this, network_delegate_, redirect_info.new_url); |
| 832 if (job) { | 842 if (job) { |
| 833 RestartWithJob(job); | 843 RestartWithJob(job); |
| 834 } else if (delegate_) { | 844 } else if (delegate_) { |
| 835 OnCallToDelegate(); | 845 OnCallToDelegate(); |
| 836 delegate_->OnReceivedRedirect(this, location, defer_redirect); | 846 delegate_->OnReceivedRedirect(this, redirect_info, defer_redirect); |
| 837 // |this| may be have been destroyed here. | 847 // |this| may be have been destroyed here. |
| 838 } | 848 } |
| 839 } | 849 } |
| 840 | 850 |
| 841 void URLRequest::NotifyBeforeNetworkStart(bool* defer) { | 851 void URLRequest::NotifyBeforeNetworkStart(bool* defer) { |
| 842 if (delegate_ && !notified_before_network_start_) { | 852 if (delegate_ && !notified_before_network_start_) { |
| 843 OnCallToDelegate(); | 853 OnCallToDelegate(); |
| 844 delegate_->OnBeforeNetworkStart(this, defer); | 854 delegate_->OnBeforeNetworkStart(this, defer); |
| 845 if (!*defer) | 855 if (!*defer) |
| 846 OnCallToDelegateComplete(); | 856 OnCallToDelegateComplete(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 // - OrphanJob is called on JobRestart, in this case the URLRequestJob cannot | 959 // - OrphanJob is called on JobRestart, in this case the URLRequestJob cannot |
| 950 // be receiving any headers at that time. | 960 // be receiving any headers at that time. |
| 951 // - OrphanJob is called in ~URLRequest, in this case | 961 // - OrphanJob is called in ~URLRequest, in this case |
| 952 // NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate | 962 // NetworkDelegate::NotifyURLRequestDestroyed notifies the NetworkDelegate |
| 953 // that the callback becomes invalid. | 963 // that the callback becomes invalid. |
| 954 job_->Kill(); | 964 job_->Kill(); |
| 955 job_->DetachRequest(); // ensures that the job will not call us again | 965 job_->DetachRequest(); // ensures that the job will not call us again |
| 956 job_ = NULL; | 966 job_ = NULL; |
| 957 } | 967 } |
| 958 | 968 |
| 959 int URLRequest::Redirect(const GURL& location, int http_status_code) { | 969 int URLRequest::Redirect(const RedirectInfo& redirect_info) { |
| 960 // Matches call in NotifyReceivedRedirect. | 970 // Matches call in NotifyReceivedRedirect. |
| 961 OnCallToDelegateComplete(); | 971 OnCallToDelegateComplete(); |
| 962 if (net_log_.IsLogging()) { | 972 if (net_log_.IsLogging()) { |
| 963 net_log_.AddEvent( | 973 net_log_.AddEvent( |
| 964 NetLog::TYPE_URL_REQUEST_REDIRECTED, | 974 NetLog::TYPE_URL_REQUEST_REDIRECTED, |
| 965 NetLog::StringCallback("location", &location.possibly_invalid_spec())); | 975 NetLog::StringCallback("location", |
| 976 &redirect_info.new_url.possibly_invalid_spec())); |
| 966 } | 977 } |
| 967 | 978 |
| 979 // TODO(davidben): Pass the full RedirectInfo to the NetworkDelegate. |
| 968 if (network_delegate_) | 980 if (network_delegate_) |
| 969 network_delegate_->NotifyBeforeRedirect(this, location); | 981 network_delegate_->NotifyBeforeRedirect(this, redirect_info.new_url); |
| 970 | 982 |
| 971 if (redirect_limit_ <= 0) { | 983 if (redirect_limit_ <= 0) { |
| 972 DVLOG(1) << "disallowing redirect: exceeds limit"; | 984 DVLOG(1) << "disallowing redirect: exceeds limit"; |
| 973 return ERR_TOO_MANY_REDIRECTS; | 985 return ERR_TOO_MANY_REDIRECTS; |
| 974 } | 986 } |
| 975 | 987 |
| 976 if (!location.is_valid()) | 988 if (!redirect_info.new_url.is_valid()) |
| 977 return ERR_INVALID_URL; | 989 return ERR_INVALID_URL; |
| 978 | 990 |
| 979 if (!job_->IsSafeRedirect(location)) { | 991 if (!job_->IsSafeRedirect(redirect_info.new_url)) { |
| 980 DVLOG(1) << "disallowing redirect: unsafe protocol"; | 992 DVLOG(1) << "disallowing redirect: unsafe protocol"; |
| 981 return ERR_UNSAFE_REDIRECT; | 993 return ERR_UNSAFE_REDIRECT; |
| 982 } | 994 } |
| 983 | 995 |
| 984 if (!final_upload_progress_.position()) | 996 if (!final_upload_progress_.position()) |
| 985 final_upload_progress_ = job_->GetUploadProgress(); | 997 final_upload_progress_ = job_->GetUploadProgress(); |
| 986 PrepareToRestart(); | 998 PrepareToRestart(); |
| 987 | 999 |
| 988 std::string new_method(ComputeMethodForRedirect(method_, http_status_code)); | 1000 if (redirect_info.new_method != method_) { |
| 989 if (new_method != method_) { | 1001 // TODO(davidben): This logic still needs to be replicated at the consumers. |
| 990 if (method_ == "POST") { | 1002 if (method_ == "POST") { |
| 991 // If being switched from POST, must remove headers that were specific to | 1003 // If being switched from POST, must remove headers that were specific to |
| 992 // the POST and don't have meaning in other methods. For example the | 1004 // the POST and don't have meaning in other methods. For example the |
| 993 // inclusion of a multipart Content-Type header in GET can cause problems | 1005 // inclusion of a multipart Content-Type header in GET can cause problems |
| 994 // with some servers: | 1006 // with some servers: |
| 995 // http://code.google.com/p/chromium/issues/detail?id=843 | 1007 // http://code.google.com/p/chromium/issues/detail?id=843 |
| 996 StripPostSpecificHeaders(&extra_request_headers_); | 1008 StripPostSpecificHeaders(&extra_request_headers_); |
| 997 } | 1009 } |
| 998 upload_data_stream_.reset(); | 1010 upload_data_stream_.reset(); |
| 999 method_.swap(new_method); | 1011 method_ = redirect_info.new_method; |
| 1000 } | 1012 } |
| 1001 | 1013 |
| 1002 // Suppress the referrer if we're redirecting out of https. | 1014 referrer_ = redirect_info.new_referrer; |
| 1003 if (referrer_policy_ == | 1015 first_party_for_cookies_ = redirect_info.new_first_party_for_cookies; |
| 1004 CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE && | |
| 1005 GURL(referrer_).SchemeIsSecure() && !location.SchemeIsSecure()) { | |
| 1006 referrer_.clear(); | |
| 1007 } | |
| 1008 | 1016 |
| 1009 url_chain_.push_back(location); | 1017 url_chain_.push_back(redirect_info.new_url); |
| 1010 --redirect_limit_; | 1018 --redirect_limit_; |
| 1011 | 1019 |
| 1012 Start(); | 1020 Start(); |
| 1013 return OK; | 1021 return OK; |
| 1014 } | 1022 } |
| 1015 | 1023 |
| 1016 const URLRequestContext* URLRequest::context() const { | 1024 const URLRequestContext* URLRequest::context() const { |
| 1017 return context_; | 1025 return context_; |
| 1018 } | 1026 } |
| 1019 | 1027 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1232 new base::debug::StackTrace(NULL, 0); | 1240 new base::debug::StackTrace(NULL, 0); |
| 1233 *stack_trace_copy = stack_trace; | 1241 *stack_trace_copy = stack_trace; |
| 1234 stack_trace_.reset(stack_trace_copy); | 1242 stack_trace_.reset(stack_trace_copy); |
| 1235 } | 1243 } |
| 1236 | 1244 |
| 1237 const base::debug::StackTrace* URLRequest::stack_trace() const { | 1245 const base::debug::StackTrace* URLRequest::stack_trace() const { |
| 1238 return stack_trace_.get(); | 1246 return stack_trace_.get(); |
| 1239 } | 1247 } |
| 1240 | 1248 |
| 1241 } // namespace net | 1249 } // namespace net |
| OLD | NEW |