Chromium Code Reviews| 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 |