OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/scoped_ptr.h" | 7 #include "base/scoped_ptr.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/field_trial.h" | 9 #include "base/field_trial.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 #include "net/http/http_chunked_decoder.h" | 24 #include "net/http/http_chunked_decoder.h" |
25 #include "net/http/http_network_session.h" | 25 #include "net/http/http_network_session.h" |
26 #include "net/http/http_request_info.h" | 26 #include "net/http/http_request_info.h" |
27 #include "net/http/http_response_headers.h" | 27 #include "net/http/http_response_headers.h" |
28 #include "net/http/http_util.h" | 28 #include "net/http/http_util.h" |
29 | 29 |
30 using base::Time; | 30 using base::Time; |
31 | 31 |
32 namespace net { | 32 namespace net { |
33 | 33 |
34 namespace { | |
35 | |
36 void BuildRequestHeaders(const HttpRequestInfo* request_info, | |
37 const std::string& authorization_headers, | |
38 const UploadDataStream* upload_data_stream, | |
39 bool using_proxy, | |
40 std::string* request_headers) { | |
41 const std::string path = using_proxy ? | |
42 HttpUtil::SpecForRequest(request_info->url) : | |
43 HttpUtil::PathForRequest(request_info->url); | |
44 *request_headers = | |
45 StringPrintf("%s %s HTTP/1.1\r\nHost: %s", | |
46 request_info->method.c_str(), path.c_str(), | |
47 request_info->url.host().c_str()); | |
48 if (request_info->url.IntPort() != -1) | |
49 *request_headers += ":" + request_info->url.port(); | |
50 *request_headers += "\r\n"; | |
51 | |
52 // For compat with HTTP/1.0 servers and proxies: | |
53 if (using_proxy) | |
54 *request_headers += "Proxy-"; | |
55 *request_headers += "Connection: keep-alive\r\n"; | |
56 | |
57 if (!request_info->user_agent.empty()) { | |
58 StringAppendF(request_headers, "User-Agent: %s\r\n", | |
59 request_info->user_agent.c_str()); | |
60 } | |
61 | |
62 // Our consumer should have made sure that this is a safe referrer. See for | |
63 // instance WebCore::FrameLoader::HideReferrer. | |
64 if (request_info->referrer.is_valid()) | |
65 StringAppendF(request_headers, "Referer: %s\r\n", | |
66 request_info->referrer.spec().c_str()); | |
67 | |
68 // Add a content length header? | |
69 if (upload_data_stream) { | |
70 StringAppendF(request_headers, "Content-Length: %llu\r\n", | |
wtc
2009/04/30 18:57:20
I just learned that we're supposed to use the PRIu
willchan no longer on Chromium
2009/04/30 19:32:40
That's for uint64_t. We're using uint64 here. ui
| |
71 upload_data_stream->size()); | |
72 } else if (request_info->method == "POST" || request_info->method == "PUT" || | |
73 request_info->method == "HEAD") { | |
74 // An empty POST/PUT request still needs a content length. As for HEAD, | |
75 // IE and Safari also add a content length header. Presumably it is to | |
76 // support sending a HEAD request to an URL that only expects to be sent a | |
77 // POST or some other method that normally would have a message body. | |
78 *request_headers += "Content-Length: 0\r\n"; | |
79 } | |
80 | |
81 // Honor load flags that impact proxy caches. | |
82 if (request_info->load_flags & LOAD_BYPASS_CACHE) { | |
83 *request_headers += "Pragma: no-cache\r\nCache-Control: no-cache\r\n"; | |
84 } else if (request_info->load_flags & LOAD_VALIDATE_CACHE) { | |
85 *request_headers += "Cache-Control: max-age=0\r\n"; | |
86 } | |
87 | |
88 if (!authorization_headers.empty()) { | |
89 *request_headers += authorization_headers; | |
90 } | |
91 | |
92 // TODO(darin): Need to prune out duplicate headers. | |
93 | |
94 *request_headers += request_info->extra_headers; | |
95 *request_headers += "\r\n"; | |
96 } | |
97 | |
98 // The HTTP CONNECT method for establishing a tunnel connection is documented | |
99 // in draft-luotonen-web-proxy-tunneling-01.txt and RFC 2817, Sections 5.2 and | |
100 // 5.3. | |
101 void BuildTunnelRequest(const HttpRequestInfo* request_info, | |
102 const std::string& authorization_headers, | |
103 std::string* request_headers) { | |
104 // RFC 2616 Section 9 says the Host request-header field MUST accompany all | |
105 // HTTP/1.1 requests. | |
106 *request_headers = StringPrintf("CONNECT %s:%d HTTP/1.1\r\n", | |
107 request_info->url.host().c_str(), request_info->url.EffectiveIntPort()); | |
108 *request_headers += "Host: " + request_info->url.host(); | |
109 if (request_info->url.has_port()) | |
110 *request_headers += ":" + request_info->url.port(); | |
111 *request_headers += "\r\n"; | |
112 | |
113 if (!request_info->user_agent.empty()) | |
114 StringAppendF(request_headers, "User-Agent: %s\r\n", | |
115 request_info->user_agent.c_str()); | |
116 | |
117 if (!authorization_headers.empty()) { | |
118 *request_headers += authorization_headers; | |
119 } | |
120 | |
121 *request_headers += "\r\n"; | |
122 } | |
123 | |
124 } // namespace | |
125 | |
34 //----------------------------------------------------------------------------- | 126 //----------------------------------------------------------------------------- |
35 | 127 |
36 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, | 128 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, |
37 ClientSocketFactory* csf) | 129 ClientSocketFactory* csf) |
38 : pending_auth_target_(HttpAuth::AUTH_NONE), | 130 : pending_auth_target_(HttpAuth::AUTH_NONE), |
39 ALLOW_THIS_IN_INITIALIZER_LIST( | 131 ALLOW_THIS_IN_INITIALIZER_LIST( |
40 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), | 132 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), |
41 user_callback_(NULL), | 133 user_callback_(NULL), |
42 session_(session), | 134 session_(session), |
43 request_(NULL), | 135 request_(NULL), |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 HttpNetworkTransaction::~HttpNetworkTransaction() { | 376 HttpNetworkTransaction::~HttpNetworkTransaction() { |
285 // If we still have an open socket, then make sure to close it so we don't | 377 // If we still have an open socket, then make sure to close it so we don't |
286 // try to reuse it later on. | 378 // try to reuse it later on. |
287 if (connection_.is_initialized()) | 379 if (connection_.is_initialized()) |
288 connection_.set_socket(NULL); | 380 connection_.set_socket(NULL); |
289 | 381 |
290 if (pac_request_) | 382 if (pac_request_) |
291 session_->proxy_service()->CancelPacRequest(pac_request_); | 383 session_->proxy_service()->CancelPacRequest(pac_request_); |
292 } | 384 } |
293 | 385 |
294 void HttpNetworkTransaction::BuildRequestHeaders() { | |
295 // For proxy use the full url. Otherwise just the absolute path. | |
296 // This strips out any reference/username/password. | |
297 std::string path = using_proxy_ ? | |
298 HttpUtil::SpecForRequest(request_->url) : | |
299 HttpUtil::PathForRequest(request_->url); | |
300 | |
301 request_headers_ = request_->method + " " + path + | |
302 " HTTP/1.1\r\nHost: " + request_->url.host(); | |
303 if (request_->url.IntPort() != -1) | |
304 request_headers_ += ":" + request_->url.port(); | |
305 request_headers_ += "\r\n"; | |
306 | |
307 // For compat with HTTP/1.0 servers and proxies: | |
308 if (using_proxy_) | |
309 request_headers_ += "Proxy-"; | |
310 request_headers_ += "Connection: keep-alive\r\n"; | |
311 | |
312 if (!request_->user_agent.empty()) | |
313 request_headers_ += "User-Agent: " + request_->user_agent + "\r\n"; | |
314 | |
315 // Our consumer should have made sure that this is a safe referrer. See for | |
316 // instance WebCore::FrameLoader::HideReferrer. | |
317 if (request_->referrer.is_valid()) | |
318 request_headers_ += "Referer: " + request_->referrer.spec() + "\r\n"; | |
319 | |
320 // Add a content length header? | |
321 if (request_->upload_data) { | |
322 request_body_stream_.reset(new UploadDataStream(request_->upload_data)); | |
323 request_headers_ += | |
324 "Content-Length: " + Uint64ToString(request_body_stream_->size()) + | |
325 "\r\n"; | |
326 } else if (request_->method == "POST" || request_->method == "PUT" || | |
327 request_->method == "HEAD") { | |
328 // An empty POST/PUT request still needs a content length. As for HEAD, | |
329 // IE and Safari also add a content length header. Presumably it is to | |
330 // support sending a HEAD request to an URL that only expects to be sent a | |
331 // POST or some other method that normally would have a message body. | |
332 request_headers_ += "Content-Length: 0\r\n"; | |
333 } | |
334 | |
335 // Honor load flags that impact proxy caches. | |
336 if (request_->load_flags & LOAD_BYPASS_CACHE) { | |
337 request_headers_ += "Pragma: no-cache\r\nCache-Control: no-cache\r\n"; | |
338 } else if (request_->load_flags & LOAD_VALIDATE_CACHE) { | |
339 request_headers_ += "Cache-Control: max-age=0\r\n"; | |
340 } | |
341 | |
342 ApplyAuth(); | |
343 | |
344 // TODO(darin): Need to prune out duplicate headers. | |
345 | |
346 request_headers_ += request_->extra_headers; | |
347 request_headers_ += "\r\n"; | |
348 } | |
349 | |
350 // The HTTP CONNECT method for establishing a tunnel connection is documented | |
351 // in draft-luotonen-web-proxy-tunneling-01.txt and RFC 2817, Sections 5.2 and | |
352 // 5.3. | |
353 void HttpNetworkTransaction::BuildTunnelRequest() { | |
354 // RFC 2616 Section 9 says the Host request-header field MUST accompany all | |
355 // HTTP/1.1 requests. | |
356 request_headers_ = StringPrintf("CONNECT %s:%d HTTP/1.1\r\n", | |
357 request_->url.host().c_str(), request_->url.EffectiveIntPort()); | |
358 request_headers_ += "Host: " + request_->url.host(); | |
359 if (request_->url.has_port()) | |
360 request_headers_ += ":" + request_->url.port(); | |
361 request_headers_ += "\r\n"; | |
362 | |
363 if (!request_->user_agent.empty()) | |
364 request_headers_ += "User-Agent: " + request_->user_agent + "\r\n"; | |
365 | |
366 ApplyAuth(); | |
367 | |
368 request_headers_ += "\r\n"; | |
369 } | |
370 | |
371 void HttpNetworkTransaction::DoCallback(int rv) { | 386 void HttpNetworkTransaction::DoCallback(int rv) { |
372 DCHECK(rv != ERR_IO_PENDING); | 387 DCHECK(rv != ERR_IO_PENDING); |
373 DCHECK(user_callback_); | 388 DCHECK(user_callback_); |
374 | 389 |
375 // Since Run may result in Read being called, clear user_callback_ up front. | 390 // Since Run may result in Read being called, clear user_callback_ up front. |
376 CompletionCallback* c = user_callback_; | 391 CompletionCallback* c = user_callback_; |
377 user_callback_ = NULL; | 392 user_callback_ = NULL; |
378 c->Run(rv); | 393 c->Run(rv); |
379 } | 394 } |
380 | 395 |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
648 } | 663 } |
649 return result; | 664 return result; |
650 } | 665 } |
651 | 666 |
652 int HttpNetworkTransaction::DoWriteHeaders() { | 667 int HttpNetworkTransaction::DoWriteHeaders() { |
653 next_state_ = STATE_WRITE_HEADERS_COMPLETE; | 668 next_state_ = STATE_WRITE_HEADERS_COMPLETE; |
654 | 669 |
655 // This is constructed lazily (instead of within our Start method), so that | 670 // This is constructed lazily (instead of within our Start method), so that |
656 // we have proxy info available. | 671 // we have proxy info available. |
657 if (request_headers_.empty()) { | 672 if (request_headers_.empty()) { |
673 // Figure out if we can/should add Proxy-Authentication & Authentication | |
674 // headers. | |
675 bool have_proxy_auth = | |
676 ShouldApplyProxyAuth() && | |
677 (HaveAuth(HttpAuth::AUTH_PROXY) || | |
678 SelectPreemptiveAuth(HttpAuth::AUTH_PROXY)); | |
679 bool have_server_auth = | |
680 ShouldApplyServerAuth() && | |
681 (HaveAuth(HttpAuth::AUTH_SERVER) || | |
682 SelectPreemptiveAuth(HttpAuth::AUTH_SERVER)); | |
683 | |
684 std::string authorization_headers; | |
685 | |
686 if (have_proxy_auth) | |
687 authorization_headers.append( | |
688 BuildAuthorizationHeader(HttpAuth::AUTH_PROXY)); | |
689 if (have_server_auth) | |
690 authorization_headers.append( | |
691 BuildAuthorizationHeader(HttpAuth::AUTH_SERVER)); | |
692 | |
658 if (establishing_tunnel_) { | 693 if (establishing_tunnel_) { |
659 BuildTunnelRequest(); | 694 BuildTunnelRequest(request_, authorization_headers, &request_headers_); |
660 } else { | 695 } else { |
661 BuildRequestHeaders(); | 696 if (request_->upload_data) |
697 request_body_stream_.reset(new UploadDataStream(request_->upload_data)); | |
698 BuildRequestHeaders(request_, | |
699 authorization_headers, | |
700 request_body_stream_.get(), | |
701 using_proxy_, | |
702 &request_headers_); | |
662 } | 703 } |
663 } | 704 } |
664 | 705 |
665 // Record our best estimate of the 'request time' as the time when we send | 706 // Record our best estimate of the 'request time' as the time when we send |
666 // out the first bytes of the request headers. | 707 // out the first bytes of the request headers. |
667 if (request_headers_bytes_sent_ == 0) { | 708 if (request_headers_bytes_sent_ == 0) { |
668 response_.request_time = Time::Now(); | 709 response_.request_time = Time::Now(); |
669 } | 710 } |
670 | 711 |
671 const char* buf = request_headers_.data() + request_headers_bytes_sent_; | 712 const char* buf = request_headers_.data() + request_headers_bytes_sent_; |
672 int buf_len = static_cast<int>(request_headers_.size() - | 713 int buf_len = static_cast<int>(request_headers_.size() - |
673 request_headers_bytes_sent_); | 714 request_headers_bytes_sent_); |
674 DCHECK(buf_len > 0); | 715 DCHECK_GT(buf_len, 0); |
675 | 716 |
676 return connection_.socket()->Write(buf, buf_len, &io_callback_); | 717 return connection_.socket()->Write(buf, buf_len, &io_callback_); |
677 } | 718 } |
678 | 719 |
679 int HttpNetworkTransaction::DoWriteHeadersComplete(int result) { | 720 int HttpNetworkTransaction::DoWriteHeadersComplete(int result) { |
680 if (result < 0) | 721 if (result < 0) |
681 return HandleIOError(result); | 722 return HandleIOError(result); |
682 | 723 |
683 request_headers_bytes_sent_ += result; | 724 request_headers_bytes_sent_ += result; |
684 if (request_headers_bytes_sent_ < request_headers_.size()) { | 725 if (request_headers_bytes_sent_ < request_headers_.size()) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
758 // Assume everything else is a HTTP/0.9 response (including responses | 799 // Assume everything else is a HTTP/0.9 response (including responses |
759 // of 'h', 'ht', 'htt'). | 800 // of 'h', 'ht', 'htt'). |
760 header_buf_body_offset_ = 0; | 801 header_buf_body_offset_ = 0; |
761 return OK; | 802 return OK; |
762 } | 803 } |
763 | 804 |
764 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { | 805 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { |
765 if (result < 0) | 806 if (result < 0) |
766 return HandleIOError(result); | 807 return HandleIOError(result); |
767 | 808 |
768 if (result == 0 && ShouldResendRequest()) | 809 if (result == 0 && ShouldResendRequest()) { |
810 ResetConnectionAndRequestForResend(); | |
769 return result; | 811 return result; |
812 } | |
770 | 813 |
771 // Record our best estimate of the 'response time' as the time when we read | 814 // Record our best estimate of the 'response time' as the time when we read |
772 // the first bytes of the response headers. | 815 // the first bytes of the response headers. |
773 if (header_buf_len_ == 0) { | 816 if (header_buf_len_ == 0) { |
774 // After we call RestartWithAuth header_buf_len will be zero again, and | 817 // After we call RestartWithAuth header_buf_len will be zero again, and |
775 // we need to be cautious about incorrectly logging the duration across the | 818 // we need to be cautious about incorrectly logging the duration across the |
776 // authentication activitiy. | 819 // authentication activitiy. |
777 bool first_response = response_.response_time == Time(); | 820 bool first_response = response_.response_time == Time(); |
778 response_.response_time = Time::Now(); | 821 response_.response_time = Time::Now(); |
779 if (first_response) | 822 if (first_response) |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1250 // other cases, such as a Connect error. | 1293 // other cases, such as a Connect error. |
1251 int HttpNetworkTransaction::HandleIOError(int error) { | 1294 int HttpNetworkTransaction::HandleIOError(int error) { |
1252 switch (error) { | 1295 switch (error) { |
1253 // If we try to reuse a connection that the server is in the process of | 1296 // If we try to reuse a connection that the server is in the process of |
1254 // closing, we may end up successfully writing out our request (or a | 1297 // closing, we may end up successfully writing out our request (or a |
1255 // portion of our request) only to find a connection error when we try to | 1298 // portion of our request) only to find a connection error when we try to |
1256 // read from (or finish writing to) the socket. | 1299 // read from (or finish writing to) the socket. |
1257 case ERR_CONNECTION_RESET: | 1300 case ERR_CONNECTION_RESET: |
1258 case ERR_CONNECTION_CLOSED: | 1301 case ERR_CONNECTION_CLOSED: |
1259 case ERR_CONNECTION_ABORTED: | 1302 case ERR_CONNECTION_ABORTED: |
1260 if (ShouldResendRequest()) | 1303 if (ShouldResendRequest()) { |
1304 ResetConnectionAndRequestForResend(); | |
1261 error = OK; | 1305 error = OK; |
1306 } | |
1262 break; | 1307 break; |
1263 } | 1308 } |
1264 return error; | 1309 return error; |
1265 } | 1310 } |
1266 | 1311 |
1267 void HttpNetworkTransaction::ResetStateForRestart() { | 1312 void HttpNetworkTransaction::ResetStateForRestart() { |
1268 pending_auth_target_ = HttpAuth::AUTH_NONE; | 1313 pending_auth_target_ = HttpAuth::AUTH_NONE; |
1269 header_buf_.reset(); | 1314 header_buf_.reset(); |
1270 header_buf_capacity_ = 0; | 1315 header_buf_capacity_ = 0; |
1271 header_buf_len_ = 0; | 1316 header_buf_len_ = 0; |
1272 header_buf_body_offset_ = -1; | 1317 header_buf_body_offset_ = -1; |
1273 header_buf_http_offset_ = -1; | 1318 header_buf_http_offset_ = -1; |
1274 response_body_length_ = -1; | 1319 response_body_length_ = -1; |
1275 response_body_read_ = 0; | 1320 response_body_read_ = 0; |
1276 read_buf_ = NULL; | 1321 read_buf_ = NULL; |
1277 read_buf_len_ = 0; | 1322 read_buf_len_ = 0; |
1278 request_headers_.clear(); | 1323 request_headers_.clear(); |
1279 request_headers_bytes_sent_ = 0; | 1324 request_headers_bytes_sent_ = 0; |
1280 chunked_decoder_.reset(); | 1325 chunked_decoder_.reset(); |
1281 // Reset all the members of response_. | 1326 // Reset all the members of response_. |
1282 response_ = HttpResponseInfo(); | 1327 response_ = HttpResponseInfo(); |
1283 } | 1328 } |
1284 | 1329 |
1285 bool HttpNetworkTransaction::ShouldResendRequest() { | 1330 bool HttpNetworkTransaction::ShouldResendRequest() const { |
1286 // NOTE: we resend a request only if we reused a keep-alive connection. | 1331 // NOTE: we resend a request only if we reused a keep-alive connection. |
1287 // This automatically prevents an infinite resend loop because we'll run | 1332 // This automatically prevents an infinite resend loop because we'll run |
1288 // out of the cached keep-alive connections eventually. | 1333 // out of the cached keep-alive connections eventually. |
1289 if (establishing_tunnel_ || | 1334 if (establishing_tunnel_ || |
1290 !reused_socket_ || // We didn't reuse a keep-alive connection. | 1335 !reused_socket_ || // We didn't reuse a keep-alive connection. |
1291 header_buf_len_) { // We have received some response headers. | 1336 header_buf_len_) { // We have received some response headers. |
1292 return false; | 1337 return false; |
1293 } | 1338 } |
1339 return true; | |
1340 } | |
1341 | |
1342 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { | |
1294 connection_.set_socket(NULL); | 1343 connection_.set_socket(NULL); |
1295 connection_.Reset(); | 1344 connection_.Reset(); |
1296 // There are two reasons we need to clear request_headers_. 1) It contains | 1345 // There are two reasons we need to clear request_headers_. 1) It contains |
1297 // the real request headers, but we may need to resend the CONNECT request | 1346 // the real request headers, but we may need to resend the CONNECT request |
1298 // first to recreate the SSL tunnel. 2) An empty request_headers_ causes | 1347 // first to recreate the SSL tunnel. 2) An empty request_headers_ causes |
1299 // BuildRequestHeaders to be called, which rewinds request_body_stream_ to | 1348 // BuildRequestHeaders to be called, which rewinds request_body_stream_ to |
1300 // the beginning of request_->upload_data. | 1349 // the beginning of request_->upload_data. |
1301 request_headers_.clear(); | 1350 request_headers_.clear(); |
1302 request_headers_bytes_sent_ = 0; | 1351 request_headers_bytes_sent_ = 0; |
1303 next_state_ = STATE_INIT_CONNECTION; // Resend the request. | 1352 next_state_ = STATE_INIT_CONNECTION; // Resend the request. |
1304 return true; | |
1305 } | 1353 } |
1306 | 1354 |
1307 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { | 1355 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { |
1308 DCHECK(!pac_request_); | 1356 DCHECK(!pac_request_); |
1309 | 1357 |
1310 // A failure to resolve the hostname or any error related to establishing a | 1358 // A failure to resolve the hostname or any error related to establishing a |
1311 // TCP connection could be grounds for trying a new proxy configuration. | 1359 // TCP connection could be grounds for trying a new proxy configuration. |
1312 // | 1360 // |
1313 // Why do this when a hostname cannot be resolved? Some URLs only make sense | 1361 // Why do this when a hostname cannot be resolved? Some URLs only make sense |
1314 // to proxy servers. The hostname in those URLs might fail to resolve if we | 1362 // to proxy servers. The hostname in those URLs might fail to resolve if we |
(...skipping 26 matching lines...) Expand all Loading... | |
1341 connection_.Reset(); | 1389 connection_.Reset(); |
1342 DCHECK(!request_headers_bytes_sent_); | 1390 DCHECK(!request_headers_bytes_sent_); |
1343 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | 1391 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
1344 } else { | 1392 } else { |
1345 rv = error; | 1393 rv = error; |
1346 } | 1394 } |
1347 | 1395 |
1348 return rv; | 1396 return rv; |
1349 } | 1397 } |
1350 | 1398 |
1351 void HttpNetworkTransaction::AddAuthorizationHeader(HttpAuth::Target target) { | 1399 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { |
1352 // If we have no authentication information, check if we can select | 1400 return using_proxy_ || establishing_tunnel_; |
1353 // a cache entry preemptively (based on the path). | 1401 } |
1354 if (!HaveAuth(target) && !SelectPreemptiveAuth(target)) | |
1355 return; | |
1356 | 1402 |
1403 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { | |
1404 return !establishing_tunnel_; | |
1405 } | |
1406 | |
1407 std::string HttpNetworkTransaction::BuildAuthorizationHeader( | |
1408 HttpAuth::Target target) const { | |
1357 DCHECK(HaveAuth(target)); | 1409 DCHECK(HaveAuth(target)); |
1358 | 1410 |
1359 // Add a Authorization/Proxy-Authorization header line. | 1411 // Add a Authorization/Proxy-Authorization header line. |
1360 std::string credentials = auth_handler_[target]->GenerateCredentials( | 1412 std::string credentials = auth_handler_[target]->GenerateCredentials( |
1361 auth_identity_[target].username, | 1413 auth_identity_[target].username, |
1362 auth_identity_[target].password, | 1414 auth_identity_[target].password, |
1363 request_, | 1415 request_, |
1364 &proxy_info_); | 1416 &proxy_info_); |
1365 request_headers_ += HttpAuth::GetAuthorizationHeaderName(target) + | 1417 |
1418 return HttpAuth::GetAuthorizationHeaderName(target) + | |
1366 ": " + credentials + "\r\n"; | 1419 ": " + credentials + "\r\n"; |
1367 } | 1420 } |
1368 | 1421 |
1369 void HttpNetworkTransaction::ApplyAuth() { | |
1370 // We expect using_proxy_ and using_tunnel_ to be mutually exclusive. | |
1371 DCHECK(!using_proxy_ || !using_tunnel_); | |
1372 | |
1373 // Don't send proxy auth after tunnel has been established. | |
1374 bool should_apply_proxy_auth = using_proxy_ || establishing_tunnel_; | |
1375 | |
1376 // Don't send origin server auth while establishing tunnel. | |
1377 bool should_apply_server_auth = !establishing_tunnel_; | |
1378 | |
1379 if (should_apply_proxy_auth) | |
1380 AddAuthorizationHeader(HttpAuth::AUTH_PROXY); | |
1381 if (should_apply_server_auth) | |
1382 AddAuthorizationHeader(HttpAuth::AUTH_SERVER); | |
1383 } | |
1384 | |
1385 GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const { | 1422 GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const { |
1386 return target == HttpAuth::AUTH_PROXY ? | 1423 return target == HttpAuth::AUTH_PROXY ? |
1387 GURL("http://" + proxy_info_.proxy_server().host_and_port()) : | 1424 GURL("http://" + proxy_info_.proxy_server().host_and_port()) : |
1388 request_->url.GetOrigin(); | 1425 request_->url.GetOrigin(); |
1389 } | 1426 } |
1390 | 1427 |
1391 std::string HttpNetworkTransaction::AuthPath(HttpAuth::Target target) | 1428 std::string HttpNetworkTransaction::AuthPath(HttpAuth::Target target) |
1392 const { | 1429 const { |
1393 // Proxy authentication realms apply to all paths. So we will use | 1430 // Proxy authentication realms apply to all paths. So we will use |
1394 // empty string in place of an absolute path. | 1431 // empty string in place of an absolute path. |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1621 if (target == HttpAuth::AUTH_PROXY) { | 1658 if (target == HttpAuth::AUTH_PROXY) { |
1622 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); | 1659 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); |
1623 } else { | 1660 } else { |
1624 DCHECK(target == HttpAuth::AUTH_SERVER); | 1661 DCHECK(target == HttpAuth::AUTH_SERVER); |
1625 auth_info->host = ASCIIToWide(request_->url.host()); | 1662 auth_info->host = ASCIIToWide(request_->url.host()); |
1626 } | 1663 } |
1627 response_.auth_challenge = auth_info; | 1664 response_.auth_challenge = auth_info; |
1628 } | 1665 } |
1629 | 1666 |
1630 } // namespace net | 1667 } // namespace net |
OLD | NEW |