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 |