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_job.h" | 5 #include "net/url_request/url_request_job.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
13 #include "base/power_monitor/power_monitor.h" | 13 #include "base/power_monitor/power_monitor.h" |
14 #include "base/profiler/scoped_tracker.h" | 14 #include "base/profiler/scoped_tracker.h" |
15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/string_split.h" | |
18 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
19 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
20 #include "base/values.h" | 19 #include "base/values.h" |
21 #include "net/base/auth.h" | 20 #include "net/base/auth.h" |
22 #include "net/base/host_port_pair.h" | 21 #include "net/base/host_port_pair.h" |
23 #include "net/base/io_buffer.h" | 22 #include "net/base/io_buffer.h" |
24 #include "net/base/load_flags.h" | 23 #include "net/base/load_flags.h" |
25 #include "net/base/load_states.h" | 24 #include "net/base/load_states.h" |
26 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
27 #include "net/base/network_delegate.h" | 26 #include "net/base/network_delegate.h" |
(...skipping 28 matching lines...) Expand all Loading... |
56 // See: | 55 // See: |
57 // https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3 | 56 // https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-7.3 |
58 if ((http_status_code == 303 && method != "HEAD") || | 57 if ((http_status_code == 303 && method != "HEAD") || |
59 ((http_status_code == 301 || http_status_code == 302) && | 58 ((http_status_code == 301 || http_status_code == 302) && |
60 method == "POST")) { | 59 method == "POST")) { |
61 return "GET"; | 60 return "GET"; |
62 } | 61 } |
63 return method; | 62 return method; |
64 } | 63 } |
65 | 64 |
66 // A redirect response can contain a Referrer-Policy header | |
67 // (https://w3c.github.io/webappsec-referrer-policy/). This function | |
68 // checks for a Referrer-Policy header, and parses it if | |
69 // present. Returns the referrer policy that should be used for the | |
70 // request. | |
71 URLRequest::ReferrerPolicy ProcessReferrerPolicyHeaderOnRedirect( | |
72 URLRequest* request) { | |
73 URLRequest::ReferrerPolicy new_policy = request->referrer_policy(); | |
74 | |
75 std::string referrer_policy_header; | |
76 request->GetResponseHeaderByName("Referrer-Policy", &referrer_policy_header); | |
77 std::vector<std::string> policy_tokens = | |
78 base::SplitString(referrer_policy_header, ",", base::TRIM_WHITESPACE, | |
79 base::SPLIT_WANT_NONEMPTY); | |
80 | |
81 for (const auto& token : policy_tokens) { | |
82 if (base::CompareCaseInsensitiveASCII(token, "never") == 0 || | |
83 base::CompareCaseInsensitiveASCII(token, "no-referrer") == 0) { | |
84 new_policy = URLRequest::NO_REFERRER; | |
85 continue; | |
86 } | |
87 | |
88 if (base::CompareCaseInsensitiveASCII(token, "default") == 0 || | |
89 base::CompareCaseInsensitiveASCII(token, | |
90 "no-referrer-when-downgrade") == 0) { | |
91 new_policy = | |
92 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE; | |
93 continue; | |
94 } | |
95 | |
96 if (base::CompareCaseInsensitiveASCII(token, "origin") == 0) { | |
97 new_policy = URLRequest::ORIGIN; | |
98 continue; | |
99 } | |
100 | |
101 if (base::CompareCaseInsensitiveASCII(token, "origin-when-cross-origin") == | |
102 0) { | |
103 new_policy = URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN; | |
104 continue; | |
105 } | |
106 | |
107 if (base::CompareCaseInsensitiveASCII(token, "always") == 0 || | |
108 base::CompareCaseInsensitiveASCII(token, "unsafe-url") == 0) { | |
109 new_policy = URLRequest::NEVER_CLEAR_REFERRER; | |
110 continue; | |
111 } | |
112 } | |
113 return new_policy; | |
114 } | |
115 | |
116 } // namespace | 65 } // namespace |
117 | 66 |
118 URLRequestJob::URLRequestJob(URLRequest* request, | 67 URLRequestJob::URLRequestJob(URLRequest* request, |
119 NetworkDelegate* network_delegate) | 68 NetworkDelegate* network_delegate) |
120 : request_(request), | 69 : request_(request), |
121 done_(false), | 70 done_(false), |
122 prefilter_bytes_read_(0), | 71 prefilter_bytes_read_(0), |
123 postfilter_bytes_read_(0), | 72 postfilter_bytes_read_(0), |
124 filter_needs_more_output_space_(false), | 73 filter_needs_more_output_space_(false), |
125 filtered_read_buffer_len_(0), | 74 filtered_read_buffer_len_(0), |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 return GURL(); | 337 return GURL(); |
389 } else { | 338 } else { |
390 return original_referrer.GetOrigin(); | 339 return original_referrer.GetOrigin(); |
391 } | 340 } |
392 | 341 |
393 case URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN: | 342 case URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN: |
394 return same_origin ? original_referrer : original_referrer.GetOrigin(); | 343 return same_origin ? original_referrer : original_referrer.GetOrigin(); |
395 | 344 |
396 case URLRequest::NEVER_CLEAR_REFERRER: | 345 case URLRequest::NEVER_CLEAR_REFERRER: |
397 return original_referrer; | 346 return original_referrer; |
398 case URLRequest::ORIGIN: | |
399 return original_referrer.GetOrigin(); | |
400 case URLRequest::NO_REFERRER: | |
401 return GURL(); | |
402 case URLRequest::MAX_REFERRER_POLICY: | |
403 NOTREACHED(); | |
404 return GURL(); | |
405 } | 347 } |
406 | 348 |
407 NOTREACHED(); | 349 NOTREACHED(); |
408 return GURL(); | 350 return GURL(); |
409 } | 351 } |
410 | 352 |
411 void URLRequestJob::NotifyCertificateRequested( | 353 void URLRequestJob::NotifyCertificateRequested( |
412 SSLCertRequestInfo* cert_request_info) { | 354 SSLCertRequestInfo* cert_request_info) { |
413 request_->NotifyCertificateRequested(cert_request_info); | 355 request_->NotifyCertificateRequested(cert_request_info); |
414 } | 356 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 // the time stamps if it has that information. The default request_time is | 391 // the time stamps if it has that information. The default request_time is |
450 // set by URLRequest before it calls our Start method. | 392 // set by URLRequest before it calls our Start method. |
451 request_->response_info_.response_time = base::Time::Now(); | 393 request_->response_info_.response_time = base::Time::Now(); |
452 GetResponseInfo(&request_->response_info_); | 394 GetResponseInfo(&request_->response_info_); |
453 | 395 |
454 MaybeNotifyNetworkBytes(); | 396 MaybeNotifyNetworkBytes(); |
455 request_->OnHeadersComplete(); | 397 request_->OnHeadersComplete(); |
456 | 398 |
457 GURL new_location; | 399 GURL new_location; |
458 int http_status_code; | 400 int http_status_code; |
459 | |
460 if (IsRedirectResponse(&new_location, &http_status_code)) { | 401 if (IsRedirectResponse(&new_location, &http_status_code)) { |
461 // Redirect response bodies are not read. Notify the transaction | 402 // Redirect response bodies are not read. Notify the transaction |
462 // so it does not treat being stopped as an error. | 403 // so it does not treat being stopped as an error. |
463 DoneReadingRedirectResponse(); | 404 DoneReadingRedirectResponse(); |
464 | 405 |
465 // When notifying the URLRequest::Delegate, it can destroy the request, | 406 // When notifying the URLRequest::Delegate, it can destroy the request, |
466 // which will destroy |this|. After calling to the URLRequest::Delegate, | 407 // which will destroy |this|. After calling to the URLRequest::Delegate, |
467 // pointer must be checked to see if |this| still exists, and if not, the | 408 // pointer must be checked to see if |this| still exists, and if not, the |
468 // code must return immediately. | 409 // code must return immediately. |
469 base::WeakPtr<URLRequestJob> weak_this(weak_factory_.GetWeakPtr()); | 410 base::WeakPtr<URLRequestJob> weak_this(weak_factory_.GetWeakPtr()); |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 | 937 |
997 // Update the first-party URL if appropriate. | 938 // Update the first-party URL if appropriate. |
998 if (request_->first_party_url_policy() == | 939 if (request_->first_party_url_policy() == |
999 URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT) { | 940 URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT) { |
1000 redirect_info.new_first_party_for_cookies = redirect_info.new_url; | 941 redirect_info.new_first_party_for_cookies = redirect_info.new_url; |
1001 } else { | 942 } else { |
1002 redirect_info.new_first_party_for_cookies = | 943 redirect_info.new_first_party_for_cookies = |
1003 request_->first_party_for_cookies(); | 944 request_->first_party_for_cookies(); |
1004 } | 945 } |
1005 | 946 |
1006 if (request_->context()->enable_referrer_policy_header()) { | |
1007 redirect_info.new_referrer_policy = | |
1008 ProcessReferrerPolicyHeaderOnRedirect(request_); | |
1009 } else { | |
1010 redirect_info.new_referrer_policy = request_->referrer_policy(); | |
1011 } | |
1012 | |
1013 // Alter the referrer if redirecting cross-origin (especially HTTP->HTTPS). | 947 // Alter the referrer if redirecting cross-origin (especially HTTP->HTTPS). |
1014 redirect_info.new_referrer = | 948 redirect_info.new_referrer = |
1015 ComputeReferrerForRedirect(redirect_info.new_referrer_policy, | 949 ComputeReferrerForRedirect(request_->referrer_policy(), |
1016 request_->referrer(), redirect_info.new_url) | 950 request_->referrer(), |
1017 .spec(); | 951 redirect_info.new_url).spec(); |
1018 | 952 |
1019 std::string include_referer; | 953 std::string include_referer; |
1020 request_->GetResponseHeaderByName("include-referer-token-binding-id", | 954 request_->GetResponseHeaderByName("include-referer-token-binding-id", |
1021 &include_referer); | 955 &include_referer); |
1022 if (include_referer == "true" && | 956 if (include_referer == "true" && |
1023 request_->ssl_info().token_binding_negotiated) { | 957 request_->ssl_info().token_binding_negotiated) { |
1024 redirect_info.referred_token_binding_host = url.host(); | 958 redirect_info.referred_token_binding_host = url.host(); |
1025 } | 959 } |
1026 | 960 |
1027 return redirect_info; | 961 return redirect_info; |
(...skipping 16 matching lines...) Expand all Loading... |
1044 int64_t total_sent_bytes = GetTotalSentBytes(); | 978 int64_t total_sent_bytes = GetTotalSentBytes(); |
1045 DCHECK_GE(total_sent_bytes, last_notified_total_sent_bytes_); | 979 DCHECK_GE(total_sent_bytes, last_notified_total_sent_bytes_); |
1046 if (total_sent_bytes > last_notified_total_sent_bytes_) { | 980 if (total_sent_bytes > last_notified_total_sent_bytes_) { |
1047 network_delegate_->NotifyNetworkBytesSent( | 981 network_delegate_->NotifyNetworkBytesSent( |
1048 request_, total_sent_bytes - last_notified_total_sent_bytes_); | 982 request_, total_sent_bytes - last_notified_total_sent_bytes_); |
1049 } | 983 } |
1050 last_notified_total_sent_bytes_ = total_sent_bytes; | 984 last_notified_total_sent_bytes_ = total_sent_bytes; |
1051 } | 985 } |
1052 | 986 |
1053 } // namespace net | 987 } // namespace net |
OLD | NEW |