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 26 matching lines...) Expand all Loading... | |
| 37 } // namespace | 37 } // namespace |
| 38 | 38 |
| 39 BidirectionalStreamQuicImpl::BidirectionalStreamQuicImpl( | 39 BidirectionalStreamQuicImpl::BidirectionalStreamQuicImpl( |
| 40 std::unique_ptr<QuicChromiumClientSession::Handle> session) | 40 std::unique_ptr<QuicChromiumClientSession::Handle> session) |
| 41 : session_(std::move(session)), | 41 : session_(std::move(session)), |
| 42 stream_(nullptr), | 42 stream_(nullptr), |
| 43 request_info_(nullptr), | 43 request_info_(nullptr), |
| 44 delegate_(nullptr), | 44 delegate_(nullptr), |
| 45 response_status_(OK), | 45 response_status_(OK), |
| 46 negotiated_protocol_(kProtoUnknown), | 46 negotiated_protocol_(kProtoUnknown), |
| 47 expect_trailers_(true), | |
| 47 read_buffer_len_(0), | 48 read_buffer_len_(0), |
| 48 headers_bytes_received_(0), | 49 headers_bytes_received_(0), |
| 49 headers_bytes_sent_(0), | 50 headers_bytes_sent_(0), |
| 50 closed_stream_received_bytes_(0), | 51 closed_stream_received_bytes_(0), |
| 51 closed_stream_sent_bytes_(0), | 52 closed_stream_sent_bytes_(0), |
| 52 closed_is_first_stream_(false), | 53 closed_is_first_stream_(false), |
| 53 has_sent_headers_(false), | 54 has_sent_headers_(false), |
| 54 send_request_headers_automatically_(true), | 55 send_request_headers_automatically_(true), |
| 55 may_invoke_callbacks_(true), | 56 may_invoke_callbacks_(true), |
| 56 weak_factory_(this) {} | 57 weak_factory_(this) {} |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 return; | 96 return; |
| 96 } | 97 } |
| 97 | 98 |
| 98 base::ThreadTaskRunnerHandle::Get()->PostTask( | 99 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 99 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnStreamReady, | 100 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnStreamReady, |
| 100 weak_factory_.GetWeakPtr(), rv)); | 101 weak_factory_.GetWeakPtr(), rv)); |
| 101 } | 102 } |
| 102 | 103 |
| 103 void BidirectionalStreamQuicImpl::SendRequestHeaders() { | 104 void BidirectionalStreamQuicImpl::SendRequestHeaders() { |
| 104 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | 105 ScopedBoolSaver saver(&may_invoke_callbacks_, false); |
| 105 // If this fails, a task will have been posted to notify the delegate | 106 int rv = WriteHeaders(); |
| 106 // asynchronously. | 107 if (rv < 0) { |
| 107 WriteHeaders(); | 108 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 109 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | |
| 110 weak_factory_.GetWeakPtr(), rv)); | |
| 111 } | |
| 108 } | 112 } |
| 109 | 113 |
| 110 bool BidirectionalStreamQuicImpl::WriteHeaders() { | 114 int BidirectionalStreamQuicImpl::WriteHeaders() { |
| 111 DCHECK(!has_sent_headers_); | 115 DCHECK(!has_sent_headers_); |
| 112 if (!stream_) { | |
| 113 LOG(ERROR) | |
| 114 << "Trying to send request headers after stream has been destroyed."; | |
| 115 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 116 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | |
| 117 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | |
| 118 return false; | |
| 119 } | |
| 120 | 116 |
| 121 SpdyHeaderBlock headers; | 117 SpdyHeaderBlock headers; |
| 122 HttpRequestInfo http_request_info; | 118 HttpRequestInfo http_request_info; |
| 123 http_request_info.url = request_info_->url; | 119 http_request_info.url = request_info_->url; |
| 124 http_request_info.method = request_info_->method; | 120 http_request_info.method = request_info_->method; |
| 125 http_request_info.extra_headers = request_info_->extra_headers; | 121 http_request_info.extra_headers = request_info_->extra_headers; |
| 126 | 122 |
| 127 CreateSpdyHeadersFromHttpRequest( | 123 CreateSpdyHeadersFromHttpRequest( |
| 128 http_request_info, http_request_info.extra_headers, true, &headers); | 124 http_request_info, http_request_info.extra_headers, true, &headers); |
| 129 // Sending the request might result in the stream being closed via OnClose | 125 int rv = stream_->WriteHeaders(std::move(headers), |
| 130 // which will post a task to notify the delegate asynchronously. | 126 request_info_->end_stream_on_headers, nullptr); |
| 131 // TODO(rch): Clean up this interface when OnClose and OnError are removed. | 127 if (rv >= 0) { |
| 132 size_t headers_bytes_sent = stream_->WriteHeaders( | 128 headers_bytes_sent_ += rv; |
| 133 std::move(headers), request_info_->end_stream_on_headers, nullptr); | 129 has_sent_headers_ = true; |
| 134 if (!stream_) | 130 } |
| 135 return false; | 131 return rv; |
| 136 | |
| 137 headers_bytes_sent_ += headers_bytes_sent; | |
| 138 has_sent_headers_ = true; | |
| 139 return true; | |
| 140 } | 132 } |
| 141 | 133 |
| 142 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) { | 134 int BidirectionalStreamQuicImpl::ReadData(IOBuffer* buffer, int buffer_len) { |
| 143 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | 135 ScopedBoolSaver saver(&may_invoke_callbacks_, false); |
| 144 DCHECK(buffer); | 136 DCHECK(buffer); |
| 145 DCHECK(buffer_len); | 137 DCHECK(buffer_len); |
| 146 | 138 |
| 147 if (!stream_) { | |
| 148 // If the stream is already closed, there is no body to read. | |
| 149 return response_status_; | |
| 150 } | |
| 151 int rv = stream_->ReadBody( | 139 int rv = stream_->ReadBody( |
| 152 buffer, buffer_len, | 140 buffer, buffer_len, |
| 153 base::Bind(&BidirectionalStreamQuicImpl::OnReadDataComplete, | 141 base::Bind(&BidirectionalStreamQuicImpl::OnReadDataComplete, |
| 154 weak_factory_.GetWeakPtr())); | 142 weak_factory_.GetWeakPtr())); |
| 155 if (rv == ERR_IO_PENDING) { | 143 if (rv == ERR_IO_PENDING) { |
| 156 read_buffer_ = buffer; | 144 read_buffer_ = buffer; |
| 157 read_buffer_len_ = buffer_len; | 145 read_buffer_len_ = buffer_len; |
| 158 return ERR_IO_PENDING; | 146 return ERR_IO_PENDING; |
| 159 } | 147 } |
| 160 | 148 |
| 161 if (rv < 0) | 149 if (rv < 0) |
| 162 return rv; | 150 return rv; |
| 163 | 151 |
| 164 if (stream_->IsDoneReading()) { | 152 if (stream_->IsDoneReading()) { |
| 165 // If the write side is closed, OnFinRead() will call | 153 // If the write side is closed, OnFinRead() will call |
| 166 // BidirectionalStreamQuicImpl::OnClose(). | 154 // BidirectionalStreamQuicImpl::OnClose(). |
| 155 expect_trailers_ = false; | |
| 167 stream_->OnFinRead(); | 156 stream_->OnFinRead(); |
| 168 } | 157 } |
| 169 return rv; | 158 return rv; |
| 170 } | 159 } |
| 171 | 160 |
| 172 void BidirectionalStreamQuicImpl::SendData(const scoped_refptr<IOBuffer>& data, | 161 void BidirectionalStreamQuicImpl::SendData(const scoped_refptr<IOBuffer>& data, |
| 173 int length, | 162 int length, |
| 174 bool end_stream) { | 163 bool end_stream) { |
| 175 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | 164 ScopedBoolSaver saver(&may_invoke_callbacks_, false); |
| 176 DCHECK(length > 0 || (length == 0 && end_stream)); | 165 DCHECK(length > 0 || (length == 0 && end_stream)); |
| 177 if (!stream_) { | 166 if (!stream_->IsOpen()) { |
| 178 LOG(ERROR) << "Trying to send data after stream has been destroyed."; | 167 LOG(ERROR) << "Trying to send data after stream has been closed."; |
| 179 base::ThreadTaskRunnerHandle::Get()->PostTask( | 168 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 180 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | 169 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, |
| 181 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | 170 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
| 182 return; | 171 return; |
| 183 } | 172 } |
| 184 | 173 |
| 185 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler; | 174 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler; |
| 186 if (!has_sent_headers_) { | 175 if (!has_sent_headers_) { |
| 187 DCHECK(!send_request_headers_automatically_); | 176 DCHECK(!send_request_headers_automatically_); |
| 188 // Creates a bundler only if there are headers to be sent along with the | 177 // Creates a bundler only if there are headers to be sent along with the |
| 189 // single data buffer. | 178 // single data buffer. |
| 190 bundler = | 179 bundler = |
| 191 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING); | 180 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING); |
| 192 // Sending the request might result in the stream being closed. | 181 // Sending the request might result in the stream being closed. |
| 193 if (!WriteHeaders()) | 182 int rv = WriteHeaders(); |
| 183 if (rv < 0) { | |
| 184 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 185 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | |
| 186 weak_factory_.GetWeakPtr(), rv)); | |
| 194 return; | 187 return; |
| 188 } | |
| 195 } | 189 } |
| 196 | 190 |
| 197 QuicStringPiece string_data(data->data(), length); | 191 QuicStringPiece string_data(data->data(), length); |
| 198 int rv = stream_->WriteStreamData( | 192 int rv = stream_->WriteStreamData( |
| 199 string_data, end_stream, | 193 string_data, end_stream, |
| 200 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, | 194 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, |
| 201 weak_factory_.GetWeakPtr())); | 195 weak_factory_.GetWeakPtr())); |
| 202 DCHECK(rv == OK || rv == ERR_IO_PENDING); | 196 if (rv != ERR_IO_PENDING) { |
| 203 if (rv == OK) { | |
| 204 base::ThreadTaskRunnerHandle::Get()->PostTask( | 197 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 205 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, | 198 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, |
| 206 weak_factory_.GetWeakPtr(), OK)); | 199 weak_factory_.GetWeakPtr(), rv)); |
| 207 } | 200 } |
| 208 } | 201 } |
| 209 | 202 |
| 210 void BidirectionalStreamQuicImpl::SendvData( | 203 void BidirectionalStreamQuicImpl::SendvData( |
| 211 const std::vector<scoped_refptr<IOBuffer>>& buffers, | 204 const std::vector<scoped_refptr<IOBuffer>>& buffers, |
| 212 const std::vector<int>& lengths, | 205 const std::vector<int>& lengths, |
| 213 bool end_stream) { | 206 bool end_stream) { |
| 214 ScopedBoolSaver saver(&may_invoke_callbacks_, false); | 207 ScopedBoolSaver saver(&may_invoke_callbacks_, false); |
| 215 DCHECK_EQ(buffers.size(), lengths.size()); | 208 DCHECK_EQ(buffers.size(), lengths.size()); |
| 216 | 209 |
| 217 if (!stream_) { | 210 if (!stream_->IsOpen()) { |
| 218 LOG(ERROR) << "Trying to send data after stream has been destroyed."; | 211 LOG(ERROR) << "Trying to send data after stream has been closed."; |
| 219 base::ThreadTaskRunnerHandle::Get()->PostTask( | 212 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 220 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | 213 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, |
| 221 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); | 214 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
| 222 return; | 215 return; |
| 223 } | 216 } |
| 224 | 217 |
| 225 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler( | 218 std::unique_ptr<QuicConnection::ScopedPacketBundler> bundler( |
| 226 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING)); | 219 session_->CreatePacketBundler(QuicConnection::SEND_ACK_IF_PENDING)); |
| 227 if (!has_sent_headers_) { | 220 if (!has_sent_headers_) { |
| 228 DCHECK(!send_request_headers_automatically_); | 221 DCHECK(!send_request_headers_automatically_); |
| 229 // Sending the request might result in the stream being closed. | 222 int rv = WriteHeaders(); |
| 230 if (!WriteHeaders()) | 223 if (rv < 0) { |
| 224 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 225 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | |
| 226 weak_factory_.GetWeakPtr(), rv)); | |
|
Ryan Hamilton
2017/06/01 23:20:30
Since we do this same thing every time we call Wri
| |
| 231 return; | 227 return; |
| 228 } | |
| 232 } | 229 } |
| 233 | 230 |
| 234 int rv = stream_->WritevStreamData( | 231 int rv = stream_->WritevStreamData( |
| 235 buffers, lengths, end_stream, | 232 buffers, lengths, end_stream, |
| 236 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, | 233 base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, |
| 237 weak_factory_.GetWeakPtr())); | 234 weak_factory_.GetWeakPtr())); |
| 238 | 235 |
| 239 DCHECK(rv == OK || rv == ERR_IO_PENDING); | 236 if (rv != ERR_IO_PENDING) { |
| 240 if (rv == OK) { | |
| 241 base::ThreadTaskRunnerHandle::Get()->PostTask( | 237 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 242 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, | 238 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::OnSendDataComplete, |
| 243 weak_factory_.GetWeakPtr(), OK)); | 239 weak_factory_.GetWeakPtr(), rv)); |
| 244 } | 240 } |
| 245 } | 241 } |
| 246 | 242 |
| 247 NextProto BidirectionalStreamQuicImpl::GetProtocol() const { | 243 NextProto BidirectionalStreamQuicImpl::GetProtocol() const { |
| 248 return negotiated_protocol_; | 244 return negotiated_protocol_; |
| 249 } | 245 } |
| 250 | 246 |
| 251 int64_t BidirectionalStreamQuicImpl::GetTotalReceivedBytes() const { | 247 int64_t BidirectionalStreamQuicImpl::GetTotalReceivedBytes() const { |
| 252 if (stream_) | 248 if (stream_) |
| 253 return headers_bytes_received_ + stream_->stream_bytes_read(); | 249 return headers_bytes_received_ + stream_->stream_bytes_read(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 267 is_first_stream = stream_->IsFirstStream(); | 263 is_first_stream = stream_->IsFirstStream(); |
| 268 if (is_first_stream) { | 264 if (is_first_stream) { |
| 269 load_timing_info->socket_reused = false; | 265 load_timing_info->socket_reused = false; |
| 270 load_timing_info->connect_timing = connect_timing_; | 266 load_timing_info->connect_timing = connect_timing_; |
| 271 } else { | 267 } else { |
| 272 load_timing_info->socket_reused = true; | 268 load_timing_info->socket_reused = true; |
| 273 } | 269 } |
| 274 return true; | 270 return true; |
| 275 } | 271 } |
| 276 | 272 |
| 277 void BidirectionalStreamQuicImpl::OnClose() { | |
| 278 DCHECK(stream_); | |
| 279 | |
| 280 if (stream_->connection_error() != QUIC_NO_ERROR || | |
| 281 stream_->stream_error() != QUIC_STREAM_NO_ERROR) { | |
| 282 OnError(session_->IsCryptoHandshakeConfirmed() ? ERR_QUIC_PROTOCOL_ERROR | |
| 283 : ERR_QUIC_HANDSHAKE_FAILED); | |
| 284 return; | |
| 285 } | |
| 286 | |
| 287 if (!stream_->fin_sent() || !stream_->fin_received()) { | |
| 288 // The connection must have been closed by the peer with QUIC_NO_ERROR, | |
| 289 // which is improper. | |
| 290 OnError(ERR_UNEXPECTED); | |
| 291 return; | |
| 292 } | |
| 293 | |
| 294 // The connection was closed normally so there is no need to notify | |
| 295 // the delegate. | |
| 296 ResetStream(); | |
| 297 } | |
| 298 | |
| 299 void BidirectionalStreamQuicImpl::OnError(int error) { | |
| 300 // Avoid reentrancy by notifying the delegate asynchronously. | |
| 301 NotifyErrorImpl(error, /*notify_delegate_later*/ true); | |
| 302 } | |
| 303 | |
| 304 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) { | 273 void BidirectionalStreamQuicImpl::OnStreamReady(int rv) { |
| 305 DCHECK_NE(ERR_IO_PENDING, rv); | 274 DCHECK_NE(ERR_IO_PENDING, rv); |
| 306 DCHECK(rv == OK || !stream_); | 275 DCHECK(!stream_); |
| 307 if (rv != OK) { | 276 if (rv != OK) { |
| 308 NotifyError(rv); | 277 NotifyError(rv); |
| 309 return; | 278 return; |
| 310 } | 279 } |
| 311 | 280 |
| 312 stream_ = session_->ReleaseStream(this); | 281 stream_ = session_->ReleaseStream(); |
| 313 | 282 |
| 314 base::ThreadTaskRunnerHandle::Get()->PostTask( | 283 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 315 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::ReadInitialHeaders, | 284 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::ReadInitialHeaders, |
| 316 weak_factory_.GetWeakPtr())); | 285 weak_factory_.GetWeakPtr())); |
| 317 | 286 |
| 318 NotifyStreamReady(); | 287 NotifyStreamReady(); |
| 319 } | 288 } |
| 320 | 289 |
| 321 void BidirectionalStreamQuicImpl::OnSendDataComplete(int rv) { | 290 void BidirectionalStreamQuicImpl::OnSendDataComplete(int rv) { |
| 322 CHECK(may_invoke_callbacks_); | 291 CHECK(may_invoke_callbacks_); |
| 323 DCHECK(rv == OK || !stream_); | 292 DCHECK_NE(ERR_IO_PENDING, rv); |
| 324 if (rv != 0) { | 293 if (rv < 0) { |
| 325 NotifyError(rv); | 294 NotifyError(rv); |
| 326 return; | 295 return; |
| 327 } | 296 } |
| 328 | 297 |
| 329 if (delegate_) | 298 if (delegate_) |
| 330 delegate_->OnDataSent(); | 299 delegate_->OnDataSent(); |
| 331 } | 300 } |
| 332 | 301 |
| 333 void BidirectionalStreamQuicImpl::OnReadInitialHeadersComplete(int rv) { | 302 void BidirectionalStreamQuicImpl::OnReadInitialHeadersComplete(int rv) { |
| 334 CHECK(may_invoke_callbacks_); | 303 CHECK(may_invoke_callbacks_); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 365 weak_factory_.GetWeakPtr())); | 334 weak_factory_.GetWeakPtr())); |
| 366 | 335 |
| 367 if (rv != ERR_IO_PENDING) | 336 if (rv != ERR_IO_PENDING) |
| 368 OnReadTrailingHeadersComplete(rv); | 337 OnReadTrailingHeadersComplete(rv); |
| 369 } | 338 } |
| 370 | 339 |
| 371 void BidirectionalStreamQuicImpl::OnReadTrailingHeadersComplete(int rv) { | 340 void BidirectionalStreamQuicImpl::OnReadTrailingHeadersComplete(int rv) { |
| 372 CHECK(may_invoke_callbacks_); | 341 CHECK(may_invoke_callbacks_); |
| 373 DCHECK_NE(ERR_IO_PENDING, rv); | 342 DCHECK_NE(ERR_IO_PENDING, rv); |
| 374 if (rv < 0) { | 343 if (rv < 0) { |
| 375 NotifyError(rv); | 344 if (expect_trailers_) |
| 345 NotifyError(rv); | |
| 376 return; | 346 return; |
| 377 } | 347 } |
| 378 | 348 |
| 379 headers_bytes_received_ += rv; | 349 headers_bytes_received_ += rv; |
| 380 | 350 |
| 381 if (delegate_) | 351 if (delegate_) |
| 382 delegate_->OnTrailersReceived(trailing_headers_); | 352 delegate_->OnTrailersReceived(trailing_headers_); |
| 383 } | 353 } |
| 384 | 354 |
| 385 void BidirectionalStreamQuicImpl::OnReadDataComplete(int rv) { | 355 void BidirectionalStreamQuicImpl::OnReadDataComplete(int rv) { |
| 386 CHECK(may_invoke_callbacks_); | 356 CHECK(may_invoke_callbacks_); |
| 387 DCHECK_GE(rv, 0); | 357 |
| 388 read_buffer_ = nullptr; | 358 read_buffer_ = nullptr; |
| 389 read_buffer_len_ = 0; | 359 read_buffer_len_ = 0; |
| 390 | 360 |
| 391 if (stream_->IsDoneReading()) { | 361 if (stream_->IsDoneReading()) { |
| 392 // If the write side is closed, OnFinRead() will call | 362 // If the write side is closed, OnFinRead() will call |
| 393 // BidirectionalStreamQuicImpl::OnClose(). | 363 // BidirectionalStreamQuicImpl::OnClose(). |
| 394 stream_->OnFinRead(); | 364 stream_->OnFinRead(); |
| 395 } | 365 } |
| 396 | 366 |
| 397 if (delegate_) | 367 if (!delegate_) |
| 368 return; | |
| 369 | |
| 370 if (rv < 0) | |
| 371 NotifyError(rv); | |
| 372 else | |
| 398 delegate_->OnDataRead(rv); | 373 delegate_->OnDataRead(rv); |
| 399 } | 374 } |
| 400 | 375 |
| 401 void BidirectionalStreamQuicImpl::NotifyError(int error) { | 376 void BidirectionalStreamQuicImpl::NotifyError(int error) { |
| 402 NotifyErrorImpl(error, /*notify_delegate_later*/ false); | 377 NotifyErrorImpl(error, /*notify_delegate_later*/ false); |
| 403 } | 378 } |
| 404 | 379 |
| 405 void BidirectionalStreamQuicImpl::NotifyErrorImpl(int error, | 380 void BidirectionalStreamQuicImpl::NotifyErrorImpl(int error, |
| 406 bool notify_delegate_later) { | 381 bool notify_delegate_later) { |
| 407 DCHECK_NE(OK, error); | 382 DCHECK_NE(OK, error); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 428 void BidirectionalStreamQuicImpl::NotifyFailure( | 403 void BidirectionalStreamQuicImpl::NotifyFailure( |
| 429 BidirectionalStreamImpl::Delegate* delegate, | 404 BidirectionalStreamImpl::Delegate* delegate, |
| 430 int error) { | 405 int error) { |
| 431 CHECK(may_invoke_callbacks_); | 406 CHECK(may_invoke_callbacks_); |
| 432 delegate->OnFailed(error); | 407 delegate->OnFailed(error); |
| 433 // |this| might be destroyed at this point. | 408 // |this| might be destroyed at this point. |
| 434 } | 409 } |
| 435 | 410 |
| 436 void BidirectionalStreamQuicImpl::NotifyStreamReady() { | 411 void BidirectionalStreamQuicImpl::NotifyStreamReady() { |
| 437 CHECK(may_invoke_callbacks_); | 412 CHECK(may_invoke_callbacks_); |
| 438 // Sending the request might result in the stream being closed. | 413 if (send_request_headers_automatically_) { |
| 439 if (send_request_headers_automatically_ && !WriteHeaders()) | 414 int rv = WriteHeaders(); |
| 440 return; | 415 if (rv < 0) { |
| 416 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 417 FROM_HERE, base::Bind(&BidirectionalStreamQuicImpl::NotifyError, | |
| 418 weak_factory_.GetWeakPtr(), rv)); | |
| 419 return; | |
| 420 } | |
| 421 } | |
| 441 | 422 |
| 442 if (delegate_) | 423 if (delegate_) |
| 443 delegate_->OnStreamReady(has_sent_headers_); | 424 delegate_->OnStreamReady(has_sent_headers_); |
| 444 } | 425 } |
| 445 | 426 |
| 446 void BidirectionalStreamQuicImpl::ResetStream() { | 427 void BidirectionalStreamQuicImpl::ResetStream() { |
| 447 if (!stream_) | 428 if (!stream_) |
| 448 return; | 429 return; |
| 449 closed_stream_received_bytes_ = stream_->stream_bytes_read(); | 430 closed_stream_received_bytes_ = stream_->stream_bytes_read(); |
| 450 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); | 431 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); |
| 451 closed_is_first_stream_ = stream_->IsFirstStream(); | 432 closed_is_first_stream_ = stream_->IsFirstStream(); |
| 452 stream_->ClearDelegate(); | |
| 453 stream_ = nullptr; | |
| 454 } | 433 } |
| 455 | 434 |
| 456 } // namespace net | 435 } // namespace net |
| OLD | NEW |