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 19 matching lines...) Expand all Loading... |
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/redirect_info.h" |
34 #include "net/url_request/url_request_context.h" | 34 #include "net/url_request/url_request_context.h" |
35 #include "net/url_request/url_request_error_job.h" | 35 #include "net/url_request/url_request_error_job.h" |
36 #include "net/url_request/url_request_job.h" | 36 #include "net/url_request/url_request_job.h" |
37 #include "net/url_request/url_request_job_manager.h" | 37 #include "net/url_request/url_request_job_manager.h" |
38 #include "net/url_request/url_request_netlog_params.h" | 38 #include "net/url_request/url_request_netlog_params.h" |
39 #include "net/url_request/url_request_redirect_job.h" | 39 #include "net/url_request/url_request_redirect_job.h" |
| 40 #include "url/gurl.h" |
| 41 #include "url/origin.h" |
40 | 42 |
41 using base::Time; | 43 using base::Time; |
42 using std::string; | 44 using std::string; |
43 | 45 |
44 namespace net { | 46 namespace net { |
45 | 47 |
46 namespace { | 48 namespace { |
47 | 49 |
48 // Max number of http redirects to follow. Same number as gecko. | 50 // Max number of http redirects to follow. Same number as gecko. |
49 const int kMaxRedirects = 20; | 51 const int kMaxRedirects = 20; |
50 | 52 |
51 // Discard headers which have meaning in POST (Content-Length, Content-Type, | 53 // Discard headers which have meaning in POST (Content-Length, Content-Type, |
52 // Origin). | 54 // Origin). |
53 void StripPostSpecificHeaders(HttpRequestHeaders* headers) { | 55 void StripPostSpecificHeaders(HttpRequestHeaders* headers) { |
54 // These are headers that may be attached to a POST. | 56 // These are headers that may be attached to a POST. |
55 headers->RemoveHeader(HttpRequestHeaders::kContentLength); | 57 headers->RemoveHeader(HttpRequestHeaders::kContentLength); |
56 headers->RemoveHeader(HttpRequestHeaders::kContentType); | 58 headers->RemoveHeader(HttpRequestHeaders::kContentType); |
| 59 // TODO(jww): This is Origin header removal is probably layering violation and |
| 60 // should be refactored into //content. See https://crbug.com/471397. |
57 headers->RemoveHeader(HttpRequestHeaders::kOrigin); | 61 headers->RemoveHeader(HttpRequestHeaders::kOrigin); |
58 } | 62 } |
59 | 63 |
60 // TODO(battre): Delete this, see http://crbug.com/89321: | 64 // TODO(battre): Delete this, see http://crbug.com/89321: |
61 // This counter keeps track of the identifiers used for URL requests so far. | 65 // This counter keeps track of the identifiers used for URL requests so far. |
62 // 0 is reserved to represent an invalid ID. | 66 // 0 is reserved to represent an invalid ID. |
63 uint64 g_next_url_request_identifier = 1; | 67 uint64 g_next_url_request_identifier = 1; |
64 | 68 |
65 // This lock protects g_next_url_request_identifier. | 69 // This lock protects g_next_url_request_identifier. |
66 base::LazyInstance<base::Lock>::Leaky | 70 base::LazyInstance<base::Lock>::Leaky |
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 // the POST and don't have meaning in other methods. For example the | 937 // the POST and don't have meaning in other methods. For example the |
934 // inclusion of a multipart Content-Type header in GET can cause problems | 938 // inclusion of a multipart Content-Type header in GET can cause problems |
935 // with some servers: | 939 // with some servers: |
936 // http://code.google.com/p/chromium/issues/detail?id=843 | 940 // http://code.google.com/p/chromium/issues/detail?id=843 |
937 StripPostSpecificHeaders(&extra_request_headers_); | 941 StripPostSpecificHeaders(&extra_request_headers_); |
938 } | 942 } |
939 upload_data_stream_.reset(); | 943 upload_data_stream_.reset(); |
940 method_ = redirect_info.new_method; | 944 method_ = redirect_info.new_method; |
941 } | 945 } |
942 | 946 |
| 947 // Cross-origin redirects should not result in an Origin header value that is |
| 948 // equal to the original request's Origin header. This is necessary to prevent |
| 949 // a reflection of POST requests to bypass CSRF protections. If the header was |
| 950 // not set to "null", a POST request from origin A to a malicious origin M |
| 951 // could be redirected by M back to A. |
| 952 // |
| 953 // In the Section 4.2, Step 4.10 of the Fetch spec |
| 954 // (https://fetch.spec.whatwg.org/#concept-http-fetch), it states that on |
| 955 // cross-origin 301, 302, 303, 307, and 308 redirects, the user agent should |
| 956 // set the request's origin to an "opaque identifier," which serializes to |
| 957 // "null." This matches Firefox and IE behavior, although it supercedes the |
| 958 // suggested behavior in RFC 6454, "The Web Origin Concept." |
| 959 // |
| 960 // See also https://crbug.com/465517. |
| 961 // |
| 962 // TODO(jww): This is probably layering violation and should be refactored |
| 963 // into //content. See https://crbug.com/471397. |
| 964 if (redirect_info.new_url.GetOrigin() != url().GetOrigin() && |
| 965 extra_request_headers_.HasHeader(HttpRequestHeaders::kOrigin)) { |
| 966 extra_request_headers_.SetHeader(HttpRequestHeaders::kOrigin, |
| 967 url::Origin().string()); |
| 968 } |
| 969 |
943 referrer_ = redirect_info.new_referrer; | 970 referrer_ = redirect_info.new_referrer; |
944 first_party_for_cookies_ = redirect_info.new_first_party_for_cookies; | 971 first_party_for_cookies_ = redirect_info.new_first_party_for_cookies; |
945 | 972 |
946 url_chain_.push_back(redirect_info.new_url); | 973 url_chain_.push_back(redirect_info.new_url); |
947 --redirect_limit_; | 974 --redirect_limit_; |
948 | 975 |
949 Start(); | 976 Start(); |
950 return OK; | 977 return OK; |
951 } | 978 } |
952 | 979 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 new base::debug::StackTrace(NULL, 0); | 1215 new base::debug::StackTrace(NULL, 0); |
1189 *stack_trace_copy = stack_trace; | 1216 *stack_trace_copy = stack_trace; |
1190 stack_trace_.reset(stack_trace_copy); | 1217 stack_trace_.reset(stack_trace_copy); |
1191 } | 1218 } |
1192 | 1219 |
1193 const base::debug::StackTrace* URLRequest::stack_trace() const { | 1220 const base::debug::StackTrace* URLRequest::stack_trace() const { |
1194 return stack_trace_.get(); | 1221 return stack_trace_.get(); |
1195 } | 1222 } |
1196 | 1223 |
1197 } // namespace net | 1224 } // namespace net |
OLD | NEW |