Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(954)

Side by Side Diff: net/http/http_network_transaction.cc

Issue 1110012: Revert r42300: "HttpRequestHeaders refactor." (Closed)
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include "base/format_macros.h"
8 #include "base/scoped_ptr.h"
7 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
8 #include "base/field_trial.h" 10 #include "base/field_trial.h"
9 #include "base/format_macros.h"
10 #include "base/histogram.h" 11 #include "base/histogram.h"
11 #include "base/scoped_ptr.h"
12 #include "base/stats_counters.h" 12 #include "base/stats_counters.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/trace_event.h" 14 #include "base/trace_event.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "net/base/connection_type_histograms.h" 16 #include "net/base/connection_type_histograms.h"
17 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
18 #include "net/base/load_flags.h" 18 #include "net/base/load_flags.h"
19 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
20 #include "net/base/net_util.h" 20 #include "net/base/net_util.h"
21 #include "net/base/ssl_cert_request_info.h" 21 #include "net/base/ssl_cert_request_info.h"
22 #include "net/base/upload_data_stream.h" 22 #include "net/base/upload_data_stream.h"
23 #include "net/http/http_auth.h" 23 #include "net/http/http_auth.h"
24 #include "net/http/http_auth_handler.h" 24 #include "net/http/http_auth_handler.h"
25 #include "net/http/http_basic_stream.h" 25 #include "net/http/http_basic_stream.h"
26 #include "net/http/http_chunked_decoder.h" 26 #include "net/http/http_chunked_decoder.h"
27 #include "net/http/http_network_session.h" 27 #include "net/http/http_network_session.h"
28 #include "net/http/http_request_headers.h"
29 #include "net/http/http_request_info.h" 28 #include "net/http/http_request_info.h"
30 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
31 #include "net/http/http_response_info.h" 30 #include "net/http/http_response_info.h"
32 #include "net/http/http_util.h" 31 #include "net/http/http_util.h"
33 #include "net/socket/client_socket_factory.h" 32 #include "net/socket/client_socket_factory.h"
34 #include "net/socket/socks_client_socket_pool.h" 33 #include "net/socket/socks_client_socket_pool.h"
35 #include "net/socket/ssl_client_socket.h" 34 #include "net/socket/ssl_client_socket.h"
36 #include "net/socket/tcp_client_socket_pool.h" 35 #include "net/socket/tcp_client_socket_pool.h"
37 #include "net/spdy/spdy_session.h" 36 #include "net/spdy/spdy_session.h"
38 #include "net/spdy/spdy_session_pool.h" 37 #include "net/spdy/spdy_session_pool.h"
39 #include "net/spdy/spdy_stream.h" 38 #include "net/spdy/spdy_stream.h"
40 39
41 using base::Time; 40 using base::Time;
42 41
43 namespace net { 42 namespace net {
44 43
45 namespace { 44 namespace {
46 45
47 const std::string* g_next_protos = NULL; 46 const std::string* g_next_protos = NULL;
48 47
49 void BuildRequestHeaders(const HttpRequestInfo* request_info, 48 void BuildRequestHeaders(const HttpRequestInfo* request_info,
50 const HttpRequestHeaders& authorization_headers, 49 const std::string& authorization_headers,
51 const UploadDataStream* upload_data_stream, 50 const UploadDataStream* upload_data_stream,
52 bool using_proxy, 51 bool using_proxy,
53 HttpRequestHeaders* request_headers) { 52 std::string* request_headers) {
54 const std::string path = using_proxy ?
55 HttpUtil::SpecForRequest(request_info->url) :
56 HttpUtil::PathForRequest(request_info->url);
57 request_headers->SetRequestLine(
58 request_info->method, path, "1.1");
59
60 request_headers->SetHeader(HttpRequestHeaders::kHost,
61 GetHostAndOptionalPort(request_info->url));
62
63 // For compat with HTTP/1.0 servers and proxies:
64 if (using_proxy) {
65 request_headers->SetHeader(HttpRequestHeaders::kProxyConnection,
66 "keep-alive");
67 } else {
68 request_headers->SetHeader(HttpRequestHeaders::kConnection, "keep-alive");
69 }
70
71 if (!request_info->user_agent.empty()) {
72 request_headers->SetHeader(HttpRequestHeaders::kUserAgent,
73 request_info->user_agent);
74 }
75
76 // Our consumer should have made sure that this is a safe referrer. See for
77 // instance WebCore::FrameLoader::HideReferrer.
78 if (request_info->referrer.is_valid()) {
79 request_headers->SetHeader(HttpRequestHeaders::kReferer,
80 request_info->referrer.spec());
81 }
82
83 // Add a content length header?
84 if (upload_data_stream) {
85 request_headers->SetHeader(
86 HttpRequestHeaders::kContentLength,
87 Uint64ToString(upload_data_stream->size()));
88 } else if (request_info->method == "POST" || request_info->method == "PUT" ||
89 request_info->method == "HEAD") {
90 // An empty POST/PUT request still needs a content length. As for HEAD,
91 // IE and Safari also add a content length header. Presumably it is to
92 // support sending a HEAD request to an URL that only expects to be sent a
93 // POST or some other method that normally would have a message body.
94 request_headers->SetHeader(HttpRequestHeaders::kContentLength, "0");
95 }
96
97 // Honor load flags that impact proxy caches.
98 if (request_info->load_flags & LOAD_BYPASS_CACHE) {
99 request_headers->SetHeader(HttpRequestHeaders::kPragma, "no-cache");
100 request_headers->SetHeader(HttpRequestHeaders::kCacheControl, "no-cache");
101 } else if (request_info->load_flags & LOAD_VALIDATE_CACHE) {
102 request_headers->SetHeader(HttpRequestHeaders::kCacheControl, "max-age=0");
103 }
104
105 request_headers->MergeFrom(authorization_headers);
106
107 // Headers that will be stripped from request_info->extra_headers to prevent, 53 // Headers that will be stripped from request_info->extra_headers to prevent,
108 // e.g., plugins from overriding headers that are controlled using other 54 // e.g., plugins from overriding headers that are controlled using other
109 // means. Otherwise a plugin could set a referrer although sending the 55 // means. Otherwise a plugin could set a referrer although sending the
110 // referrer is inhibited. 56 // referrer is inhibited.
111 // TODO(jochen): check whether also other headers should be stripped. 57 // TODO(jochen): check whether also other headers should be stripped.
112 static const char* const kExtraHeadersToBeStripped[] = { 58 static const char* const kExtraHeadersToBeStripped[] = {
113 "Referer" 59 "Referer"
114 }; 60 };
115 61
116 // TODO(willchan): Change HttpRequestInfo::extra_headers to be a 62 const std::string path = using_proxy ?
117 // HttpRequestHeaders. 63 HttpUtil::SpecForRequest(request_info->url) :
64 HttpUtil::PathForRequest(request_info->url);
65 *request_headers =
66 StringPrintf("%s %s HTTP/1.1\r\nHost: %s\r\n",
67 request_info->method.c_str(), path.c_str(),
68 GetHostAndOptionalPort(request_info->url).c_str());
118 69
119 std::vector<std::string> extra_headers_vector; 70 // For compat with HTTP/1.0 servers and proxies:
120 Tokenize(request_info->extra_headers, "\r\n", &extra_headers_vector); 71 if (using_proxy)
121 HttpRequestHeaders extra_headers; 72 *request_headers += "Proxy-";
122 if (!extra_headers_vector.empty()) { 73 *request_headers += "Connection: keep-alive\r\n";
123 for (std::vector<std::string>::const_iterator it =
124 extra_headers_vector.begin(); it != extra_headers_vector.end(); ++it)
125 extra_headers.AddHeaderFromString(*it);
126 74
127 for (size_t i = 0; i < arraysize(kExtraHeadersToBeStripped); ++i) 75 if (!request_info->user_agent.empty()) {
128 extra_headers.RemoveHeader(kExtraHeadersToBeStripped[i]); 76 StringAppendF(request_headers, "User-Agent: %s\r\n",
77 request_info->user_agent.c_str());
78 }
129 79
130 request_headers->MergeFrom(extra_headers); 80 // Our consumer should have made sure that this is a safe referrer. See for
81 // instance WebCore::FrameLoader::HideReferrer.
82 if (request_info->referrer.is_valid())
83 StringAppendF(request_headers, "Referer: %s\r\n",
84 request_info->referrer.spec().c_str());
85
86 // Add a content length header?
87 if (upload_data_stream) {
88 StringAppendF(request_headers, "Content-Length: %" PRIu64 "\r\n",
89 upload_data_stream->size());
90 } else if (request_info->method == "POST" || request_info->method == "PUT" ||
91 request_info->method == "HEAD") {
92 // An empty POST/PUT request still needs a content length. As for HEAD,
93 // IE and Safari also add a content length header. Presumably it is to
94 // support sending a HEAD request to an URL that only expects to be sent a
95 // POST or some other method that normally would have a message body.
96 *request_headers += "Content-Length: 0\r\n";
131 } 97 }
98
99 // Honor load flags that impact proxy caches.
100 if (request_info->load_flags & LOAD_BYPASS_CACHE) {
101 *request_headers += "Pragma: no-cache\r\nCache-Control: no-cache\r\n";
102 } else if (request_info->load_flags & LOAD_VALIDATE_CACHE) {
103 *request_headers += "Cache-Control: max-age=0\r\n";
104 }
105
106 if (!authorization_headers.empty()) {
107 *request_headers += authorization_headers;
108 }
109
110 // TODO(darin): Need to prune out duplicate headers.
111
112 *request_headers += HttpUtil::StripHeaders(request_info->extra_headers,
113 kExtraHeadersToBeStripped, arraysize(kExtraHeadersToBeStripped));
114 *request_headers += "\r\n";
132 } 115 }
133 116
134 // The HTTP CONNECT method for establishing a tunnel connection is documented 117 // The HTTP CONNECT method for establishing a tunnel connection is documented
135 // in draft-luotonen-web-proxy-tunneling-01.txt and RFC 2817, Sections 5.2 and 118 // in draft-luotonen-web-proxy-tunneling-01.txt and RFC 2817, Sections 5.2 and
136 // 5.3. 119 // 5.3.
137 void BuildTunnelRequest(const HttpRequestInfo* request_info, 120 void BuildTunnelRequest(const HttpRequestInfo* request_info,
138 const HttpRequestHeaders& authorization_headers, 121 const std::string& authorization_headers,
139 HttpRequestHeaders* request_headers) { 122 std::string* request_headers) {
140 // RFC 2616 Section 9 says the Host request-header field MUST accompany all 123 // RFC 2616 Section 9 says the Host request-header field MUST accompany all
141 // HTTP/1.1 requests. Add "Proxy-Connection: keep-alive" for compat with 124 // HTTP/1.1 requests. Add "Proxy-Connection: keep-alive" for compat with
142 // HTTP/1.0 proxies such as Squid (required for NTLM authentication). 125 // HTTP/1.0 proxies such as Squid (required for NTLM authentication).
143 request_headers->SetRequestLine( 126 *request_headers = StringPrintf(
144 "CONNECT", GetHostAndPort(request_info->url), "1.1"); 127 "CONNECT %s HTTP/1.1\r\nHost: %s\r\nProxy-Connection: keep-alive\r\n",
145 request_headers->SetHeader(HttpRequestHeaders::kHost, 128 GetHostAndPort(request_info->url).c_str(),
146 GetHostAndOptionalPort(request_info->url)); 129 GetHostAndOptionalPort(request_info->url).c_str());
147 request_headers->SetHeader(HttpRequestHeaders::kProxyConnection,
148 "keep-alive");
149 130
150 if (!request_info->user_agent.empty()) { 131 if (!request_info->user_agent.empty())
151 request_headers->SetHeader(HttpRequestHeaders::kUserAgent, 132 StringAppendF(request_headers, "User-Agent: %s\r\n",
152 request_info->user_agent); 133 request_info->user_agent.c_str());
134
135 if (!authorization_headers.empty()) {
136 *request_headers += authorization_headers;
153 } 137 }
154 138
155 request_headers->MergeFrom(authorization_headers); 139 *request_headers += "\r\n";
156 } 140 }
157 141
158 void ProcessAlternateProtocol(const HttpResponseHeaders& headers, 142 void ProcessAlternateProtocol(const HttpResponseHeaders& headers,
159 const HostPortPair& http_host_port_pair, 143 const HostPortPair& http_host_port_pair,
160 HttpAlternateProtocols* alternate_protocols) { 144 HttpAlternateProtocols* alternate_protocols) {
161 if (!g_next_protos || g_next_protos->empty()) { 145 if (!g_next_protos || g_next_protos->empty()) {
162 // This implies that NPN is not suppoted. We don't currently support any 146 // This implies that NPN is not suppoted. We don't currently support any
163 // alternate protocols that don't use NPN. 147 // alternate protocols that don't use NPN.
164 return; 148 return;
165 } 149 }
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 // headers. 897 // headers.
914 bool have_proxy_auth = 898 bool have_proxy_auth =
915 ShouldApplyProxyAuth() && 899 ShouldApplyProxyAuth() &&
916 (HaveAuth(HttpAuth::AUTH_PROXY) || 900 (HaveAuth(HttpAuth::AUTH_PROXY) ||
917 SelectPreemptiveAuth(HttpAuth::AUTH_PROXY)); 901 SelectPreemptiveAuth(HttpAuth::AUTH_PROXY));
918 bool have_server_auth = 902 bool have_server_auth =
919 ShouldApplyServerAuth() && 903 ShouldApplyServerAuth() &&
920 (HaveAuth(HttpAuth::AUTH_SERVER) || 904 (HaveAuth(HttpAuth::AUTH_SERVER) ||
921 SelectPreemptiveAuth(HttpAuth::AUTH_SERVER)); 905 SelectPreemptiveAuth(HttpAuth::AUTH_SERVER));
922 906
923 HttpRequestHeaders request_headers; 907 std::string authorization_headers;
924 HttpRequestHeaders authorization_headers;
925 908
926 // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization 909 // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization
927 // header with no credentials), we should return an error to prevent 910 // header with no credentials), we should return an error to prevent
928 // entering an infinite auth restart loop. See http://crbug.com/21050. 911 // entering an infinite auth restart loop. See http://crbug.com/21050.
929 if (have_proxy_auth) 912 if (have_proxy_auth)
930 AddAuthorizationHeader(HttpAuth::AUTH_PROXY, &authorization_headers); 913 authorization_headers.append(
914 BuildAuthorizationHeader(HttpAuth::AUTH_PROXY));
931 if (have_server_auth) 915 if (have_server_auth)
932 AddAuthorizationHeader(HttpAuth::AUTH_SERVER, &authorization_headers); 916 authorization_headers.append(
917 BuildAuthorizationHeader(HttpAuth::AUTH_SERVER));
933 918
934 if (establishing_tunnel_) { 919 if (establishing_tunnel_) {
935 BuildTunnelRequest(request_, authorization_headers, &request_headers); 920 BuildTunnelRequest(request_, authorization_headers, &request_headers_);
936 } else { 921 } else {
937 BuildRequestHeaders(request_, authorization_headers, request_body, 922 BuildRequestHeaders(request_, authorization_headers, request_body,
938 proxy_mode_ == kHTTPProxy, &request_headers); 923 proxy_mode_ == kHTTPProxy, &request_headers_);
939 } 924 }
940
941 request_headers_ = request_headers.ToString();
942 } 925 }
943 926
944 headers_valid_ = false; 927 headers_valid_ = false;
945 http_stream_.reset(new HttpBasicStream(connection_.get(), net_log_)); 928 http_stream_.reset(new HttpBasicStream(connection_.get(), net_log_));
946 929
947 return http_stream_->SendRequest(request_, request_headers_, 930 return http_stream_->SendRequest(request_, request_headers_,
948 request_body, &response_, &io_callback_); 931 request_body, &response_, &io_callback_);
949 } 932 }
950 933
951 int HttpNetworkTransaction::DoSendRequestComplete(int result) { 934 int HttpNetworkTransaction::DoSendRequestComplete(int result) {
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 1588
1606 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { 1589 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const {
1607 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_; 1590 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_;
1608 } 1591 }
1609 1592
1610 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { 1593 bool HttpNetworkTransaction::ShouldApplyServerAuth() const {
1611 return !establishing_tunnel_ && 1594 return !establishing_tunnel_ &&
1612 !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); 1595 !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA);
1613 } 1596 }
1614 1597
1615 void HttpNetworkTransaction::AddAuthorizationHeader( 1598 std::string HttpNetworkTransaction::BuildAuthorizationHeader(
1616 HttpAuth::Target target, HttpRequestHeaders* authorization_headers) const { 1599 HttpAuth::Target target) const {
1617 DCHECK(HaveAuth(target)); 1600 DCHECK(HaveAuth(target));
1618 1601
1619 // Add a Authorization/Proxy-Authorization header line. 1602 // Add a Authorization/Proxy-Authorization header line.
1620 std::string auth_token; 1603 std::string auth_token;
1621 int rv = auth_handler_[target]->GenerateAuthToken( 1604 int rv = auth_handler_[target]->GenerateAuthToken(
1622 auth_identity_[target].username, 1605 auth_identity_[target].username,
1623 auth_identity_[target].password, 1606 auth_identity_[target].password,
1624 request_, 1607 request_,
1625 &proxy_info_, 1608 &proxy_info_,
1626 &auth_token); 1609 &auth_token);
1627 if (rv == OK) { 1610 if (rv == OK)
1628 authorization_headers->SetHeader( 1611 return HttpAuth::GetAuthorizationHeaderName(target) +
1629 HttpAuth::GetAuthorizationHeaderName(target), auth_token); 1612 ": " + auth_token + "\r\n";
1630 }
1631 1613
1632 // TODO(cbentzel): Evict username and password from cache on non-OK return? 1614 // TODO(cbentzel): Evict username and password from cache on non-OK return?
1633 // TODO(cbentzel): Never use this scheme again if 1615 // TODO(cbentzel): Never use this scheme again if
1634 // ERR_UNSUPPORTED_AUTH_SCHEME is returned. 1616 // ERR_UNSUPPORTED_AUTH_SCHEME is returned.
1617 return std::string();
1635 } 1618 }
1636 1619
1637 GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const { 1620 GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const {
1638 return target == HttpAuth::AUTH_PROXY ? 1621 return target == HttpAuth::AUTH_PROXY ?
1639 GURL("http://" + proxy_info_.proxy_server().host_and_port()) : 1622 GURL("http://" + proxy_info_.proxy_server().host_and_port()) :
1640 request_->url.GetOrigin(); 1623 request_->url.GetOrigin();
1641 } 1624 }
1642 1625
1643 std::string HttpNetworkTransaction::AuthPath(HttpAuth::Target target) 1626 std::string HttpNetworkTransaction::AuthPath(HttpAuth::Target target)
1644 const { 1627 const {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1890 http_host_port_pair); 1873 http_host_port_pair);
1891 1874
1892 alternate_protocol_mode_ = kDoNotUseAlternateProtocol; 1875 alternate_protocol_mode_ = kDoNotUseAlternateProtocol;
1893 if (connection_->socket()) 1876 if (connection_->socket())
1894 connection_->socket()->Disconnect(); 1877 connection_->socket()->Disconnect();
1895 connection_->Reset(); 1878 connection_->Reset();
1896 next_state_ = STATE_INIT_CONNECTION; 1879 next_state_ = STATE_INIT_CONNECTION;
1897 } 1880 }
1898 1881
1899 } // namespace net 1882 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698