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 |