| 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 void HttpNetworkTransaction::ResponseHeaders::Realloc(size_t new_size) { |
| 35 headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size))); |
| 36 } |
| 37 |
| 34 //----------------------------------------------------------------------------- | 38 //----------------------------------------------------------------------------- |
| 35 | 39 |
| 36 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, | 40 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, |
| 37 ClientSocketFactory* csf) | 41 ClientSocketFactory* csf) |
| 38 : pending_auth_target_(HttpAuth::AUTH_NONE), | 42 : pending_auth_target_(HttpAuth::AUTH_NONE), |
| 39 ALLOW_THIS_IN_INITIALIZER_LIST( | 43 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 40 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), | 44 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), |
| 41 user_callback_(NULL), | 45 user_callback_(NULL), |
| 42 session_(session), | 46 session_(session), |
| 43 request_(NULL), | 47 request_(NULL), |
| 44 pac_request_(NULL), | 48 pac_request_(NULL), |
| 45 socket_factory_(csf), | 49 socket_factory_(csf), |
| 46 connection_(session->connection_pool()), | 50 connection_(session->connection_pool()), |
| 47 reused_socket_(false), | 51 reused_socket_(false), |
| 48 using_ssl_(false), | 52 using_ssl_(false), |
| 49 using_proxy_(false), | 53 using_proxy_(false), |
| 50 using_tunnel_(false), | 54 using_tunnel_(false), |
| 51 establishing_tunnel_(false), | 55 establishing_tunnel_(false), |
| 52 reading_body_from_socket_(false), | 56 reading_body_from_socket_(false), |
| 57 request_headers_(new RequestHeaders()), |
| 53 request_headers_bytes_sent_(0), | 58 request_headers_bytes_sent_(0), |
| 59 header_buf_(new ResponseHeaders()), |
| 54 header_buf_capacity_(0), | 60 header_buf_capacity_(0), |
| 55 header_buf_len_(0), | 61 header_buf_len_(0), |
| 56 header_buf_body_offset_(-1), | 62 header_buf_body_offset_(-1), |
| 57 header_buf_http_offset_(-1), | 63 header_buf_http_offset_(-1), |
| 58 response_body_length_(-1), // -1 means unspecified. | 64 response_body_length_(-1), // -1 means unspecified. |
| 59 response_body_read_(0), | 65 response_body_read_(0), |
| 60 read_buf_len_(0), | 66 read_buf_len_(0), |
| 61 next_state_(STATE_NONE) { | 67 next_state_(STATE_NONE) { |
| 62 #if defined(OS_WIN) | 68 #if defined(OS_WIN) |
| 63 // TODO(port): Port the SSLConfigService class to Linux and Mac OS X. | 69 // TODO(port): Port the SSLConfigService class to Linux and Mac OS X. |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 session_->proxy_service()->CancelPacRequest(pac_request_); | 297 session_->proxy_service()->CancelPacRequest(pac_request_); |
| 292 } | 298 } |
| 293 | 299 |
| 294 void HttpNetworkTransaction::BuildRequestHeaders() { | 300 void HttpNetworkTransaction::BuildRequestHeaders() { |
| 295 // For proxy use the full url. Otherwise just the absolute path. | 301 // For proxy use the full url. Otherwise just the absolute path. |
| 296 // This strips out any reference/username/password. | 302 // This strips out any reference/username/password. |
| 297 std::string path = using_proxy_ ? | 303 std::string path = using_proxy_ ? |
| 298 HttpUtil::SpecForRequest(request_->url) : | 304 HttpUtil::SpecForRequest(request_->url) : |
| 299 HttpUtil::PathForRequest(request_->url); | 305 HttpUtil::PathForRequest(request_->url); |
| 300 | 306 |
| 301 request_headers_ = request_->method + " " + path + | 307 request_headers_->headers_ = request_->method + " " + path + |
| 302 " HTTP/1.1\r\nHost: " + request_->url.host(); | 308 " HTTP/1.1\r\nHost: " + request_->url.host(); |
| 303 if (request_->url.IntPort() != -1) | 309 if (request_->url.IntPort() != -1) |
| 304 request_headers_ += ":" + request_->url.port(); | 310 request_headers_->headers_ += ":" + request_->url.port(); |
| 305 request_headers_ += "\r\n"; | 311 request_headers_->headers_ += "\r\n"; |
| 306 | 312 |
| 307 // For compat with HTTP/1.0 servers and proxies: | 313 // For compat with HTTP/1.0 servers and proxies: |
| 308 if (using_proxy_) | 314 if (using_proxy_) |
| 309 request_headers_ += "Proxy-"; | 315 request_headers_->headers_ += "Proxy-"; |
| 310 request_headers_ += "Connection: keep-alive\r\n"; | 316 request_headers_->headers_ += "Connection: keep-alive\r\n"; |
| 311 | 317 |
| 312 if (!request_->user_agent.empty()) | 318 if (!request_->user_agent.empty()) |
| 313 request_headers_ += "User-Agent: " + request_->user_agent + "\r\n"; | 319 request_headers_->headers_ += "User-Agent: " + request_->user_agent + |
| 320 "\r\n"; |
| 314 | 321 |
| 315 // Our consumer should have made sure that this is a safe referrer. See for | 322 // Our consumer should have made sure that this is a safe referrer. See for |
| 316 // instance WebCore::FrameLoader::HideReferrer. | 323 // instance WebCore::FrameLoader::HideReferrer. |
| 317 if (request_->referrer.is_valid()) | 324 if (request_->referrer.is_valid()) |
| 318 request_headers_ += "Referer: " + request_->referrer.spec() + "\r\n"; | 325 request_headers_->headers_ += "Referer: " + request_->referrer.spec() + |
| 326 "\r\n"; |
| 319 | 327 |
| 320 // Add a content length header? | 328 // Add a content length header? |
| 321 if (request_->upload_data) { | 329 if (request_->upload_data) { |
| 322 request_body_stream_.reset(new UploadDataStream(request_->upload_data)); | 330 request_body_stream_.reset(new UploadDataStream(request_->upload_data)); |
| 323 request_headers_ += | 331 request_headers_->headers_ += |
| 324 "Content-Length: " + Uint64ToString(request_body_stream_->size()) + | 332 "Content-Length: " + Uint64ToString(request_body_stream_->size()) + |
| 325 "\r\n"; | 333 "\r\n"; |
| 326 } else if (request_->method == "POST" || request_->method == "PUT" || | 334 } else if (request_->method == "POST" || request_->method == "PUT" || |
| 327 request_->method == "HEAD") { | 335 request_->method == "HEAD") { |
| 328 // An empty POST/PUT request still needs a content length. As for HEAD, | 336 // 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 | 337 // 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 | 338 // 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. | 339 // POST or some other method that normally would have a message body. |
| 332 request_headers_ += "Content-Length: 0\r\n"; | 340 request_headers_->headers_ += "Content-Length: 0\r\n"; |
| 333 } | 341 } |
| 334 | 342 |
| 335 // Honor load flags that impact proxy caches. | 343 // Honor load flags that impact proxy caches. |
| 336 if (request_->load_flags & LOAD_BYPASS_CACHE) { | 344 if (request_->load_flags & LOAD_BYPASS_CACHE) { |
| 337 request_headers_ += "Pragma: no-cache\r\nCache-Control: no-cache\r\n"; | 345 request_headers_->headers_ += |
| 346 "Pragma: no-cache\r\nCache-Control: no-cache\r\n"; |
| 338 } else if (request_->load_flags & LOAD_VALIDATE_CACHE) { | 347 } else if (request_->load_flags & LOAD_VALIDATE_CACHE) { |
| 339 request_headers_ += "Cache-Control: max-age=0\r\n"; | 348 request_headers_->headers_ += "Cache-Control: max-age=0\r\n"; |
| 340 } | 349 } |
| 341 | 350 |
| 342 ApplyAuth(); | 351 ApplyAuth(); |
| 343 | 352 |
| 344 // TODO(darin): Need to prune out duplicate headers. | 353 // TODO(darin): Need to prune out duplicate headers. |
| 345 | 354 |
| 346 request_headers_ += request_->extra_headers; | 355 request_headers_->headers_ += request_->extra_headers; |
| 347 request_headers_ += "\r\n"; | 356 request_headers_->headers_ += "\r\n"; |
| 348 } | 357 } |
| 349 | 358 |
| 350 // The HTTP CONNECT method for establishing a tunnel connection is documented | 359 // 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 | 360 // in draft-luotonen-web-proxy-tunneling-01.txt and RFC 2817, Sections 5.2 and |
| 352 // 5.3. | 361 // 5.3. |
| 353 void HttpNetworkTransaction::BuildTunnelRequest() { | 362 void HttpNetworkTransaction::BuildTunnelRequest() { |
| 354 // RFC 2616 Section 9 says the Host request-header field MUST accompany all | 363 // RFC 2616 Section 9 says the Host request-header field MUST accompany all |
| 355 // HTTP/1.1 requests. | 364 // HTTP/1.1 requests. |
| 356 request_headers_ = StringPrintf("CONNECT %s:%d HTTP/1.1\r\n", | 365 request_headers_->headers_ = StringPrintf("CONNECT %s:%d HTTP/1.1\r\n", |
| 357 request_->url.host().c_str(), request_->url.EffectiveIntPort()); | 366 request_->url.host().c_str(), request_->url.EffectiveIntPort()); |
| 358 request_headers_ += "Host: " + request_->url.host(); | 367 request_headers_->headers_ += "Host: " + request_->url.host(); |
| 359 if (request_->url.has_port()) | 368 if (request_->url.has_port()) |
| 360 request_headers_ += ":" + request_->url.port(); | 369 request_headers_->headers_ += ":" + request_->url.port(); |
| 361 request_headers_ += "\r\n"; | 370 request_headers_->headers_ += "\r\n"; |
| 362 | 371 |
| 363 if (!request_->user_agent.empty()) | 372 if (!request_->user_agent.empty()) |
| 364 request_headers_ += "User-Agent: " + request_->user_agent + "\r\n"; | 373 request_headers_->headers_ += "User-Agent: " + request_->user_agent + |
| 374 "\r\n"; |
| 365 | 375 |
| 366 ApplyAuth(); | 376 ApplyAuth(); |
| 367 | 377 |
| 368 request_headers_ += "\r\n"; | 378 request_headers_->headers_ += "\r\n"; |
| 369 } | 379 } |
| 370 | 380 |
| 371 void HttpNetworkTransaction::DoCallback(int rv) { | 381 void HttpNetworkTransaction::DoCallback(int rv) { |
| 372 DCHECK(rv != ERR_IO_PENDING); | 382 DCHECK(rv != ERR_IO_PENDING); |
| 373 DCHECK(user_callback_); | 383 DCHECK(user_callback_); |
| 374 | 384 |
| 375 // Since Run may result in Read being called, clear user_callback_ up front. | 385 // Since Run may result in Read being called, clear user_callback_ up front. |
| 376 CompletionCallback* c = user_callback_; | 386 CompletionCallback* c = user_callback_; |
| 377 user_callback_ = NULL; | 387 user_callback_ = NULL; |
| 378 c->Run(rv); | 388 c->Run(rv); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 result = HandleSSLHandshakeError(result); | 657 result = HandleSSLHandshakeError(result); |
| 648 } | 658 } |
| 649 return result; | 659 return result; |
| 650 } | 660 } |
| 651 | 661 |
| 652 int HttpNetworkTransaction::DoWriteHeaders() { | 662 int HttpNetworkTransaction::DoWriteHeaders() { |
| 653 next_state_ = STATE_WRITE_HEADERS_COMPLETE; | 663 next_state_ = STATE_WRITE_HEADERS_COMPLETE; |
| 654 | 664 |
| 655 // This is constructed lazily (instead of within our Start method), so that | 665 // This is constructed lazily (instead of within our Start method), so that |
| 656 // we have proxy info available. | 666 // we have proxy info available. |
| 657 if (request_headers_.empty()) { | 667 if (request_headers_->headers_.empty()) { |
| 658 if (establishing_tunnel_) { | 668 if (establishing_tunnel_) { |
| 659 BuildTunnelRequest(); | 669 BuildTunnelRequest(); |
| 660 } else { | 670 } else { |
| 661 BuildRequestHeaders(); | 671 BuildRequestHeaders(); |
| 662 } | 672 } |
| 663 } | 673 } |
| 664 | 674 |
| 665 // Record our best estimate of the 'request time' as the time when we send | 675 // Record our best estimate of the 'request time' as the time when we send |
| 666 // out the first bytes of the request headers. | 676 // out the first bytes of the request headers. |
| 667 if (request_headers_bytes_sent_ == 0) { | 677 if (request_headers_bytes_sent_ == 0) { |
| 668 response_.request_time = Time::Now(); | 678 response_.request_time = Time::Now(); |
| 669 } | 679 } |
| 670 | 680 |
| 671 const char* buf = request_headers_.data() + request_headers_bytes_sent_; | 681 request_headers_->SetDataOffset(request_headers_bytes_sent_); |
| 672 int buf_len = static_cast<int>(request_headers_.size() - | 682 int buf_len = static_cast<int>(request_headers_->headers_.size() - |
| 673 request_headers_bytes_sent_); | 683 request_headers_bytes_sent_); |
| 674 DCHECK(buf_len > 0); | 684 DCHECK(buf_len > 0); |
| 675 | 685 |
| 676 return connection_.socket()->Write(buf, buf_len, &io_callback_); | 686 return connection_.socket()->Write(request_headers_, buf_len, &io_callback_); |
| 677 } | 687 } |
| 678 | 688 |
| 679 int HttpNetworkTransaction::DoWriteHeadersComplete(int result) { | 689 int HttpNetworkTransaction::DoWriteHeadersComplete(int result) { |
| 680 if (result < 0) | 690 if (result < 0) |
| 681 return HandleIOError(result); | 691 return HandleIOError(result); |
| 682 | 692 |
| 683 request_headers_bytes_sent_ += result; | 693 request_headers_bytes_sent_ += result; |
| 684 if (request_headers_bytes_sent_ < request_headers_.size()) { | 694 if (request_headers_bytes_sent_ < request_headers_->headers_.size()) { |
| 685 next_state_ = STATE_WRITE_HEADERS; | 695 next_state_ = STATE_WRITE_HEADERS; |
| 686 } else if (!establishing_tunnel_ && request_body_stream_.get() && | 696 } else if (!establishing_tunnel_ && request_body_stream_.get() && |
| 687 request_body_stream_->size()) { | 697 request_body_stream_->size()) { |
| 688 next_state_ = STATE_WRITE_BODY; | 698 next_state_ = STATE_WRITE_BODY; |
| 689 } else { | 699 } else { |
| 690 next_state_ = STATE_READ_HEADERS; | 700 next_state_ = STATE_READ_HEADERS; |
| 691 } | 701 } |
| 692 return OK; | 702 return OK; |
| 693 } | 703 } |
| 694 | 704 |
| 695 int HttpNetworkTransaction::DoWriteBody() { | 705 int HttpNetworkTransaction::DoWriteBody() { |
| 696 next_state_ = STATE_WRITE_BODY_COMPLETE; | 706 next_state_ = STATE_WRITE_BODY_COMPLETE; |
| 697 | 707 |
| 698 DCHECK(request_body_stream_.get()); | 708 DCHECK(request_body_stream_.get()); |
| 699 DCHECK(request_body_stream_->size()); | 709 DCHECK(request_body_stream_->size()); |
| 700 | 710 |
| 701 const char* buf = request_body_stream_->buf(); | 711 const char* buf = request_body_stream_->buf(); |
| 702 int buf_len = static_cast<int>(request_body_stream_->buf_len()); | 712 int buf_len = static_cast<int>(request_body_stream_->buf_len()); |
| 713 DCHECK(!write_buffer_); |
| 714 write_buffer_ = new IOBuffer(buf_len); |
| 715 memcpy(write_buffer_->data(), buf, buf_len); |
| 703 | 716 |
| 704 return connection_.socket()->Write(buf, buf_len, &io_callback_); | 717 return connection_.socket()->Write(write_buffer_, buf_len, &io_callback_); |
| 705 } | 718 } |
| 706 | 719 |
| 707 int HttpNetworkTransaction::DoWriteBodyComplete(int result) { | 720 int HttpNetworkTransaction::DoWriteBodyComplete(int result) { |
| 721 DCHECK(write_buffer_); |
| 722 write_buffer_ = NULL; |
| 723 |
| 708 if (result < 0) | 724 if (result < 0) |
| 709 return HandleIOError(result); | 725 return HandleIOError(result); |
| 710 | 726 |
| 711 request_body_stream_->DidConsume(result); | 727 request_body_stream_->DidConsume(result); |
| 712 | 728 |
| 713 if (request_body_stream_->position() < request_body_stream_->size()) { | 729 if (request_body_stream_->position() < request_body_stream_->size()) { |
| 714 next_state_ = STATE_WRITE_BODY; | 730 next_state_ = STATE_WRITE_BODY; |
| 715 } else { | 731 } else { |
| 716 next_state_ = STATE_READ_HEADERS; | 732 next_state_ = STATE_READ_HEADERS; |
| 717 } | 733 } |
| 718 return OK; | 734 return OK; |
| 719 } | 735 } |
| 720 | 736 |
| 721 int HttpNetworkTransaction::DoReadHeaders() { | 737 int HttpNetworkTransaction::DoReadHeaders() { |
| 722 next_state_ = STATE_READ_HEADERS_COMPLETE; | 738 next_state_ = STATE_READ_HEADERS_COMPLETE; |
| 723 | 739 |
| 724 // Grow the read buffer if necessary. | 740 // Grow the read buffer if necessary. |
| 725 if (header_buf_len_ == header_buf_capacity_) { | 741 if (header_buf_len_ == header_buf_capacity_) { |
| 726 header_buf_capacity_ += kHeaderBufInitialSize; | 742 header_buf_capacity_ += kHeaderBufInitialSize; |
| 727 header_buf_.reset(static_cast<char*>( | 743 header_buf_->Realloc(header_buf_capacity_); |
| 728 realloc(header_buf_.release(), header_buf_capacity_))); | |
| 729 } | 744 } |
| 730 | 745 |
| 731 char* buf = header_buf_.get() + header_buf_len_; | |
| 732 int buf_len = header_buf_capacity_ - header_buf_len_; | 746 int buf_len = header_buf_capacity_ - header_buf_len_; |
| 747 header_buf_->set_data(header_buf_len_); |
| 733 | 748 |
| 734 return connection_.socket()->Read(buf, buf_len, &io_callback_); | 749 return connection_.socket()->Read(header_buf_, buf_len, &io_callback_); |
| 735 } | 750 } |
| 736 | 751 |
| 737 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() { | 752 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() { |
| 738 if (establishing_tunnel_) { | 753 if (establishing_tunnel_) { |
| 739 // The connection was closed before the tunnel could be established. | 754 // The connection was closed before the tunnel could be established. |
| 740 return ERR_TUNNEL_CONNECTION_FAILED; | 755 return ERR_TUNNEL_CONNECTION_FAILED; |
| 741 } | 756 } |
| 742 | 757 |
| 743 if (has_found_status_line_start()) { | 758 if (has_found_status_line_start()) { |
| 744 // Assume EOF is end-of-headers. | 759 // Assume EOF is end-of-headers. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 int rv = HandleConnectionClosedBeforeEndOfHeaders(); | 800 int rv = HandleConnectionClosedBeforeEndOfHeaders(); |
| 786 if (rv != OK) | 801 if (rv != OK) |
| 787 return rv; | 802 return rv; |
| 788 } else { | 803 } else { |
| 789 header_buf_len_ += result; | 804 header_buf_len_ += result; |
| 790 DCHECK(header_buf_len_ <= header_buf_capacity_); | 805 DCHECK(header_buf_len_ <= header_buf_capacity_); |
| 791 | 806 |
| 792 // Look for the start of the status line, if it hasn't been found yet. | 807 // Look for the start of the status line, if it hasn't been found yet. |
| 793 if (!has_found_status_line_start()) { | 808 if (!has_found_status_line_start()) { |
| 794 header_buf_http_offset_ = HttpUtil::LocateStartOfStatusLine( | 809 header_buf_http_offset_ = HttpUtil::LocateStartOfStatusLine( |
| 795 header_buf_.get(), header_buf_len_); | 810 header_buf_->headers(), header_buf_len_); |
| 796 } | 811 } |
| 797 | 812 |
| 798 if (has_found_status_line_start()) { | 813 if (has_found_status_line_start()) { |
| 799 int eoh = HttpUtil::LocateEndOfHeaders( | 814 int eoh = HttpUtil::LocateEndOfHeaders( |
| 800 header_buf_.get(), header_buf_len_, header_buf_http_offset_); | 815 header_buf_->headers(), header_buf_len_, header_buf_http_offset_); |
| 801 if (eoh == -1) { | 816 if (eoh == -1) { |
| 802 // Prevent growing the headers buffer indefinitely. | 817 // Prevent growing the headers buffer indefinitely. |
| 803 if (header_buf_len_ >= kMaxHeaderBufSize) | 818 if (header_buf_len_ >= kMaxHeaderBufSize) |
| 804 return ERR_RESPONSE_HEADERS_TOO_BIG; | 819 return ERR_RESPONSE_HEADERS_TOO_BIG; |
| 805 | 820 |
| 806 // Haven't found the end of headers yet, keep reading. | 821 // Haven't found the end of headers yet, keep reading. |
| 807 next_state_ = STATE_READ_HEADERS; | 822 next_state_ = STATE_READ_HEADERS; |
| 808 return OK; | 823 return OK; |
| 809 } | 824 } |
| 810 header_buf_body_offset_ = eoh; | 825 header_buf_body_offset_ = eoh; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 829 DCHECK(connection_.is_initialized()); | 844 DCHECK(connection_.is_initialized()); |
| 830 | 845 |
| 831 next_state_ = STATE_READ_BODY_COMPLETE; | 846 next_state_ = STATE_READ_BODY_COMPLETE; |
| 832 | 847 |
| 833 // We may have already consumed the indicated content length. | 848 // We may have already consumed the indicated content length. |
| 834 if (response_body_length_ != -1 && | 849 if (response_body_length_ != -1 && |
| 835 response_body_read_ >= response_body_length_) | 850 response_body_read_ >= response_body_length_) |
| 836 return 0; | 851 return 0; |
| 837 | 852 |
| 838 // We may have some data remaining in the header buffer. | 853 // We may have some data remaining in the header buffer. |
| 839 if (header_buf_.get() && header_buf_body_offset_ < header_buf_len_) { | 854 if (header_buf_->headers() && header_buf_body_offset_ < header_buf_len_) { |
| 840 int n = std::min(read_buf_len_, header_buf_len_ - header_buf_body_offset_); | 855 int n = std::min(read_buf_len_, header_buf_len_ - header_buf_body_offset_); |
| 841 memcpy(read_buf_->data(), header_buf_.get() + header_buf_body_offset_, n); | 856 memcpy(read_buf_->data(), header_buf_->headers() + header_buf_body_offset_, |
| 857 n); |
| 842 header_buf_body_offset_ += n; | 858 header_buf_body_offset_ += n; |
| 843 if (header_buf_body_offset_ == header_buf_len_) { | 859 if (header_buf_body_offset_ == header_buf_len_) { |
| 844 header_buf_.reset(); | 860 header_buf_->Reset(); |
| 845 header_buf_capacity_ = 0; | 861 header_buf_capacity_ = 0; |
| 846 header_buf_len_ = 0; | 862 header_buf_len_ = 0; |
| 847 header_buf_body_offset_ = -1; | 863 header_buf_body_offset_ = -1; |
| 848 } | 864 } |
| 849 return n; | 865 return n; |
| 850 } | 866 } |
| 851 | 867 |
| 852 reading_body_from_socket_ = true; | 868 reading_body_from_socket_ = true; |
| 853 return connection_.socket()->Read(read_buf_->data(), read_buf_len_, | 869 return connection_.socket()->Read(read_buf_, read_buf_len_, &io_callback_); |
| 854 &io_callback_); | |
| 855 } | 870 } |
| 856 | 871 |
| 857 int HttpNetworkTransaction::DoReadBodyComplete(int result) { | 872 int HttpNetworkTransaction::DoReadBodyComplete(int result) { |
| 858 // We are done with the Read call. | 873 // We are done with the Read call. |
| 859 DCHECK(!establishing_tunnel_) << | 874 DCHECK(!establishing_tunnel_) << |
| 860 "We should never read a response body of a tunnel."; | 875 "We should never read a response body of a tunnel."; |
| 861 | 876 |
| 862 bool unfiltered_eof = (result == 0 && reading_body_from_socket_); | 877 bool unfiltered_eof = (result == 0 && reading_body_from_socket_); |
| 863 reading_body_from_socket_ = false; | 878 reading_body_from_socket_ = false; |
| 864 | 879 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 LOG(WARNING) << "Blocked proxy response with status " << response_code | 1067 LOG(WARNING) << "Blocked proxy response with status " << response_code |
| 1053 << " to CONNECT request for " << request_->url.host() << ":" | 1068 << " to CONNECT request for " << request_->url.host() << ":" |
| 1054 << request_->url.EffectiveIntPort() << "."; | 1069 << request_->url.EffectiveIntPort() << "."; |
| 1055 } | 1070 } |
| 1056 | 1071 |
| 1057 int HttpNetworkTransaction::DidReadResponseHeaders() { | 1072 int HttpNetworkTransaction::DidReadResponseHeaders() { |
| 1058 scoped_refptr<HttpResponseHeaders> headers; | 1073 scoped_refptr<HttpResponseHeaders> headers; |
| 1059 if (has_found_status_line_start()) { | 1074 if (has_found_status_line_start()) { |
| 1060 headers = new HttpResponseHeaders( | 1075 headers = new HttpResponseHeaders( |
| 1061 HttpUtil::AssembleRawHeaders( | 1076 HttpUtil::AssembleRawHeaders( |
| 1062 header_buf_.get(), header_buf_body_offset_)); | 1077 header_buf_->headers(), header_buf_body_offset_)); |
| 1063 } else { | 1078 } else { |
| 1064 // Fabricate a status line to to preserve the HTTP/0.9 version. | 1079 // Fabricate a status line to to preserve the HTTP/0.9 version. |
| 1065 // (otherwise HttpResponseHeaders will default it to HTTP/1.0). | 1080 // (otherwise HttpResponseHeaders will default it to HTTP/1.0). |
| 1066 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK")); | 1081 headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK")); |
| 1067 } | 1082 } |
| 1068 | 1083 |
| 1069 if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { | 1084 if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { |
| 1070 // Require the "HTTP/1.x" status line for SSL CONNECT. | 1085 // Require the "HTTP/1.x" status line for SSL CONNECT. |
| 1071 if (establishing_tunnel_) | 1086 if (establishing_tunnel_) |
| 1072 return ERR_TUNNEL_CONNECTION_FAILED; | 1087 return ERR_TUNNEL_CONNECTION_FAILED; |
| 1073 | 1088 |
| 1074 // HTTP/0.9 doesn't support the PUT method, so lack of response headers | 1089 // HTTP/0.9 doesn't support the PUT method, so lack of response headers |
| 1075 // indicates a buggy server. See: | 1090 // indicates a buggy server. See: |
| 1076 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 | 1091 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 |
| 1077 if (request_->method == "PUT") | 1092 if (request_->method == "PUT") |
| 1078 return ERR_METHOD_NOT_SUPPORTED; | 1093 return ERR_METHOD_NOT_SUPPORTED; |
| 1079 } | 1094 } |
| 1080 | 1095 |
| 1081 if (establishing_tunnel_) { | 1096 if (establishing_tunnel_) { |
| 1082 switch (headers->response_code()) { | 1097 switch (headers->response_code()) { |
| 1083 case 200: // OK | 1098 case 200: // OK |
| 1084 if (header_buf_body_offset_ != header_buf_len_) { | 1099 if (header_buf_body_offset_ != header_buf_len_) { |
| 1085 // The proxy sent extraneous data after the headers. | 1100 // The proxy sent extraneous data after the headers. |
| 1086 return ERR_TUNNEL_CONNECTION_FAILED; | 1101 return ERR_TUNNEL_CONNECTION_FAILED; |
| 1087 } | 1102 } |
| 1088 next_state_ = STATE_SSL_CONNECT; | 1103 next_state_ = STATE_SSL_CONNECT; |
| 1089 // Reset for the real request and response headers. | 1104 // Reset for the real request and response headers. |
| 1090 request_headers_.clear(); | 1105 request_headers_->headers_.clear(); |
| 1091 request_headers_bytes_sent_ = 0; | 1106 request_headers_bytes_sent_ = 0; |
| 1092 header_buf_len_ = 0; | 1107 header_buf_len_ = 0; |
| 1093 header_buf_body_offset_ = 0; | 1108 header_buf_body_offset_ = 0; |
| 1094 establishing_tunnel_ = false; | 1109 establishing_tunnel_ = false; |
| 1095 return OK; | 1110 return OK; |
| 1096 | 1111 |
| 1097 // We aren't able to CONNECT to the remote host through the proxy. We | 1112 // We aren't able to CONNECT to the remote host through the proxy. We |
| 1098 // need to be very suspicious about the response because an active network | 1113 // need to be very suspicious about the response because an active network |
| 1099 // attacker can force us into this state by masquerading as the proxy. | 1114 // attacker can force us into this state by masquerading as the proxy. |
| 1100 // The only safe thing to do here is to fail the connection because our | 1115 // The only safe thing to do here is to fail the connection because our |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1120 // Check for an intermediate 100 Continue response. An origin server is | 1135 // Check for an intermediate 100 Continue response. An origin server is |
| 1121 // allowed to send this response even if we didn't ask for it, so we just | 1136 // allowed to send this response even if we didn't ask for it, so we just |
| 1122 // need to skip over it. | 1137 // need to skip over it. |
| 1123 // We treat any other 1xx in this same way (although in practice getting | 1138 // We treat any other 1xx in this same way (although in practice getting |
| 1124 // a 1xx that isn't a 100 is rare). | 1139 // a 1xx that isn't a 100 is rare). |
| 1125 if (headers->response_code() / 100 == 1) { | 1140 if (headers->response_code() / 100 == 1) { |
| 1126 header_buf_len_ -= header_buf_body_offset_; | 1141 header_buf_len_ -= header_buf_body_offset_; |
| 1127 // If we've already received some bytes after the 1xx response, | 1142 // If we've already received some bytes after the 1xx response, |
| 1128 // move them to the beginning of header_buf_. | 1143 // move them to the beginning of header_buf_. |
| 1129 if (header_buf_len_) { | 1144 if (header_buf_len_) { |
| 1130 memmove(header_buf_.get(), header_buf_.get() + header_buf_body_offset_, | 1145 memmove(header_buf_->headers(), |
| 1146 header_buf_->headers() + header_buf_body_offset_, |
| 1131 header_buf_len_); | 1147 header_buf_len_); |
| 1132 } | 1148 } |
| 1133 header_buf_body_offset_ = -1; | 1149 header_buf_body_offset_ = -1; |
| 1134 next_state_ = STATE_READ_HEADERS; | 1150 next_state_ = STATE_READ_HEADERS; |
| 1135 return OK; | 1151 return OK; |
| 1136 } | 1152 } |
| 1137 | 1153 |
| 1138 response_.headers = headers; | 1154 response_.headers = headers; |
| 1139 response_.vary_data.Init(*request_, *response_.headers); | 1155 response_.vary_data.Init(*request_, *response_.headers); |
| 1140 | 1156 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1259 case ERR_CONNECTION_ABORTED: | 1275 case ERR_CONNECTION_ABORTED: |
| 1260 if (ShouldResendRequest()) | 1276 if (ShouldResendRequest()) |
| 1261 error = OK; | 1277 error = OK; |
| 1262 break; | 1278 break; |
| 1263 } | 1279 } |
| 1264 return error; | 1280 return error; |
| 1265 } | 1281 } |
| 1266 | 1282 |
| 1267 void HttpNetworkTransaction::ResetStateForRestart() { | 1283 void HttpNetworkTransaction::ResetStateForRestart() { |
| 1268 pending_auth_target_ = HttpAuth::AUTH_NONE; | 1284 pending_auth_target_ = HttpAuth::AUTH_NONE; |
| 1269 header_buf_.reset(); | 1285 header_buf_->Reset(); |
| 1270 header_buf_capacity_ = 0; | 1286 header_buf_capacity_ = 0; |
| 1271 header_buf_len_ = 0; | 1287 header_buf_len_ = 0; |
| 1272 header_buf_body_offset_ = -1; | 1288 header_buf_body_offset_ = -1; |
| 1273 header_buf_http_offset_ = -1; | 1289 header_buf_http_offset_ = -1; |
| 1274 response_body_length_ = -1; | 1290 response_body_length_ = -1; |
| 1275 response_body_read_ = 0; | 1291 response_body_read_ = 0; |
| 1276 read_buf_ = NULL; | 1292 read_buf_ = NULL; |
| 1277 read_buf_len_ = 0; | 1293 read_buf_len_ = 0; |
| 1278 request_headers_.clear(); | 1294 request_headers_->headers_.clear(); |
| 1279 request_headers_bytes_sent_ = 0; | 1295 request_headers_bytes_sent_ = 0; |
| 1280 chunked_decoder_.reset(); | 1296 chunked_decoder_.reset(); |
| 1281 // Reset all the members of response_. | 1297 // Reset all the members of response_. |
| 1282 response_ = HttpResponseInfo(); | 1298 response_ = HttpResponseInfo(); |
| 1283 } | 1299 } |
| 1284 | 1300 |
| 1285 bool HttpNetworkTransaction::ShouldResendRequest() { | 1301 bool HttpNetworkTransaction::ShouldResendRequest() { |
| 1286 // NOTE: we resend a request only if we reused a keep-alive connection. | 1302 // 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 | 1303 // This automatically prevents an infinite resend loop because we'll run |
| 1288 // out of the cached keep-alive connections eventually. | 1304 // out of the cached keep-alive connections eventually. |
| 1289 if (establishing_tunnel_ || | 1305 if (establishing_tunnel_ || |
| 1290 !reused_socket_ || // We didn't reuse a keep-alive connection. | 1306 !reused_socket_ || // We didn't reuse a keep-alive connection. |
| 1291 header_buf_len_) { // We have received some response headers. | 1307 header_buf_len_) { // We have received some response headers. |
| 1292 return false; | 1308 return false; |
| 1293 } | 1309 } |
| 1294 connection_.set_socket(NULL); | 1310 connection_.set_socket(NULL); |
| 1295 connection_.Reset(); | 1311 connection_.Reset(); |
| 1296 // There are two reasons we need to clear request_headers_. 1) It contains | 1312 // 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 | 1313 // 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 | 1314 // first to recreate the SSL tunnel. 2) An empty request_headers_ causes |
| 1299 // BuildRequestHeaders to be called, which rewinds request_body_stream_ to | 1315 // BuildRequestHeaders to be called, which rewinds request_body_stream_ to |
| 1300 // the beginning of request_->upload_data. | 1316 // the beginning of request_->upload_data. |
| 1301 request_headers_.clear(); | 1317 request_headers_->headers_.clear(); |
| 1302 request_headers_bytes_sent_ = 0; | 1318 request_headers_bytes_sent_ = 0; |
| 1303 next_state_ = STATE_INIT_CONNECTION; // Resend the request. | 1319 next_state_ = STATE_INIT_CONNECTION; // Resend the request. |
| 1304 return true; | 1320 return true; |
| 1305 } | 1321 } |
| 1306 | 1322 |
| 1307 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { | 1323 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { |
| 1308 DCHECK(!pac_request_); | 1324 DCHECK(!pac_request_); |
| 1309 | 1325 |
| 1310 // A failure to resolve the hostname or any error related to establishing a | 1326 // 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. | 1327 // TCP connection could be grounds for trying a new proxy configuration. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 return; | 1371 return; |
| 1356 | 1372 |
| 1357 DCHECK(HaveAuth(target)); | 1373 DCHECK(HaveAuth(target)); |
| 1358 | 1374 |
| 1359 // Add a Authorization/Proxy-Authorization header line. | 1375 // Add a Authorization/Proxy-Authorization header line. |
| 1360 std::string credentials = auth_handler_[target]->GenerateCredentials( | 1376 std::string credentials = auth_handler_[target]->GenerateCredentials( |
| 1361 auth_identity_[target].username, | 1377 auth_identity_[target].username, |
| 1362 auth_identity_[target].password, | 1378 auth_identity_[target].password, |
| 1363 request_, | 1379 request_, |
| 1364 &proxy_info_); | 1380 &proxy_info_); |
| 1365 request_headers_ += HttpAuth::GetAuthorizationHeaderName(target) + | 1381 request_headers_->headers_ += HttpAuth::GetAuthorizationHeaderName(target) + |
| 1366 ": " + credentials + "\r\n"; | 1382 ": " + credentials + "\r\n"; |
| 1367 } | 1383 } |
| 1368 | 1384 |
| 1369 void HttpNetworkTransaction::ApplyAuth() { | 1385 void HttpNetworkTransaction::ApplyAuth() { |
| 1370 // We expect using_proxy_ and using_tunnel_ to be mutually exclusive. | 1386 // We expect using_proxy_ and using_tunnel_ to be mutually exclusive. |
| 1371 DCHECK(!using_proxy_ || !using_tunnel_); | 1387 DCHECK(!using_proxy_ || !using_tunnel_); |
| 1372 | 1388 |
| 1373 // Don't send proxy auth after tunnel has been established. | 1389 // Don't send proxy auth after tunnel has been established. |
| 1374 bool should_apply_proxy_auth = using_proxy_ || establishing_tunnel_; | 1390 bool should_apply_proxy_auth = using_proxy_ || establishing_tunnel_; |
| 1375 | 1391 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1621 if (target == HttpAuth::AUTH_PROXY) { | 1637 if (target == HttpAuth::AUTH_PROXY) { |
| 1622 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); | 1638 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); |
| 1623 } else { | 1639 } else { |
| 1624 DCHECK(target == HttpAuth::AUTH_SERVER); | 1640 DCHECK(target == HttpAuth::AUTH_SERVER); |
| 1625 auth_info->host = ASCIIToWide(request_->url.host()); | 1641 auth_info->host = ASCIIToWide(request_->url.host()); |
| 1626 } | 1642 } |
| 1627 response_.auth_challenge = auth_info; | 1643 response_.auth_challenge = auth_info; |
| 1628 } | 1644 } |
| 1629 | 1645 |
| 1630 } // namespace net | 1646 } // namespace net |
| OLD | NEW |