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

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

Issue 8586015: Slow start pipelining. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Whitelist some socket errors Created 9 years, 1 month 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_pipelined_connection_impl.h" 5 #include "net/http/http_pipelined_connection_impl.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "net/base/io_buffer.h" 9 #include "net/base/io_buffer.h"
10 #include "net/http/http_pipelined_stream.h" 10 #include "net/http/http_pipelined_stream.h"
11 #include "net/http/http_request_info.h" 11 #include "net/http/http_request_info.h"
12 #include "net/http/http_response_headers.h"
12 #include "net/http/http_stream_parser.h" 13 #include "net/http/http_stream_parser.h"
14 #include "net/http/http_version.h"
13 #include "net/socket/client_socket_handle.h" 15 #include "net/socket/client_socket_handle.h"
14 16
15 namespace net { 17 namespace net {
16 18
17 HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl( 19 HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl(
18 ClientSocketHandle* connection, 20 ClientSocketHandle* connection,
19 HttpPipelinedConnection::Delegate* delegate, 21 HttpPipelinedConnection::Delegate* delegate,
20 const SSLConfig& used_ssl_config, 22 const SSLConfig& used_ssl_config,
21 const ProxyInfo& used_proxy_info, 23 const ProxyInfo& used_proxy_info,
22 const BoundNetLog& net_log, 24 const BoundNetLog& net_log,
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 case SEND_STATE_SEND_ACTIVE_REQUEST: 160 case SEND_STATE_SEND_ACTIVE_REQUEST:
159 rv = DoSendActiveRequest(rv); 161 rv = DoSendActiveRequest(rv);
160 break; 162 break;
161 case SEND_STATE_COMPLETE: 163 case SEND_STATE_COMPLETE:
162 rv = DoSendComplete(rv); 164 rv = DoSendComplete(rv);
163 break; 165 break;
164 case SEND_STATE_EVICT_PENDING_REQUESTS: 166 case SEND_STATE_EVICT_PENDING_REQUESTS:
165 rv = DoEvictPendingSendRequests(rv); 167 rv = DoEvictPendingSendRequests(rv);
166 break; 168 break;
167 default: 169 default:
168 NOTREACHED() << "bad send state: " << state; 170 CHECK(false) << "bad send state: " << state;
169 rv = ERR_FAILED; 171 rv = ERR_FAILED;
170 break; 172 break;
171 } 173 }
172 } while (rv != ERR_IO_PENDING && send_next_state_ != SEND_STATE_NONE); 174 } while (rv != ERR_IO_PENDING && send_next_state_ != SEND_STATE_NONE);
173 send_still_on_call_stack_ = false; 175 send_still_on_call_stack_ = false;
174 return rv; 176 return rv;
175 } 177 }
176 178
177 void HttpPipelinedConnectionImpl::OnSendIOCallback(int result) { 179 void HttpPipelinedConnectionImpl::OnSendIOCallback(int result) {
178 CHECK(active_send_request_.get()); 180 CHECK(active_send_request_.get());
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 return rv; 330 return rv;
329 case READ_STATE_STREAM_CLOSED: 331 case READ_STATE_STREAM_CLOSED:
330 rv = DoReadStreamClosed(); 332 rv = DoReadStreamClosed();
331 break; 333 break;
332 case READ_STATE_EVICT_PENDING_READS: 334 case READ_STATE_EVICT_PENDING_READS:
333 rv = DoEvictPendingReadHeaders(rv); 335 rv = DoEvictPendingReadHeaders(rv);
334 break; 336 break;
335 case READ_STATE_NONE: 337 case READ_STATE_NONE:
336 break; 338 break;
337 default: 339 default:
338 NOTREACHED() << "bad read state"; 340 CHECK(false) << "bad read state";
339 rv = ERR_FAILED; 341 rv = ERR_FAILED;
340 break; 342 break;
341 } 343 }
342 } while (rv != ERR_IO_PENDING && read_next_state_ != READ_STATE_NONE); 344 } while (rv != ERR_IO_PENDING && read_next_state_ != READ_STATE_NONE);
343 read_still_on_call_stack_ = false; 345 read_still_on_call_stack_ = false;
344 return rv; 346 return rv;
345 } 347 }
346 348
347 void HttpPipelinedConnectionImpl::OnReadIOCallback(int result) { 349 void HttpPipelinedConnectionImpl::OnReadIOCallback(int result) {
348 DoReadHeadersLoop(result); 350 DoReadHeadersLoop(result);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 // Since nobody will read whatever data is on the pipeline associated with 387 // Since nobody will read whatever data is on the pipeline associated with
386 // this closed request, we must shut down the rest of the pipeline. 388 // this closed request, we must shut down the rest of the pipeline.
387 read_next_state_ = READ_STATE_EVICT_PENDING_READS; 389 read_next_state_ = READ_STATE_EVICT_PENDING_READS;
388 break; 390 break;
389 391
390 case STREAM_SENT: 392 case STREAM_SENT:
391 read_next_state_ = READ_STATE_NONE; 393 read_next_state_ = READ_STATE_NONE;
392 break; 394 break;
393 395
394 default: 396 default:
395 NOTREACHED() << "Unexpected read state: " 397 CHECK(false) << "Unexpected read state: "
396 << stream_info_map_[next_id].state; 398 << stream_info_map_[next_id].state;
397 } 399 }
398 400
399 return OK; 401 return OK;
400 } 402 }
401 403
402 int HttpPipelinedConnectionImpl::DoReadHeaders(int result) { 404 int HttpPipelinedConnectionImpl::DoReadHeaders(int result) {
403 CHECK(active_read_id_); 405 CHECK(active_read_id_);
404 CHECK(ContainsKey(stream_info_map_, active_read_id_)); 406 CHECK(ContainsKey(stream_info_map_, active_read_id_));
405 CHECK_EQ(STREAM_READ_PENDING, stream_info_map_[active_read_id_].state); 407 CHECK_EQ(STREAM_READ_PENDING, stream_info_map_[active_read_id_].state);
(...skipping 10 matching lines...) Expand all
416 CHECK_EQ(STREAM_ACTIVE, stream_info_map_[active_read_id_].state); 418 CHECK_EQ(STREAM_ACTIVE, stream_info_map_[active_read_id_].state);
417 419
418 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE; 420 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
419 if (result < OK) { 421 if (result < OK) {
420 if (result == ERR_SOCKET_NOT_CONNECTED && completed_one_request_) { 422 if (result == ERR_SOCKET_NOT_CONNECTED && completed_one_request_) {
421 result = ERR_PIPELINE_EVICTION; 423 result = ERR_PIPELINE_EVICTION;
422 } 424 }
423 usable_ = false; 425 usable_ = false;
424 } 426 }
425 427
428 CheckHeadersForPipelineCompatibility(result, active_read_id_);
429
426 if (!read_still_on_call_stack_) { 430 if (!read_still_on_call_stack_) {
427 QueueUserCallback(active_read_id_, 431 QueueUserCallback(active_read_id_,
428 stream_info_map_[active_read_id_].read_headers_callback, 432 stream_info_map_[active_read_id_].read_headers_callback,
429 result, FROM_HERE); 433 result, FROM_HERE);
430 } 434 }
431 435
432 return result; 436 return result;
433 } 437 }
434 438
435 int HttpPipelinedConnectionImpl::DoReadWaitForClose(int result) { 439 int HttpPipelinedConnectionImpl::DoReadWaitForClose(int result) {
436 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE; 440 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
437 return result; 441 return result;
438 } 442 }
439 443
440 int HttpPipelinedConnectionImpl::DoReadStreamClosed() { 444 int HttpPipelinedConnectionImpl::DoReadStreamClosed() {
441 CHECK(active_read_id_); 445 CHECK(active_read_id_);
442 CHECK(ContainsKey(stream_info_map_, active_read_id_)); 446 CHECK(ContainsKey(stream_info_map_, active_read_id_));
443 CHECK_EQ(stream_info_map_[active_read_id_].state, STREAM_CLOSED); 447 CHECK_EQ(stream_info_map_[active_read_id_].state, STREAM_CLOSED);
444 active_read_id_ = 0; 448 active_read_id_ = 0;
445 if (!usable_) { 449 if (!usable_) {
450 // TODO(simonjam): Don't wait this long to evict.
446 read_next_state_ = READ_STATE_EVICT_PENDING_READS; 451 read_next_state_ = READ_STATE_EVICT_PENDING_READS;
447 return OK; 452 return OK;
448 } 453 }
449 completed_one_request_ = true; 454 completed_one_request_ = true;
450 MessageLoop::current()->PostTask( 455 MessageLoop::current()->PostTask(
451 FROM_HERE, 456 FROM_HERE,
452 method_factory_.NewRunnableMethod( 457 method_factory_.NewRunnableMethod(
453 &HttpPipelinedConnectionImpl::StartNextDeferredRead)); 458 &HttpPipelinedConnectionImpl::StartNextDeferredRead));
454 read_next_state_ = READ_STATE_NONE; 459 read_next_state_ = READ_STATE_NONE;
455 return OK; 460 return OK;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 case STREAM_READ_EVICTED: 523 case STREAM_READ_EVICTED:
519 stream_info_map_[pipeline_id].state = STREAM_CLOSED; 524 stream_info_map_[pipeline_id].state = STREAM_CLOSED;
520 break; 525 break;
521 526
522 case STREAM_CLOSED: 527 case STREAM_CLOSED:
523 case STREAM_UNUSED: 528 case STREAM_UNUSED:
524 // TODO(simonjam): Why is Close() sometimes called twice? 529 // TODO(simonjam): Why is Close() sometimes called twice?
525 break; 530 break;
526 531
527 default: 532 default:
528 NOTREACHED(); 533 CHECK(false);
529 break; 534 break;
530 } 535 }
531 } 536 }
532 537
533 int HttpPipelinedConnectionImpl::ReadResponseBody( 538 int HttpPipelinedConnectionImpl::ReadResponseBody(
534 int pipeline_id, 539 int pipeline_id,
535 IOBuffer* buf, 540 IOBuffer* buf,
536 int buf_len, 541 int buf_len,
537 OldCompletionCallback* callback) { 542 OldCompletionCallback* callback) {
538 CHECK(ContainsKey(stream_info_map_, pipeline_id)); 543 CHECK(ContainsKey(stream_info_map_, pipeline_id));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 604
600 void HttpPipelinedConnectionImpl::GetSSLCertRequestInfo( 605 void HttpPipelinedConnectionImpl::GetSSLCertRequestInfo(
601 int pipeline_id, 606 int pipeline_id,
602 SSLCertRequestInfo* cert_request_info) { 607 SSLCertRequestInfo* cert_request_info) {
603 CHECK(ContainsKey(stream_info_map_, pipeline_id)); 608 CHECK(ContainsKey(stream_info_map_, pipeline_id));
604 CHECK(stream_info_map_[pipeline_id].parser.get()); 609 CHECK(stream_info_map_[pipeline_id].parser.get());
605 return stream_info_map_[pipeline_id].parser->GetSSLCertRequestInfo( 610 return stream_info_map_[pipeline_id].parser->GetSSLCertRequestInfo(
606 cert_request_info); 611 cert_request_info);
607 } 612 }
608 613
614 void HttpPipelinedConnectionImpl::CheckHeadersForPipelineCompatibility(
615 int result,
616 int pipeline_id) {
617 if (result < OK) {
mmenke 2011/11/21 14:51:39 When things go wrong, we won't necessarily get the
James Simonsen 2011/12/01 01:17:10 Okay, I've added a TODO. Eventually, I want to cir
618 switch (result) {
619 case ERR_ABORTED:
620 case ERR_INTERNET_DISCONNECTED:
621 // These errors are no fault of the server.
622 break;
623
624 default:
625 delegate_->OnPipelineFeedback(this, SOCKET_ERROR);
626 return;
627 }
628 }
629 HttpResponseInfo* info = GetResponseInfo(pipeline_id);
630 const HttpVersion required_version(1, 1);
631 if (info->headers->GetParsedHttpVersion() < required_version) {
632 delegate_->OnPipelineFeedback(this, OLD_HTTP_VERSION);
633 return;
634 }
635 if (!info->headers->IsKeepAlive() || !CanFindEndOfResponse(pipeline_id)) {
636 usable_ = false;
637 delegate_->OnPipelineFeedback(this, MUST_CLOSE_CONNECTION);
638 return;
639 }
mmenke 2011/11/21 14:51:39 We should also be doing something about NTLM AUTH
James Simonsen 2011/12/01 01:17:10 Yeah, that was next on my list. I'm going to do it
640 delegate_->OnPipelineFeedback(this, OK);
641 }
642
609 void HttpPipelinedConnectionImpl::QueueUserCallback( 643 void HttpPipelinedConnectionImpl::QueueUserCallback(
610 int pipeline_id, 644 int pipeline_id,
611 OldCompletionCallback* callback, 645 OldCompletionCallback* callback,
612 int rv, 646 int rv,
613 const tracked_objects::Location& from_here) { 647 const tracked_objects::Location& from_here) {
614 CHECK(!stream_info_map_[pipeline_id].pending_user_callback); 648 CHECK(!stream_info_map_[pipeline_id].pending_user_callback);
615 stream_info_map_[pipeline_id].pending_user_callback = callback; 649 stream_info_map_[pipeline_id].pending_user_callback = callback;
616 MessageLoop::current()->PostTask( 650 MessageLoop::current()->PostTask(
617 from_here, 651 from_here,
618 method_factory_.NewRunnableMethod( 652 method_factory_.NewRunnableMethod(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 HttpPipelinedConnectionImpl::StreamInfo::StreamInfo() 703 HttpPipelinedConnectionImpl::StreamInfo::StreamInfo()
670 : read_headers_callback(NULL), 704 : read_headers_callback(NULL),
671 pending_user_callback(NULL), 705 pending_user_callback(NULL),
672 state(STREAM_CREATED) { 706 state(STREAM_CREATED) {
673 } 707 }
674 708
675 HttpPipelinedConnectionImpl::StreamInfo::~StreamInfo() { 709 HttpPipelinedConnectionImpl::StreamInfo::~StreamInfo() {
676 } 710 }
677 711
678 } // namespace net 712 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698