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 |