1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/http/proxy_client_socket.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <unordered_set>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_macros.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/http/http_auth_controller.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_info.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_headers.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_info.h"
18*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
19*6777b538SAndroid Build Coastguard Worker
20*6777b538SAndroid Build Coastguard Worker namespace net {
21*6777b538SAndroid Build Coastguard Worker
SetStreamPriority(RequestPriority priority)22*6777b538SAndroid Build Coastguard Worker void ProxyClientSocket::SetStreamPriority(RequestPriority priority) {}
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Worker // static
BuildTunnelRequest(const HostPortPair & endpoint,const HttpRequestHeaders & extra_headers,const std::string & user_agent,std::string * request_line,HttpRequestHeaders * request_headers)25*6777b538SAndroid Build Coastguard Worker void ProxyClientSocket::BuildTunnelRequest(
26*6777b538SAndroid Build Coastguard Worker const HostPortPair& endpoint,
27*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& extra_headers,
28*6777b538SAndroid Build Coastguard Worker const std::string& user_agent,
29*6777b538SAndroid Build Coastguard Worker std::string* request_line,
30*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders* request_headers) {
31*6777b538SAndroid Build Coastguard Worker // RFC 7230 Section 5.4 says a client MUST send a Host header field in all
32*6777b538SAndroid Build Coastguard Worker // HTTP/1.1 request messages, and Host SHOULD be the first header field
33*6777b538SAndroid Build Coastguard Worker // following the request-line. Add "Proxy-Connection: keep-alive" for compat
34*6777b538SAndroid Build Coastguard Worker // with HTTP/1.0 proxies such as Squid (required for NTLM authentication).
35*6777b538SAndroid Build Coastguard Worker std::string host_and_port = endpoint.ToString();
36*6777b538SAndroid Build Coastguard Worker *request_line =
37*6777b538SAndroid Build Coastguard Worker base::StringPrintf("CONNECT %s HTTP/1.1\r\n", host_and_port.c_str());
38*6777b538SAndroid Build Coastguard Worker request_headers->SetHeader(HttpRequestHeaders::kHost, host_and_port);
39*6777b538SAndroid Build Coastguard Worker request_headers->SetHeader(HttpRequestHeaders::kProxyConnection,
40*6777b538SAndroid Build Coastguard Worker "keep-alive");
41*6777b538SAndroid Build Coastguard Worker if (!user_agent.empty())
42*6777b538SAndroid Build Coastguard Worker request_headers->SetHeader(HttpRequestHeaders::kUserAgent, user_agent);
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker request_headers->MergeFrom(extra_headers);
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Worker // static
HandleProxyAuthChallenge(HttpAuthController * auth,HttpResponseInfo * response,const NetLogWithSource & net_log)48*6777b538SAndroid Build Coastguard Worker int ProxyClientSocket::HandleProxyAuthChallenge(
49*6777b538SAndroid Build Coastguard Worker HttpAuthController* auth,
50*6777b538SAndroid Build Coastguard Worker HttpResponseInfo* response,
51*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& net_log) {
52*6777b538SAndroid Build Coastguard Worker DCHECK(response->headers.get());
53*6777b538SAndroid Build Coastguard Worker int rv = auth->HandleAuthChallenge(response->headers, response->ssl_info,
54*6777b538SAndroid Build Coastguard Worker false, true, net_log);
55*6777b538SAndroid Build Coastguard Worker auth->TakeAuthInfo(&response->auth_challenge);
56*6777b538SAndroid Build Coastguard Worker if (rv == OK)
57*6777b538SAndroid Build Coastguard Worker return ERR_PROXY_AUTH_REQUESTED;
58*6777b538SAndroid Build Coastguard Worker return rv;
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Worker // static
SanitizeProxyAuth(HttpResponseInfo & response)62*6777b538SAndroid Build Coastguard Worker void ProxyClientSocket::SanitizeProxyAuth(HttpResponseInfo& response) {
63*6777b538SAndroid Build Coastguard Worker DCHECK(response.headers);
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker // Copy status line and all hop-by-hop headers to preserve keep-alive
66*6777b538SAndroid Build Coastguard Worker // behavior.
67*6777b538SAndroid Build Coastguard Worker const char* kHeadersToKeep[] = {
68*6777b538SAndroid Build Coastguard Worker "connection", "proxy-connection", "keep-alive", "trailer",
69*6777b538SAndroid Build Coastguard Worker "transfer-encoding", "upgrade",
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker "content-length",
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker "proxy-authenticate",
74*6777b538SAndroid Build Coastguard Worker };
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker // Create a list of all present header not in |kHeadersToKeep|, and then
77*6777b538SAndroid Build Coastguard Worker // remove them.
78*6777b538SAndroid Build Coastguard Worker size_t iter = 0;
79*6777b538SAndroid Build Coastguard Worker std::string header_name;
80*6777b538SAndroid Build Coastguard Worker std::string header_value;
81*6777b538SAndroid Build Coastguard Worker std::unordered_set<std::string> headers_to_remove;
82*6777b538SAndroid Build Coastguard Worker while (response.headers->EnumerateHeaderLines(&iter, &header_name,
83*6777b538SAndroid Build Coastguard Worker &header_value)) {
84*6777b538SAndroid Build Coastguard Worker bool remove = true;
85*6777b538SAndroid Build Coastguard Worker for (const char* header : kHeadersToKeep) {
86*6777b538SAndroid Build Coastguard Worker if (base::EqualsCaseInsensitiveASCII(header, header_name)) {
87*6777b538SAndroid Build Coastguard Worker remove = false;
88*6777b538SAndroid Build Coastguard Worker break;
89*6777b538SAndroid Build Coastguard Worker }
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker if (remove)
92*6777b538SAndroid Build Coastguard Worker headers_to_remove.insert(header_name);
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker
95*6777b538SAndroid Build Coastguard Worker response.headers->RemoveHeaders(headers_to_remove);
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker
98*6777b538SAndroid Build Coastguard Worker } // namespace net
99