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/http/proxy_client_socket.h" | 5 #include "net/http/proxy_client_socket.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "net/base/host_port_pair.h" | 9 #include "net/base/host_port_pair.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 #include "net/base/net_util.h" | 11 #include "net/base/net_util.h" |
12 #include "net/http/http_auth_controller.h" | 12 #include "net/http/http_auth_controller.h" |
13 #include "net/http/http_request_info.h" | 13 #include "net/http/http_request_info.h" |
14 #include "net/http/http_response_headers.h" | 14 #include "net/http/http_response_headers.h" |
15 #include "net/http/http_response_info.h" | 15 #include "net/http/http_response_info.h" |
16 #include "url/gurl.h" | 16 #include "url/gurl.h" |
17 | 17 |
18 namespace net { | 18 namespace net { |
19 | 19 |
| 20 namespace { |
| 21 |
| 22 void CopyHeaderValues(scoped_refptr<HttpResponseHeaders> source, |
| 23 scoped_refptr<HttpResponseHeaders> dest, |
| 24 const std::string& header_name) { |
| 25 void* iter = NULL; |
| 26 std::string header_value; |
| 27 |
| 28 while (source->EnumerateHeader(&iter, header_name, &header_value)) |
| 29 dest->AddHeader(header_name + ": " + header_value); |
| 30 } |
| 31 |
| 32 } // namespace |
| 33 |
20 // static | 34 // static |
21 void ProxyClientSocket::BuildTunnelRequest( | 35 void ProxyClientSocket::BuildTunnelRequest( |
22 const HttpRequestInfo& request_info, | 36 const HttpRequestInfo& request_info, |
23 const HttpRequestHeaders& auth_headers, | 37 const HttpRequestHeaders& auth_headers, |
24 const HostPortPair& endpoint, | 38 const HostPortPair& endpoint, |
25 std::string* request_line, | 39 std::string* request_line, |
26 HttpRequestHeaders* request_headers) { | 40 HttpRequestHeaders* request_headers) { |
27 // RFC 2616 Section 9 says the Host request-header field MUST accompany all | 41 // RFC 2616 Section 9 says the Host request-header field MUST accompany all |
28 // HTTP/1.1 requests. Add "Proxy-Connection: keep-alive" for compat with | 42 // HTTP/1.1 requests. Add "Proxy-Connection: keep-alive" for compat with |
29 // HTTP/1.0 proxies such as Squid (required for NTLM authentication). | 43 // HTTP/1.0 proxies such as Squid (required for NTLM authentication). |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 HttpUtil::GetStatusCodesForHistogram()); | 79 HttpUtil::GetStatusCodesForHistogram()); |
66 } else { | 80 } else { |
67 UMA_HISTOGRAM_CUSTOM_ENUMERATION( | 81 UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
68 "Net.BlockedTunnelResponse.HttpProxy", | 82 "Net.BlockedTunnelResponse.HttpProxy", |
69 HttpUtil::MapStatusCodeForHistogram(http_status_code), | 83 HttpUtil::MapStatusCodeForHistogram(http_status_code), |
70 HttpUtil::GetStatusCodesForHistogram()); | 84 HttpUtil::GetStatusCodesForHistogram()); |
71 } | 85 } |
72 } | 86 } |
73 | 87 |
74 // static | 88 // static |
75 bool ProxyClientSocket::SanitizeProxyRedirect(HttpResponseInfo* response, | 89 bool ProxyClientSocket::SanitizeProxyAuth(HttpResponseInfo* response) { |
76 const GURL& url) { | 90 DCHECK(response && response->headers.get()); |
| 91 |
| 92 scoped_refptr<HttpResponseHeaders> old_headers = response->headers; |
| 93 |
| 94 const char kHeaders[] = "HTTP/1.1 407 Proxy Authentication Required\n\n"; |
| 95 scoped_refptr<HttpResponseHeaders> new_headers = new HttpResponseHeaders( |
| 96 HttpUtil::AssembleRawHeaders(kHeaders, arraysize(kHeaders))); |
| 97 |
| 98 new_headers->ReplaceStatusLine(old_headers->GetStatusLine()); |
| 99 CopyHeaderValues(old_headers, new_headers, "Connection"); |
| 100 CopyHeaderValues(old_headers, new_headers, "Proxy-Authenticate"); |
| 101 |
| 102 response->headers = new_headers; |
| 103 return true; |
| 104 } |
| 105 |
| 106 // static |
| 107 bool ProxyClientSocket::SanitizeProxyRedirect(HttpResponseInfo* response) { |
77 DCHECK(response && response->headers.get()); | 108 DCHECK(response && response->headers.get()); |
78 | 109 |
79 std::string location; | 110 std::string location; |
80 if (!response->headers->IsRedirect(&location)) | 111 if (!response->headers->IsRedirect(&location)) |
81 return false; | 112 return false; |
82 | 113 |
83 // Return minimal headers; set "Content-length: 0" to ignore response body. | 114 // Return minimal headers; set "Content-Length: 0" to ignore response body. |
84 std::string fake_response_headers = | 115 std::string fake_response_headers = base::StringPrintf( |
85 base::StringPrintf("HTTP/1.0 302 Found\n" | 116 "HTTP/1.0 302 Found\n" |
86 "Location: %s\n" | 117 "Location: %s\n" |
87 "Content-length: 0\n" | 118 "Content-Length: 0\n" |
88 "Connection: close\n" | 119 "Connection: close\n" |
89 "\n", | 120 "\n", |
90 location.c_str()); | 121 location.c_str()); |
91 std::string raw_headers = | 122 std::string raw_headers = |
92 HttpUtil::AssembleRawHeaders(fake_response_headers.data(), | 123 HttpUtil::AssembleRawHeaders(fake_response_headers.data(), |
93 fake_response_headers.length()); | 124 fake_response_headers.length()); |
94 response->headers = new HttpResponseHeaders(raw_headers); | 125 response->headers = new HttpResponseHeaders(raw_headers); |
95 | 126 |
96 return true; | 127 return true; |
97 } | 128 } |
98 | 129 |
99 } // namespace net | 130 } // namespace net |
OLD | NEW |