| Index: net/quic/chromium/quic_chromium_client_stream.cc
|
| diff --git a/net/quic/chromium/quic_chromium_client_stream.cc b/net/quic/chromium/quic_chromium_client_stream.cc
|
| index 15f464319552aa981013686009b6eec174a61928..5eb505a382db4011e8ab0e6ed3bd9f794c365855 100644
|
| --- a/net/quic/chromium/quic_chromium_client_stream.cc
|
| +++ b/net/quic/chromium/quic_chromium_client_stream.cc
|
| @@ -21,13 +21,226 @@
|
|
|
| namespace net {
|
|
|
| +QuicChromiumClientStream::Handle::Handle(QuicChromiumClientStream* stream,
|
| + Delegate* delegate)
|
| + : stream_(stream), delegate_(delegate) {
|
| + SaveState();
|
| +}
|
| +
|
| +QuicChromiumClientStream::Handle::~Handle() {
|
| + if (stream_) {
|
| + stream_->ClearHandle();
|
| + // TODO(rch): If stream_ is still valid, it should probably be Reset()
|
| + // so that it does not leak.
|
| + // stream_->Reset(QUIC_STREAM_CANCELLED);
|
| + }
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::ClearDelegate() {
|
| + delegate_ = nullptr;
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::OnInitialHeadersAvailable(
|
| + const SpdyHeaderBlock& headers,
|
| + size_t frame_len) {
|
| + delegate_->OnInitialHeadersAvailable(headers, frame_len);
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::OnTrailingHeadersAvailable(
|
| + const SpdyHeaderBlock& headers,
|
| + size_t frame_len) {
|
| + delegate_->OnTrailingHeadersAvailable(headers, frame_len);
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::OnDataAvailable() {
|
| + delegate_->OnDataAvailable();
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::OnClose() {
|
| + if (stream_)
|
| + SaveState();
|
| + stream_ = nullptr;
|
| + if (delegate_) {
|
| + auto* delegate = delegate_;
|
| + delegate_ = nullptr;
|
| + delegate->OnClose();
|
| + }
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::OnError(int error) {
|
| + if (stream_)
|
| + SaveState();
|
| + stream_ = nullptr;
|
| + if (delegate_) {
|
| + auto* delegate = delegate_;
|
| + delegate_ = nullptr;
|
| + delegate->OnError(error);
|
| + }
|
| +}
|
| +
|
| +size_t QuicChromiumClientStream::Handle::WriteHeaders(
|
| + SpdyHeaderBlock header_block,
|
| + bool fin,
|
| + QuicReferenceCountedPointer<QuicAckListenerInterface>
|
| + ack_notifier_delegate) {
|
| + if (!stream_)
|
| + return 0;
|
| + return stream_->WriteHeaders(std::move(header_block), fin,
|
| + ack_notifier_delegate);
|
| +}
|
| +
|
| +int QuicChromiumClientStream::Handle::WriteStreamData(
|
| + base::StringPiece data,
|
| + bool fin,
|
| + const CompletionCallback& callback) {
|
| + if (!stream_)
|
| + return ERR_CONNECTION_CLOSED;
|
| + return stream_->WriteStreamData(data, fin, callback);
|
| +}
|
| +
|
| +int QuicChromiumClientStream::Handle::WritevStreamData(
|
| + const std::vector<scoped_refptr<IOBuffer>>& buffers,
|
| + const std::vector<int>& lengths,
|
| + bool fin,
|
| + const CompletionCallback& callback) {
|
| + if (!stream_)
|
| + return ERR_CONNECTION_CLOSED;
|
| + return stream_->WritevStreamData(buffers, lengths, fin, callback);
|
| +}
|
| +
|
| +int QuicChromiumClientStream::Handle::Read(IOBuffer* buf, int buf_len) {
|
| + if (!stream_)
|
| + return ERR_CONNECTION_CLOSED;
|
| + return stream_->Read(buf, buf_len);
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::OnFinRead() {
|
| + if (stream_)
|
| + stream_->OnFinRead();
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::DisableConnectionMigration() {
|
| + if (stream_)
|
| + stream_->DisableConnectionMigration();
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::SetPriority(SpdyPriority priority) {
|
| + if (stream_)
|
| + stream_->SetPriority(priority);
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::Reset(
|
| + QuicRstStreamErrorCode error_code) {
|
| + if (stream_)
|
| + stream_->Reset(error_code);
|
| +}
|
| +
|
| +QuicStreamId QuicChromiumClientStream::Handle::id() const {
|
| + if (!stream_)
|
| + return id_;
|
| + return stream_->id();
|
| +}
|
| +
|
| +QuicErrorCode QuicChromiumClientStream::Handle::connection_error() const {
|
| + if (!stream_)
|
| + return connection_error_;
|
| + return stream_->connection_error();
|
| +}
|
| +
|
| +QuicRstStreamErrorCode QuicChromiumClientStream::Handle::stream_error() const {
|
| + if (!stream_)
|
| + return stream_error_;
|
| + return stream_->stream_error();
|
| +}
|
| +
|
| +bool QuicChromiumClientStream::Handle::fin_sent() const {
|
| + if (!stream_)
|
| + return fin_sent_;
|
| + return stream_->fin_sent();
|
| +}
|
| +
|
| +bool QuicChromiumClientStream::Handle::fin_received() const {
|
| + if (!stream_)
|
| + return fin_received_;
|
| + return stream_->fin_received();
|
| +}
|
| +
|
| +uint64_t QuicChromiumClientStream::Handle::stream_bytes_read() const {
|
| + if (!stream_)
|
| + return stream_bytes_read_;
|
| + return stream_->stream_bytes_read();
|
| +}
|
| +
|
| +uint64_t QuicChromiumClientStream::Handle::stream_bytes_written() const {
|
| + if (!stream_)
|
| + return stream_bytes_written_;
|
| + return stream_->stream_bytes_written();
|
| +}
|
| +
|
| +size_t QuicChromiumClientStream::Handle::NumBytesConsumed() const {
|
| + if (!stream_)
|
| + return num_bytes_consumed_;
|
| + return stream_->sequencer()->NumBytesConsumed();
|
| +}
|
| +
|
| +bool QuicChromiumClientStream::Handle::IsDoneReading() const {
|
| + if (!stream_)
|
| + return is_done_reading_;
|
| + return stream_->IsDoneReading();
|
| +}
|
| +
|
| +bool QuicChromiumClientStream::Handle::IsFirstStream() const {
|
| + if (!stream_)
|
| + return is_first_stream_;
|
| + return stream_->IsFirstStream();
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::OnPromiseHeaderList(
|
| + QuicStreamId promised_id,
|
| + size_t frame_len,
|
| + const QuicHeaderList& header_list) {
|
| + stream_->OnPromiseHeaderList(promised_id, frame_len, header_list);
|
| +}
|
| +
|
| +SpdyPriority QuicChromiumClientStream::Handle::priority() const {
|
| + if (!stream_)
|
| + return priority_;
|
| + return stream_->priority();
|
| +}
|
| +
|
| +bool QuicChromiumClientStream::Handle::can_migrate() {
|
| + if (!stream_)
|
| + return false;
|
| + return stream_->can_migrate();
|
| +}
|
| +
|
| +QuicChromiumClientStream::Delegate*
|
| +QuicChromiumClientStream::Handle::GetDelegate() {
|
| + return delegate_;
|
| +}
|
| +
|
| +void QuicChromiumClientStream::Handle::SaveState() {
|
| + DCHECK(stream_);
|
| + fin_sent_ = stream_->fin_sent();
|
| + fin_received_ = stream_->fin_received();
|
| + num_bytes_consumed_ = stream_->sequencer()->NumBytesConsumed();
|
| + id_ = stream_->id();
|
| + connection_error_ = stream_->connection_error();
|
| + stream_error_ = stream_->stream_error();
|
| + is_done_reading_ = stream_->IsDoneReading();
|
| + is_first_stream_ = stream_->IsFirstStream();
|
| + stream_bytes_read_ = stream_->stream_bytes_read();
|
| + stream_bytes_written_ = stream_->stream_bytes_written();
|
| + priority_ = stream_->priority();
|
| +}
|
| +
|
| QuicChromiumClientStream::QuicChromiumClientStream(
|
| QuicStreamId id,
|
| QuicClientSessionBase* session,
|
| const NetLogWithSource& net_log)
|
| : QuicSpdyStream(id, session),
|
| net_log_(net_log),
|
| - delegate_(nullptr),
|
| + handle_(nullptr),
|
| headers_delivered_(false),
|
| initial_headers_sent_(false),
|
| session_(session),
|
| @@ -36,8 +249,8 @@ QuicChromiumClientStream::QuicChromiumClientStream(
|
| weak_factory_(this) {}
|
|
|
| QuicChromiumClientStream::~QuicChromiumClientStream() {
|
| - if (delegate_)
|
| - delegate_->OnClose();
|
| + if (handle_)
|
| + handle_->OnClose();
|
| }
|
|
|
| void QuicChromiumClientStream::OnInitialHeadersComplete(
|
| @@ -58,14 +271,14 @@ void QuicChromiumClientStream::OnInitialHeadersComplete(
|
| ConsumeHeaderList();
|
| session_->OnInitialHeadersComplete(id(), header_block);
|
|
|
| - if (delegate_) {
|
| - // The delegate will receive the headers via a posted task.
|
| - NotifyDelegateOfInitialHeadersAvailableLater(std::move(header_block),
|
| - frame_len);
|
| + if (handle_) {
|
| + // The handle will receive the headers via a posted task.
|
| + NotifyHandleOfInitialHeadersAvailableLater(std::move(header_block),
|
| + frame_len);
|
| return;
|
| }
|
|
|
| - // Buffer the headers and deliver them when the delegate arrives.
|
| + // Buffer the headers and deliver them when the handle arrives.
|
| initial_headers_ = std::move(header_block);
|
| initial_headers_frame_len_ = frame_len;
|
| }
|
| @@ -75,8 +288,8 @@ void QuicChromiumClientStream::OnTrailingHeadersComplete(
|
| size_t frame_len,
|
| const QuicHeaderList& header_list) {
|
| QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
|
| - NotifyDelegateOfTrailingHeadersAvailableLater(received_trailers().Clone(),
|
| - frame_len);
|
| + NotifyHandleOfTrailingHeadersAvailableLater(received_trailers().Clone(),
|
| + frame_len);
|
| }
|
|
|
| void QuicChromiumClientStream::OnPromiseHeaderList(
|
| @@ -109,16 +322,16 @@ void QuicChromiumClientStream::OnDataAvailable() {
|
| return;
|
| }
|
|
|
| - // The delegate will read the data via a posted task, and
|
| + // The handle will read the data via a posted task, and
|
| // will be able to, potentially, read all data which has queued up.
|
| - if (delegate_)
|
| - NotifyDelegateOfDataAvailableLater();
|
| + if (handle_)
|
| + NotifyHandleOfDataAvailableLater();
|
| }
|
|
|
| void QuicChromiumClientStream::OnClose() {
|
| - if (delegate_) {
|
| - delegate_->OnClose();
|
| - delegate_ = nullptr;
|
| + if (handle_) {
|
| + handle_->OnClose();
|
| + handle_ = nullptr;
|
| }
|
| QuicStream::OnClose();
|
| }
|
| @@ -192,25 +405,32 @@ int QuicChromiumClientStream::WritevStreamData(
|
| return ERR_IO_PENDING;
|
| }
|
|
|
| -void QuicChromiumClientStream::SetDelegate(
|
| +std::unique_ptr<QuicChromiumClientStream::Handle>
|
| +QuicChromiumClientStream::CreateHandle(
|
| QuicChromiumClientStream::Delegate* delegate) {
|
| - DCHECK(!(delegate_ && delegate));
|
| - delegate_ = delegate;
|
| - if (delegate == nullptr)
|
| - return;
|
| + DCHECK(!handle_);
|
| + auto handle = std::unique_ptr<QuicChromiumClientStream::Handle>(
|
| + new QuicChromiumClientStream::Handle(this, delegate));
|
| + handle_ = handle.get();
|
|
|
| // Should this perhaps be via PostTask to make reasoning simpler?
|
| if (!initial_headers_.empty()) {
|
| - delegate_->OnInitialHeadersAvailable(std::move(initial_headers_),
|
| - initial_headers_frame_len_);
|
| + handle_->OnInitialHeadersAvailable(std::move(initial_headers_),
|
| + initial_headers_frame_len_);
|
| }
|
| +
|
| + return handle;
|
| +}
|
| +
|
| +void QuicChromiumClientStream::ClearHandle() {
|
| + handle_ = nullptr;
|
| }
|
|
|
| void QuicChromiumClientStream::OnError(int error) {
|
| - if (delegate_) {
|
| - QuicChromiumClientStream::Delegate* delegate = delegate_;
|
| - delegate_ = nullptr;
|
| - delegate->OnError(error);
|
| + if (handle_) {
|
| + QuicChromiumClientStream::Handle* handle = handle_;
|
| + handle_ = nullptr;
|
| + handle->OnError(error);
|
| }
|
| }
|
|
|
| @@ -230,22 +450,22 @@ int QuicChromiumClientStream::Read(IOBuffer* buf, int buf_len) {
|
| return bytes_read;
|
| }
|
|
|
| -void QuicChromiumClientStream::NotifyDelegateOfInitialHeadersAvailableLater(
|
| +void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailableLater(
|
| SpdyHeaderBlock headers,
|
| size_t frame_len) {
|
| - DCHECK(delegate_);
|
| + DCHECK(handle_);
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| - &QuicChromiumClientStream::NotifyDelegateOfInitialHeadersAvailable,
|
| + &QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable,
|
| weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)),
|
| frame_len));
|
| }
|
|
|
| -void QuicChromiumClientStream::NotifyDelegateOfInitialHeadersAvailable(
|
| +void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable(
|
| SpdyHeaderBlock headers,
|
| size_t frame_len) {
|
| - if (!delegate_)
|
| + if (!handle_)
|
| return;
|
|
|
| DCHECK(!headers_delivered_);
|
| @@ -254,50 +474,50 @@ void QuicChromiumClientStream::NotifyDelegateOfInitialHeadersAvailable(
|
| NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS,
|
| base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
|
|
|
| - delegate_->OnInitialHeadersAvailable(headers, frame_len);
|
| + handle_->OnInitialHeadersAvailable(headers, frame_len);
|
| }
|
|
|
| -void QuicChromiumClientStream::NotifyDelegateOfTrailingHeadersAvailableLater(
|
| +void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailableLater(
|
| SpdyHeaderBlock headers,
|
| size_t frame_len) {
|
| - DCHECK(delegate_);
|
| + DCHECK(handle_);
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE,
|
| base::Bind(
|
| - &QuicChromiumClientStream::NotifyDelegateOfTrailingHeadersAvailable,
|
| + &QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable,
|
| weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)),
|
| frame_len));
|
| }
|
|
|
| -void QuicChromiumClientStream::NotifyDelegateOfTrailingHeadersAvailable(
|
| +void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable(
|
| SpdyHeaderBlock headers,
|
| size_t frame_len) {
|
| - if (!delegate_)
|
| + if (!handle_)
|
| return;
|
|
|
| DCHECK(headers_delivered_);
|
| // Only mark trailers consumed when we are about to notify delegate.
|
| MarkTrailersConsumed();
|
| // Post an async task to notify delegate of the FIN flag.
|
| - NotifyDelegateOfDataAvailableLater();
|
| + NotifyHandleOfDataAvailableLater();
|
| net_log_.AddEvent(
|
| NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS,
|
| base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
|
|
|
| - delegate_->OnTrailingHeadersAvailable(headers, frame_len);
|
| + handle_->OnTrailingHeadersAvailable(headers, frame_len);
|
| }
|
|
|
| -void QuicChromiumClientStream::NotifyDelegateOfDataAvailableLater() {
|
| - DCHECK(delegate_);
|
| +void QuicChromiumClientStream::NotifyHandleOfDataAvailableLater() {
|
| + DCHECK(handle_);
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&QuicChromiumClientStream::NotifyDelegateOfDataAvailable,
|
| + base::Bind(&QuicChromiumClientStream::NotifyHandleOfDataAvailable,
|
| weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| -void QuicChromiumClientStream::NotifyDelegateOfDataAvailable() {
|
| - if (delegate_)
|
| - delegate_->OnDataAvailable();
|
| +void QuicChromiumClientStream::NotifyHandleOfDataAvailable() {
|
| + if (handle_)
|
| + handle_->OnDataAvailable();
|
| }
|
|
|
| void QuicChromiumClientStream::DisableConnectionMigration() {
|
|
|