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

Side by Side Diff: net/spdy/spdy_stream.cc

Issue 129543002: Enable SpdyStream's HALF_CLOSED_REMOTE state. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased on to upstream changes. Created 6 years, 10 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/spdy/spdy_stream.h ('k') | net/spdy/spdy_websocket_stream_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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/spdy/spdy_stream.h" 5 #include "net/spdy/spdy_stream.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 // headers once we've finished sending the request headers. 396 // headers once we've finished sending the request headers.
397 if (io_state_ == STATE_IDLE) { 397 if (io_state_ == STATE_IDLE) {
398 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, 398 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR,
399 "Response received before request sent"); 399 "Response received before request sent");
400 return ERR_SPDY_PROTOCOL_ERROR; 400 return ERR_SPDY_PROTOCOL_ERROR;
401 } 401 }
402 break; 402 break;
403 403
404 case SPDY_REQUEST_RESPONSE_STREAM: 404 case SPDY_REQUEST_RESPONSE_STREAM:
405 // For a request/response stream, we're ready for the response 405 // For a request/response stream, we're ready for the response
406 // headers once we've finished sending the request headers and 406 // headers once we've finished sending the request headers.
407 // the request body (if we have one). 407 if (io_state_ == STATE_IDLE) {
408 if (io_state_ != STATE_HALF_CLOSED_LOCAL) {
409 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, 408 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR,
410 "Response received before request sent"); 409 "Response received before request sent");
411 return ERR_SPDY_PROTOCOL_ERROR; 410 return ERR_SPDY_PROTOCOL_ERROR;
412 } 411 }
413 break; 412 break;
414 413
415 case SPDY_PUSH_STREAM: 414 case SPDY_PUSH_STREAM:
416 // Push streams transition to a locally half-closed state upon headers. 415 // Push streams transition to a locally half-closed state upon headers.
417 // We must continue to buffer data while waiting for a call to 416 // We must continue to buffer data while waiting for a call to
418 // SetDelegate() (which may not ever happen). 417 // SetDelegate() (which may not ever happen).
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, 477 LogStreamError(ERR_SPDY_PROTOCOL_ERROR,
479 "Data received with incomplete headers."); 478 "Data received with incomplete headers.");
480 session_->CloseActiveStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR); 479 session_->CloseActiveStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR);
481 return; 480 return;
482 } 481 }
483 482
484 CHECK(!IsClosed()); 483 CHECK(!IsClosed());
485 484
486 if (!buffer) { 485 if (!buffer) {
487 metrics_.StopStream(); 486 metrics_.StopStream();
488 // TODO(jgraettinger): Closing from OPEN preserves current SpdyStream 487 if (io_state_ == STATE_OPEN) {
489 // behavior, but is incorrect HTTP/2 behavior. |io_state_| should be 488 io_state_ = STATE_HALF_CLOSED_REMOTE;
490 // HALF_CLOSED_REMOTE. To be changed in a subsequent CL. 489 } else if (io_state_ == STATE_HALF_CLOSED_LOCAL) {
491 if (io_state_ == STATE_OPEN || io_state_ == STATE_HALF_CLOSED_LOCAL) {
492 io_state_ = STATE_CLOSED; 490 io_state_ = STATE_CLOSED;
493 // Deletes |this|. 491 // Deletes |this|.
494 session_->CloseActiveStream(stream_id_, OK); 492 session_->CloseActiveStream(stream_id_, OK);
495 return; 493 } else {
494 NOTREACHED() << io_state_;
496 } 495 }
497 NOTREACHED() << io_state_;
498 return; 496 return;
499 } 497 }
500 498
501 size_t length = buffer->GetRemainingSize(); 499 size_t length = buffer->GetRemainingSize();
502 DCHECK_LE(length, session_->GetDataFrameMaximumPayload()); 500 DCHECK_LE(length, session_->GetDataFrameMaximumPayload());
503 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) { 501 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) {
504 DecreaseRecvWindowSize(static_cast<int32>(length)); 502 DecreaseRecvWindowSize(static_cast<int32>(length));
505 buffer->AddConsumeCallback( 503 buffer->AddConsumeCallback(
506 base::Bind(&SpdyStream::OnReadBufferConsumed, GetWeakPtr())); 504 base::Bind(&SpdyStream::OnReadBufferConsumed, GetWeakPtr()));
507 } 505 }
(...skipping 20 matching lines...) Expand all
528 frame_type == DATA) << frame_type; 526 frame_type == DATA) << frame_type;
529 527
530 int result = (frame_type == SYN_STREAM) ? 528 int result = (frame_type == SYN_STREAM) ?
531 OnRequestHeadersSent() : OnDataSent(frame_size); 529 OnRequestHeadersSent() : OnDataSent(frame_size);
532 if (result == ERR_IO_PENDING) { 530 if (result == ERR_IO_PENDING) {
533 // The write operation hasn't completed yet. 531 // The write operation hasn't completed yet.
534 return; 532 return;
535 } 533 }
536 534
537 if (pending_send_status_ == NO_MORE_DATA_TO_SEND) { 535 if (pending_send_status_ == NO_MORE_DATA_TO_SEND) {
538 // TODO(jgraettinger): Once HALF_CLOSED_REMOTE is added, 536 if(io_state_ == STATE_OPEN) {
539 // we'll need to handle transitions to fully closed here. 537 io_state_ = STATE_HALF_CLOSED_LOCAL;
540 CHECK_EQ(io_state_, STATE_OPEN); 538 } else if(io_state_ == STATE_HALF_CLOSED_REMOTE) {
541 io_state_ = STATE_HALF_CLOSED_LOCAL; 539 io_state_ = STATE_CLOSED;
540 } else {
541 NOTREACHED() << io_state_;
542 }
542 } 543 }
543 544
544 // Notify delegate of write completion. May destroy |this|. 545 // Notify delegate of write completion. Must not destroy |this|.
Johnny 2014/02/14 00:07:08 This looks scary on the surface, but I mixed up th
Ryan Hamilton 2014/02/14 01:47:22 Makes sense. I wonder if we could have a member v
Johnny 2014/02/14 16:27:30 Sure. I've added a |weak_this| guard instead. Same
545 CHECK(delegate_); 546 CHECK(delegate_);
546 if (frame_type == SYN_STREAM) { 547 if (frame_type == SYN_STREAM) {
547 delegate_->OnRequestHeadersSent(); 548 delegate_->OnRequestHeadersSent();
548 } else { 549 } else {
549 delegate_->OnDataSent(); 550 delegate_->OnDataSent();
550 } 551 }
552
553 if (io_state_ == STATE_CLOSED) {
554 // Deletes |this|.
555 session_->CloseActiveStream(stream_id_, OK);
556 }
551 } 557 }
552 558
553 int SpdyStream::OnRequestHeadersSent() { 559 int SpdyStream::OnRequestHeadersSent() {
554 CHECK_EQ(io_state_, STATE_IDLE); 560 CHECK_EQ(io_state_, STATE_IDLE);
555 CHECK_NE(stream_id_, 0u); 561 CHECK_NE(stream_id_, 0u);
556 562
557 io_state_ = STATE_OPEN; 563 io_state_ = STATE_OPEN;
558 return OK; 564 return OK;
559 } 565 }
560 566
561 int SpdyStream::OnDataSent(size_t frame_size) { 567 int SpdyStream::OnDataSent(size_t frame_size) {
562 CHECK_EQ(io_state_, STATE_OPEN); 568 CHECK(io_state_ == STATE_OPEN ||
569 io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_;
563 570
564 size_t frame_payload_size = frame_size - session_->GetDataFrameMinimumSize(); 571 size_t frame_payload_size = frame_size - session_->GetDataFrameMinimumSize();
565 572
566 CHECK_GE(frame_size, session_->GetDataFrameMinimumSize()); 573 CHECK_GE(frame_size, session_->GetDataFrameMinimumSize());
567 CHECK_LE(frame_payload_size, session_->GetDataFrameMaximumPayload()); 574 CHECK_LE(frame_payload_size, session_->GetDataFrameMaximumPayload());
568 575
569 send_bytes_ += frame_payload_size; 576 send_bytes_ += frame_payload_size;
570 577
571 // If more data is available to send, dispatch it and 578 // If more data is available to send, dispatch it and
572 // return that the write operation is still ongoing. 579 // return that the write operation is still ongoing.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 scoped_ptr<SpdyBufferProducer>( 654 scoped_ptr<SpdyBufferProducer>(
648 new SynStreamBufferProducer(GetWeakPtr()))); 655 new SynStreamBufferProducer(GetWeakPtr())));
649 return ERR_IO_PENDING; 656 return ERR_IO_PENDING;
650 } 657 }
651 658
652 void SpdyStream::SendData(IOBuffer* data, 659 void SpdyStream::SendData(IOBuffer* data,
653 int length, 660 int length,
654 SpdySendStatus send_status) { 661 SpdySendStatus send_status) {
655 CHECK_NE(type_, SPDY_PUSH_STREAM); 662 CHECK_NE(type_, SPDY_PUSH_STREAM);
656 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); 663 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND);
657 CHECK_EQ(io_state_, STATE_OPEN); 664 CHECK(io_state_ == STATE_OPEN ||
665 io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_;
658 CHECK(!pending_send_data_.get()); 666 CHECK(!pending_send_data_.get());
659 pending_send_data_ = new DrainableIOBuffer(data, length); 667 pending_send_data_ = new DrainableIOBuffer(data, length);
660 pending_send_status_ = send_status; 668 pending_send_status_ = send_status;
661 QueueNextDataFrame(); 669 QueueNextDataFrame();
662 } 670 }
663 671
664 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, 672 bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info,
665 bool* was_npn_negotiated, 673 bool* was_npn_negotiated,
666 NextProto* protocol_negotiated) { 674 NextProto* protocol_negotiated) {
667 return session_->GetSSLInfo( 675 return session_->GetSSLInfo(
(...skipping 21 matching lines...) Expand all
689 bool SpdyStream::IsClosed() const { 697 bool SpdyStream::IsClosed() const {
690 return io_state_ == STATE_CLOSED; 698 return io_state_ == STATE_CLOSED;
691 } 699 }
692 700
693 bool SpdyStream::IsLocallyClosed() const { 701 bool SpdyStream::IsLocallyClosed() const {
694 return io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED || 702 return io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED ||
695 io_state_ == STATE_HALF_CLOSED_LOCAL || 703 io_state_ == STATE_HALF_CLOSED_LOCAL ||
696 io_state_ == STATE_CLOSED; 704 io_state_ == STATE_CLOSED;
697 } 705 }
698 706
699 bool SpdyStream::IsIdleTemporaryRename() const { 707 bool SpdyStream::IsIdle() const {
700 return io_state_ == STATE_IDLE; 708 return io_state_ == STATE_IDLE;
701 } 709 }
702 710
703 bool SpdyStream::IsOpen() const { 711 bool SpdyStream::IsOpen() const {
704 return io_state_ == STATE_OPEN; 712 return io_state_ == STATE_OPEN;
705 } 713 }
706 714
707 NextProto SpdyStream::GetProtocol() const { 715 NextProto SpdyStream::GetProtocol() const {
708 return session_->protocol(); 716 return session_->protocol();
709 } 717 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", 763 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime",
756 recv_last_byte_time_ - effective_send_time); 764 recv_last_byte_time_ - effective_send_time);
757 765
758 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); 766 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_);
759 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); 767 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_);
760 } 768 }
761 769
762 void SpdyStream::QueueNextDataFrame() { 770 void SpdyStream::QueueNextDataFrame() {
763 // Until the request has been completely sent, we cannot be sure 771 // Until the request has been completely sent, we cannot be sure
764 // that our stream_id is correct. 772 // that our stream_id is correct.
765 CHECK_EQ(io_state_, STATE_OPEN); 773 CHECK(io_state_ == STATE_OPEN ||
774 io_state_ == STATE_HALF_CLOSED_REMOTE) << io_state_;
766 CHECK_GT(stream_id_, 0u); 775 CHECK_GT(stream_id_, 0u);
767 CHECK(pending_send_data_.get()); 776 CHECK(pending_send_data_.get());
768 CHECK_GT(pending_send_data_->BytesRemaining(), 0); 777 CHECK_GT(pending_send_data_->BytesRemaining(), 0);
769 778
770 SpdyDataFlags flags = 779 SpdyDataFlags flags =
771 (pending_send_status_ == NO_MORE_DATA_TO_SEND) ? 780 (pending_send_status_ == NO_MORE_DATA_TO_SEND) ?
772 DATA_FLAG_FIN : DATA_FLAG_NONE; 781 DATA_FLAG_FIN : DATA_FLAG_NONE;
773 scoped_ptr<SpdyBuffer> data_buffer( 782 scoped_ptr<SpdyBuffer> data_buffer(
774 session_->CreateDataBuffer(stream_id_, 783 session_->CreateDataBuffer(stream_id_,
775 pending_send_data_.get(), 784 pending_send_data_.get(),
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, 883 description = base::StringPrintf("Unknown state 0x%08X (%u)", state,
875 state); 884 state);
876 break; 885 break;
877 } 886 }
878 return description; 887 return description;
879 } 888 }
880 889
881 #undef STATE_CASE 890 #undef STATE_CASE
882 891
883 } // namespace net 892 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/spdy/spdy_websocket_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698