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

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

Issue 87073: Extend the use of IOBuffers to the code underneath... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 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 | Annotate | Revision Log
« 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) 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
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
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
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
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
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
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
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
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
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
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
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