| Index: net/quic/chromium/bidirectional_stream_quic_impl.cc
|
| diff --git a/net/quic/chromium/bidirectional_stream_quic_impl.cc b/net/quic/chromium/bidirectional_stream_quic_impl.cc
|
| index 28f49d938d743d7f8eb2f338f95b659c106d0f22..c10720d565bf796168f59339ecafcdaf9273ae0d 100644
|
| --- a/net/quic/chromium/bidirectional_stream_quic_impl.cc
|
| +++ b/net/quic/chromium/bidirectional_stream_quic_impl.cc
|
| @@ -102,21 +102,16 @@ void BidirectionalStreamQuicImpl::Start(
|
|
|
| void BidirectionalStreamQuicImpl::SendRequestHeaders() {
|
| ScopedBoolSaver saver(&may_invoke_callbacks_, false);
|
| - // If this fails, a task will have been posted to notify the delegate
|
| - // asynchronously.
|
| - WriteHeaders();
|
| -}
|
| -
|
| -bool BidirectionalStreamQuicImpl::WriteHeaders() {
|
| - DCHECK(!has_sent_headers_);
|
| - if (!stream_) {
|
| - LOG(ERROR)
|
| - << "Trying to send request headers after stream has been destroyed.";
|
| + int rv = WriteHeaders();
|
| + if (rv < 0) {
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
|
| - weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
|
| - return false;
|
| + weak_factory_.GetWeakPtr(), rv));
|
| }
|
| +}
|
| +
|
| +int BidirectionalStreamQuicImpl::WriteHeaders() {
|
| + DCHECK(!has_sent_headers_);
|
|
|
| SpdyHeaderBlock headers;
|
| HttpRequestInfo http_request_info;
|
| @@ -126,17 +121,13 @@ bool BidirectionalStreamQuicImpl::WriteHeaders() {
|
|
|
| CreateSpdyHeadersFromHttpRequest(
|
| http_request_info, http_request_info.extra_headers, true, &headers);
|
| - // Sending the request might result in the stream being closed via OnClose
|
| - // which will post a task to notify the delegate asynchronously.
|
| - // TODO(rch): Clean up this interface when OnClose and OnError are removed.
|
| - size_t headers_bytes_sent = stream_->WriteHeaders(
|
| - std::move(headers), request_info_->end_stream_on_headers, nullptr);
|
| - if (!stream_)
|
| - return false;
|
| -
|
| - headers_bytes_sent_ += headers_bytes_sent;
|
| - has_sent_headers_ = true;
|
| - return true;
|
| + int rv = stream_->WriteHeaders(std::move(headers),
|
| + request_info_->end_stream_on_headers, nullptr);
|
| + if (rv >= 0) {
|
| + headers_bytes_sent_ += rv;
|
| + has_sent_headers_ = true;
|
| + }
|
| + return rv;
|
| }
|
|
|
| int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) {
|
| @@ -144,10 +135,6 @@ int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) {
|
| DCHECK(buffer);
|
| DCHECK(buffer_len);
|
|
|
| - if (!stream_) {
|
| - // If the stream is already closed, there is no body to read.
|
| - return response_status_;
|
| - }
|
| int rv = stream_->ReadBody(
|
| buffer, buffer_len,
|
| base::Bind(&BidirectionalStreamQuicImpl::OnReadDataComplete,
|
| @@ -161,11 +148,11 @@ int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) {
|
| if (rv < 0)
|
| return rv;
|
|
|
| - if (stream_->IsDoneReading()) {
|
| - // If the write side is closed, OnFinRead() will call
|
| - // BidirectionalStreamQuicImpl::OnClose().
|
| + // If the write side is closed, OnFinRead() will call
|
| + // BidirectionalStreamQuicImpl::OnClose().
|
| + if (stream_->IsDoneReading())
|
| stream_->OnFinRead();
|
| - }
|
| +
|
| return rv;
|
| }
|
|
|
| @@ -176,8 +163,8 @@ void BidirectionalStreamQuicImpl::SendvData(
|
| ScopedBoolSaver saver(&may_invoke_callbacks_, false);
|
| DCHECK_EQ(buffers.size(), lengths.size());
|
|
|
| - if (!stream_) {
|
| - LOG(ERROR) << "Trying to send data after stream has been destroyed.";
|
| + if (!stream_->IsOpen()) {
|
| + LOG(ERROR) << "Trying to send data after stream has been closed.";
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
|
| weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
|
| @@ -188,9 +175,13 @@ void BidirectionalStreamQuicImpl::SendvData(
|
| session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING));
|
| if (!has_sent_headers_) {
|
| DCHECK(!send_request_headers_automatically_);
|
| - // Sending the request might result in the stream being closed.
|
| - if (!WriteHeaders())
|
| + int rv = WriteHeaders();
|
| + if (rv < 0) {
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
|
| + weak_factory_.GetWeakPtr(), rv));
|
| return;
|
| + }
|
| }
|
|
|
| int rv = stream_->WritevStreamData(
|
| @@ -198,11 +189,10 @@ void BidirectionalStreamQuicImpl::SendvData(
|
| base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
|
| weak_factory_.GetWeakPtr()));
|
|
|
| - DCHECK(rv == OK || rv == ERR_IO_PENDING);
|
| - if (rv == OK) {
|
| + if (rv != ERR_IO_PENDING) {
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete,
|
| - weak_factory_.GetWeakPtr(), OK));
|
| + weak_factory_.GetWeakPtr(), rv));
|
| }
|
| }
|
|
|
| @@ -236,42 +226,15 @@ bool BidirectionalStreamQuicImpl::GetLoadTimingInfo(
|
| return true;
|
| }
|
|
|
| -void BidirectionalStreamQuicImpl::OnClose() {
|
| - DCHECK(stream_);
|
| -
|
| - if (stream_->connection_error() != QUIC_NO_ERROR ||
|
| - stream_->stream_error() != QUIC_STREAM_NO_ERROR) {
|
| - OnError(session_->IsCryptoHandshakeConfirmed() ? ERR_QUIC_PROTOCOL_ERROR
|
| - : ERR_QUIC_HANDSHAKE_FAILED);
|
| - return;
|
| - }
|
| -
|
| - if (!stream_->fin_sent() || !stream_->fin_received()) {
|
| - // The connection must have been closed by the peer with QUIC_NO_ERROR,
|
| - // which is improper.
|
| - OnError(ERR_UNEXPECTED);
|
| - return;
|
| - }
|
| -
|
| - // The connection was closed normally so there is no need to notify
|
| - // the delegate.
|
| - ResetStream();
|
| -}
|
| -
|
| -void BidirectionalStreamQuicImpl::OnError(int error) {
|
| - // Avoid reentrancy by notifying the delegate asynchronously.
|
| - NotifyErrorImpl(error, /*notify_delegate_later*/ true);
|
| -}
|
| -
|
| void BidirectionalStreamQuicImpl::OnStreamReady(int rv) {
|
| DCHECK_NE(ERR_IO_PENDING, rv);
|
| - DCHECK(rv == OK || !stream_);
|
| + DCHECK(!stream_);
|
| if (rv != OK) {
|
| NotifyError(rv);
|
| return;
|
| }
|
|
|
| - stream_ = session_->ReleaseStream(this);
|
| + stream_ = session_->ReleaseStream();
|
|
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::ReadInitialHeaders,
|
| @@ -282,8 +245,8 @@ void BidirectionalStreamQuicImpl::OnStreamReady(int rv) {
|
|
|
| void BidirectionalStreamQuicImpl::OnSendDataComplete(int rv) {
|
| CHECK(may_invoke_callbacks_);
|
| - DCHECK(rv == OK || !stream_);
|
| - if (rv != 0) {
|
| + DCHECK_NE(ERR_IO_PENDING, rv);
|
| + if (rv < 0) {
|
| NotifyError(rv);
|
| return;
|
| }
|
| @@ -346,17 +309,21 @@ void BidirectionalStreamQuicImpl::OnReadTrailingHeadersComplete(int rv) {
|
|
|
| void BidirectionalStreamQuicImpl::OnReadDataComplete(int rv) {
|
| CHECK(may_invoke_callbacks_);
|
| - DCHECK_GE(rv, 0);
|
| +
|
| read_buffer_ = nullptr;
|
| read_buffer_len_ = 0;
|
|
|
| - if (stream_->IsDoneReading()) {
|
| - // If the write side is closed, OnFinRead() will call
|
| - // BidirectionalStreamQuicImpl::OnClose().
|
| + // If the write side is closed, OnFinRead() will call
|
| + // BidirectionalStreamQuicImpl::OnClose().
|
| + if (stream_->IsDoneReading())
|
| stream_->OnFinRead();
|
| - }
|
|
|
| - if (delegate_)
|
| + if (!delegate_)
|
| + return;
|
| +
|
| + if (rv < 0)
|
| + NotifyError(rv);
|
| + else
|
| delegate_->OnDataRead(rv);
|
| }
|
|
|
| @@ -397,9 +364,15 @@ void BidirectionalStreamQuicImpl::NotifyFailure(
|
|
|
| void BidirectionalStreamQuicImpl::NotifyStreamReady() {
|
| CHECK(may_invoke_callbacks_);
|
| - // Sending the request might result in the stream being closed.
|
| - if (send_request_headers_automatically_ && !WriteHeaders())
|
| - return;
|
| + if (send_request_headers_automatically_) {
|
| + int rv = WriteHeaders();
|
| + if (rv < 0) {
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError,
|
| + weak_factory_.GetWeakPtr(), rv));
|
| + return;
|
| + }
|
| + }
|
|
|
| if (delegate_)
|
| delegate_->OnStreamReady(has_sent_headers_);
|
| @@ -411,8 +384,6 @@ void BidirectionalStreamQuicImpl::ResetStream() {
|
| closed_stream_received_bytes_ = stream_->stream_bytes_read();
|
| closed_stream_sent_bytes_ = stream_->stream_bytes_written();
|
| closed_is_first_stream_ = stream_->IsFirstStream();
|
| - stream_->ClearDelegate();
|
| - stream_ = nullptr;
|
| }
|
|
|
| } // namespace net
|
|
|