Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/quic/chromium/bidirectional_stream_quic_impl.h" | 5 #include "net/quic/chromium/bidirectional_stream_quic_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 return; | 73 return; |
| 74 | 74 |
| 75 if (rv == OK) { | 75 if (rv == OK) { |
| 76 OnStreamReady(rv); | 76 OnStreamReady(rv); |
| 77 } else if (!session_->IsCryptoHandshakeConfirmed()) { | 77 } else if (!session_->IsCryptoHandshakeConfirmed()) { |
| 78 NotifyError(ERR_QUIC_HANDSHAKE_FAILED); | 78 NotifyError(ERR_QUIC_HANDSHAKE_FAILED); |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| 82 void BidirectionalStreamQuicImpl::SendRequestHeaders() { | 82 void BidirectionalStreamQuicImpl::SendRequestHeaders() { |
| 83 WriteHeaders(); | |
| 84 } | |
| 85 | |
| 86 bool BidirectionalStreamQuicImpl::WriteHeaders() { | |
| 83 DCHECK(!has_sent_headers_); | 87 DCHECK(!has_sent_headers_); |
| 84 if (!stream_) { | 88 if (!stream_) { |
| 85 LOG(ERROR) | 89 LOG(ERROR) |
| 86 << "Trying to send request headers after stream has been destroyed."; | 90 << "Trying to send request headers after stream has been destroyed."; |
| 87 base::ThreadTaskRunnerHandle::Get()->PostTask( | 91 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 88 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | 92 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, |
| 89 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | 93 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
| 90 return; | 94 return false; |
| 91 } | 95 } |
| 92 | 96 |
| 93 SpdyHeaderBlock headers; | 97 SpdyHeaderBlock headers; |
| 94 HttpRequestInfo http_request_info; | 98 HttpRequestInfo http_request_info; |
| 95 http_request_info.url = request_info_->url; | 99 http_request_info.url = request_info_->url; |
| 96 http_request_info.method = request_info_->method; | 100 http_request_info.method = request_info_->method; |
| 97 http_request_info.extra_headers = request_info_->extra_headers; | 101 http_request_info.extra_headers = request_info_->extra_headers; |
| 98 | 102 |
| 99 CreateSpdyHeadersFromHttpRequest( | 103 CreateSpdyHeadersFromHttpRequest( |
| 100 http_request_info, http_request_info.extra_headers, true, &headers); | 104 http_request_info, http_request_info.extra_headers, true, &headers); |
| 101 // Sending the request might result in |this| being deleted. | 105 // Sending the request might result in |this| being deleted. |
| 102 auto guard = weak_factory_.GetWeakPtr(); | 106 auto guard = weak_factory_.GetWeakPtr(); |
| 103 size_t headers_bytes_sent = stream_->WriteHeaders( | 107 size_t headers_bytes_sent = stream_->WriteHeaders( |
| 104 std::move(headers), request_info_->end_stream_on_headers, nullptr); | 108 std::move(headers), request_info_->end_stream_on_headers, nullptr); |
|
Ryan Hamilton
2017/06/01 00:45:33
If this fails synchronously, then the stream will
| |
| 105 if (!guard.get()) | 109 if (!guard.get()) |
| 106 return; | 110 return false; |
| 111 | |
| 107 headers_bytes_sent_ += headers_bytes_sent; | 112 headers_bytes_sent_ += headers_bytes_sent; |
| 108 has_sent_headers_ = true; | 113 has_sent_headers_ = true; |
| 114 return true; | |
| 109 } | 115 } |
| 110 | 116 |
| 111 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) { | 117 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) { |
| 112 DCHECK(buffer); | 118 DCHECK(buffer); |
| 113 DCHECK(buffer_len); | 119 DCHECK(buffer_len); |
| 114 | 120 |
| 115 if (!stream_) { | 121 if (!stream_) { |
| 116 // If the stream is already closed, there is no body to read. | 122 // If the stream is already closed, there is no body to read. |
| 117 return response_status_; | 123 return response_status_; |
| 118 } | 124 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 149 return; | 155 return; |
| 150 } | 156 } |
| 151 | 157 |
| 152 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler; | 158 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler; |
| 153 if (!has_sent_headers_) { | 159 if (!has_sent_headers_) { |
| 154 DCHECK(!send_request_headers_automatically_); | 160 DCHECK(!send_request_headers_automatically_); |
| 155 // Creates a bundler only if there are headers to be sent along with the | 161 // Creates a bundler only if there are headers to be sent along with the |
| 156 // single data buffer. | 162 // single data buffer. |
| 157 bundler = | 163 bundler = |
| 158 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING); | 164 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING); |
| 159 SendRequestHeaders(); | 165 // Sending the request might result in |this| being deleted. |
| 166 if (!WriteHeaders()) | |
| 167 return; | |
| 160 } | 168 } |
| 161 | 169 |
| 162 QuicStringPiece string_data(data->data(), length); | 170 QuicStringPiece string_data(data->data(), length); |
| 163 int rv = stream_->WriteStreamData( | 171 int rv = stream_->WriteStreamData( |
| 164 string_data, end_stream, | 172 string_data, end_stream, |
| 165 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, | 173 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, |
| 166 weak_factory_.GetWeakPtr())); | 174 weak_factory_.GetWeakPtr())); |
| 167 DCHECK(rv == OK || rv == ERR_IO_PENDING); | 175 DCHECK(rv == OK || rv == ERR_IO_PENDING); |
| 168 if (rv == OK) { | 176 if (rv == OK) { |
| 169 base::ThreadTaskRunnerHandle::Get()->PostTask( | 177 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 183 base::ThreadTaskRunnerHandle::Get()->PostTask( | 191 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 184 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | 192 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, |
| 185 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | 193 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
| 186 return; | 194 return; |
| 187 } | 195 } |
| 188 | 196 |
| 189 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler( | 197 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler( |
| 190 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING)); | 198 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING)); |
| 191 if (!has_sent_headers_) { | 199 if (!has_sent_headers_) { |
| 192 DCHECK(!send_request_headers_automatically_); | 200 DCHECK(!send_request_headers_automatically_); |
| 193 SendRequestHeaders(); | 201 // Sending the request might result in |this| being deleted. |
| 202 if (!WriteHeaders()) | |
| 203 return; | |
| 194 } | 204 } |
| 195 | 205 |
| 196 int rv = stream_->WritevStreamData( | 206 int rv = stream_->WritevStreamData( |
| 197 buffers, lengths, end_stream, | 207 buffers, lengths, end_stream, |
| 198 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, | 208 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, |
| 199 weak_factory_.GetWeakPtr())); | 209 weak_factory_.GetWeakPtr())); |
| 200 | 210 |
| 201 DCHECK(rv == OK || rv == ERR_IO_PENDING); | 211 DCHECK(rv == OK || rv == ERR_IO_PENDING); |
| 202 if (rv == OK) { | 212 if (rv == OK) { |
| 203 base::ThreadTaskRunnerHandle::Get()->PostTask( | 213 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 BidirectionalStreamImpl::Delegate* delegate = delegate_; | 376 BidirectionalStreamImpl::Delegate* delegate = delegate_; |
| 367 delegate_ = nullptr; | 377 delegate_ = nullptr; |
| 368 // Cancel any pending callback. | 378 // Cancel any pending callback. |
| 369 weak_factory_.InvalidateWeakPtrs(); | 379 weak_factory_.InvalidateWeakPtrs(); |
| 370 delegate->OnFailed(error); | 380 delegate->OnFailed(error); |
| 371 // |this| might be destroyed at this point. | 381 // |this| might be destroyed at this point. |
| 372 } | 382 } |
| 373 } | 383 } |
| 374 | 384 |
| 375 void BidirectionalStreamQuicImpl::NotifyStreamReady() { | 385 void BidirectionalStreamQuicImpl::NotifyStreamReady() { |
| 376 if (send_request_headers_automatically_) { | 386 // Sending the request might result in |this| being deleted. |
| 377 // Sending the request might result in |this| being deleted. | 387 if (send_request_headers_automatically_ && !WriteHeaders()) |
| 378 auto guard = weak_factory_.GetWeakPtr(); | 388 return; |
| 379 SendRequestHeaders(); | 389 |
| 380 if (!guard.get()) | |
| 381 return; | |
| 382 } | |
| 383 if (delegate_) | 390 if (delegate_) |
| 384 delegate_->OnStreamReady(has_sent_headers_); | 391 delegate_->OnStreamReady(has_sent_headers_); |
| 385 } | 392 } |
| 386 | 393 |
| 387 void BidirectionalStreamQuicImpl::ResetStream() { | 394 void BidirectionalStreamQuicImpl::ResetStream() { |
| 388 if (!stream_) | 395 if (!stream_) |
| 389 return; | 396 return; |
| 390 closed_stream_received_bytes_ = stream_->stream_bytes_read(); | 397 closed_stream_received_bytes_ = stream_->stream_bytes_read(); |
| 391 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); | 398 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); |
| 392 closed_is_first_stream_ = stream_->IsFirstStream(); | 399 closed_is_first_stream_ = stream_->IsFirstStream(); |
| 393 stream_->ClearDelegate(); | 400 stream_->ClearDelegate(); |
| 394 stream_ = nullptr; | 401 stream_ = nullptr; |
| 395 } | 402 } |
| 396 | 403 |
| 397 } // namespace net | 404 } // namespace net |
| OLD | NEW |