OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/quic_chromium_client_stream.h" | 5 #include "net/quic/chromium/quic_chromium_client_stream.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 if (!read_headers_callback_) | 47 if (!read_headers_callback_) |
48 return; // Wait for ReadInitialHeaders to be called. | 48 return; // Wait for ReadInitialHeaders to be called. |
49 | 49 |
50 int rv = ERR_QUIC_PROTOCOL_ERROR; | 50 int rv = ERR_QUIC_PROTOCOL_ERROR; |
51 if (!stream_->DeliverInitialHeaders(read_headers_buffer_, &rv)) | 51 if (!stream_->DeliverInitialHeaders(read_headers_buffer_, &rv)) |
52 rv = ERR_QUIC_PROTOCOL_ERROR; | 52 rv = ERR_QUIC_PROTOCOL_ERROR; |
53 | 53 |
54 ResetAndReturn(&read_headers_callback_).Run(rv); | 54 ResetAndReturn(&read_headers_callback_).Run(rv); |
55 } | 55 } |
56 | 56 |
57 void QuicChromiumClientStream::Handle::OnTrailingHeadersAvailable( | 57 void QuicChromiumClientStream::Handle::OnTrailingHeadersAvailable() { |
58 const SpdyHeaderBlock& headers, | 58 if (!read_headers_callback_) |
59 size_t frame_len) { | 59 return; // Wait for ReadInitialHeaders to be called. |
60 delegate_->OnTrailingHeadersAvailable(headers, frame_len); | 60 |
61 int rv = ERR_QUIC_PROTOCOL_ERROR; | |
62 if (!stream_->DeliverTrailingHeaders(read_headers_buffer_, &rv)) | |
63 rv = ERR_QUIC_PROTOCOL_ERROR; | |
64 | |
65 ResetAndReturn(&read_headers_callback_).Run(rv); | |
61 } | 66 } |
62 | 67 |
63 void QuicChromiumClientStream::Handle::OnDataAvailable() { | 68 void QuicChromiumClientStream::Handle::OnDataAvailable() { |
64 if (!read_body_callback_) | 69 if (!read_body_callback_) |
65 return; // Wait for ReadBody to be called. | 70 return; // Wait for ReadBody to be called. |
66 | 71 |
67 int rv = stream_->Read(read_body_buffer_, read_body_buffer_len_); | 72 int rv = stream_->Read(read_body_buffer_, read_body_buffer_len_); |
68 if (rv == ERR_IO_PENDING) | 73 if (rv == ERR_IO_PENDING) |
69 return; // Spurrious, likely because of trailers? | 74 return; // Spurrious, likely because of trailers? |
70 | 75 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 int rv = stream_->Read(buffer, buffer_len); | 132 int rv = stream_->Read(buffer, buffer_len); |
128 if (rv != ERR_IO_PENDING) | 133 if (rv != ERR_IO_PENDING) |
129 return rv; | 134 return rv; |
130 | 135 |
131 read_body_callback_ = callback; | 136 read_body_callback_ = callback; |
132 read_body_buffer_ = buffer; | 137 read_body_buffer_ = buffer; |
133 read_body_buffer_len_ = buffer_len; | 138 read_body_buffer_len_ = buffer_len; |
134 return ERR_IO_PENDING; | 139 return ERR_IO_PENDING; |
135 } | 140 } |
136 | 141 |
142 int QuicChromiumClientStream::Handle::ReadTrailingHeaders( | |
143 SpdyHeaderBlock* header_block, | |
144 const CompletionCallback& callback) { | |
145 if (!stream_) | |
146 return ERR_CONNECTION_CLOSED; | |
147 | |
148 int frame_len = 0; | |
149 if (stream_->DeliverTrailingHeaders(header_block, &frame_len)) | |
150 return frame_len; | |
151 | |
152 read_headers_buffer_ = header_block; | |
153 read_headers_callback_ = callback; | |
154 return ERR_IO_PENDING; | |
155 } | |
156 | |
137 size_t QuicChromiumClientStream::Handle::WriteHeaders( | 157 size_t QuicChromiumClientStream::Handle::WriteHeaders( |
138 SpdyHeaderBlock header_block, | 158 SpdyHeaderBlock header_block, |
139 bool fin, | 159 bool fin, |
140 QuicReferenceCountedPointer<QuicAckListenerInterface> | 160 QuicReferenceCountedPointer<QuicAckListenerInterface> |
141 ack_notifier_delegate) { | 161 ack_notifier_delegate) { |
142 if (!stream_) | 162 if (!stream_) |
143 return 0; | 163 return 0; |
144 return stream_->WriteHeaders(std::move(header_block), fin, | 164 return stream_->WriteHeaders(std::move(header_block), fin, |
145 ack_notifier_delegate); | 165 ack_notifier_delegate); |
146 } | 166 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 QuicClientSessionBase* session, | 325 QuicClientSessionBase* session, |
306 const NetLogWithSource& net_log) | 326 const NetLogWithSource& net_log) |
307 : QuicSpdyStream(id, session), | 327 : QuicSpdyStream(id, session), |
308 net_log_(net_log), | 328 net_log_(net_log), |
309 handle_(nullptr), | 329 handle_(nullptr), |
310 headers_delivered_(false), | 330 headers_delivered_(false), |
311 initial_headers_sent_(false), | 331 initial_headers_sent_(false), |
312 session_(session), | 332 session_(session), |
313 can_migrate_(true), | 333 can_migrate_(true), |
314 initial_headers_frame_len_(0), | 334 initial_headers_frame_len_(0), |
335 trailing_headers_frame_len_(0), | |
315 weak_factory_(this) {} | 336 weak_factory_(this) {} |
316 | 337 |
317 QuicChromiumClientStream::~QuicChromiumClientStream() { | 338 QuicChromiumClientStream::~QuicChromiumClientStream() { |
318 if (handle_) | 339 if (handle_) |
319 handle_->OnClose(); | 340 handle_->OnClose(); |
320 } | 341 } |
321 | 342 |
322 void QuicChromiumClientStream::OnInitialHeadersComplete( | 343 void QuicChromiumClientStream::OnInitialHeadersComplete( |
323 bool fin, | 344 bool fin, |
324 size_t frame_len, | 345 size_t frame_len, |
(...skipping 20 matching lines...) Expand all Loading... | |
345 // The handle will be notified of the headers via a posted task. | 366 // The handle will be notified of the headers via a posted task. |
346 NotifyHandleOfInitialHeadersAvailableLater(); | 367 NotifyHandleOfInitialHeadersAvailableLater(); |
347 } | 368 } |
348 } | 369 } |
349 | 370 |
350 void QuicChromiumClientStream::OnTrailingHeadersComplete( | 371 void QuicChromiumClientStream::OnTrailingHeadersComplete( |
351 bool fin, | 372 bool fin, |
352 size_t frame_len, | 373 size_t frame_len, |
353 const QuicHeaderList& header_list) { | 374 const QuicHeaderList& header_list) { |
354 QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list); | 375 QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list); |
355 NotifyHandleOfTrailingHeadersAvailableLater(received_trailers().Clone(), | 376 trailing_headers_frame_len_ = frame_len; |
356 frame_len); | 377 if (handle_) { |
378 // The handle will be notified of the headers via a posted task. | |
379 NotifyHandleOfTrailingHeadersAvailableLater(); | |
380 } | |
357 } | 381 } |
358 | 382 |
359 void QuicChromiumClientStream::OnPromiseHeaderList( | 383 void QuicChromiumClientStream::OnPromiseHeaderList( |
360 QuicStreamId promised_id, | 384 QuicStreamId promised_id, |
361 size_t frame_len, | 385 size_t frame_len, |
362 const QuicHeaderList& header_list) { | 386 const QuicHeaderList& header_list) { |
363 SpdyHeaderBlock promise_headers; | 387 SpdyHeaderBlock promise_headers; |
364 int64_t content_length = -1; | 388 int64_t content_length = -1; |
365 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length, | 389 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length, |
366 &promise_headers)) { | 390 &promise_headers)) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 } | 531 } |
508 | 532 |
509 void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable() { | 533 void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable() { |
510 if (!handle_) | 534 if (!handle_) |
511 return; | 535 return; |
512 | 536 |
513 if (!headers_delivered_) | 537 if (!headers_delivered_) |
514 handle_->OnInitialHeadersAvailable(); | 538 handle_->OnInitialHeadersAvailable(); |
515 } | 539 } |
516 | 540 |
517 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailableLater( | 541 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailableLater() { |
518 SpdyHeaderBlock headers, | |
519 size_t frame_len) { | |
520 DCHECK(handle_); | 542 DCHECK(handle_); |
521 base::ThreadTaskRunnerHandle::Get()->PostTask( | 543 base::ThreadTaskRunnerHandle::Get()->PostTask( |
522 FROM_HERE, | 544 FROM_HERE, |
523 base::Bind( | 545 base::Bind( |
524 &QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable, | 546 &QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable, |
525 weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)), | 547 weak_factory_.GetWeakPtr())); |
526 frame_len)); | |
527 } | 548 } |
528 | 549 |
529 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable( | 550 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable() { |
530 SpdyHeaderBlock headers, | |
531 size_t frame_len) { | |
532 if (!handle_) | 551 if (!handle_) |
533 return; | 552 return; |
534 | 553 |
535 DCHECK(headers_delivered_); | 554 DCHECK(headers_delivered_); |
536 // Only mark trailers consumed when we are about to notify delegate. | 555 // Only mark trailers consumed when we are about to notify delegate. |
537 MarkTrailersConsumed(); | 556 MarkTrailersConsumed(); |
xunjieli
2017/05/29 19:39:01
Sorry I haven't realized earlier. Can we move "Mar
Ryan Hamilton
2017/05/29 20:29:57
Ah, good point. Done.
| |
538 // Post an async task to notify delegate of the FIN flag. | 557 // Post an async task to notify delegate of the FIN flag. |
539 NotifyHandleOfDataAvailableLater(); | 558 NotifyHandleOfDataAvailableLater(); |
540 net_log_.AddEvent( | 559 handle_->OnTrailingHeadersAvailable(); |
541 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS, | |
542 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers)); | |
543 handle_->OnTrailingHeadersAvailable(headers, frame_len); | |
544 } | 560 } |
545 | 561 |
546 bool QuicChromiumClientStream::DeliverInitialHeaders(SpdyHeaderBlock* headers, | 562 bool QuicChromiumClientStream::DeliverInitialHeaders(SpdyHeaderBlock* headers, |
547 int* frame_len) { | 563 int* frame_len) { |
548 if (initial_headers_.empty()) | 564 if (initial_headers_.empty()) |
549 return false; | 565 return false; |
550 | 566 |
551 headers_delivered_ = true; | 567 headers_delivered_ = true; |
552 net_log_.AddEvent( | 568 net_log_.AddEvent( |
553 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS, | 569 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS, |
554 base::Bind(&SpdyHeaderBlockNetLogCallback, &initial_headers_)); | 570 base::Bind(&SpdyHeaderBlockNetLogCallback, &initial_headers_)); |
555 | 571 |
556 *headers = std::move(initial_headers_); | 572 *headers = std::move(initial_headers_); |
557 *frame_len = initial_headers_frame_len_; | 573 *frame_len = initial_headers_frame_len_; |
558 return true; | 574 return true; |
559 } | 575 } |
560 | 576 |
577 bool QuicChromiumClientStream::DeliverTrailingHeaders(SpdyHeaderBlock* headers, | |
578 int* frame_len) { | |
579 if (received_trailers().empty()) | |
580 return false; | |
581 | |
582 net_log_.AddEvent( | |
583 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS, | |
584 base::Bind(&SpdyHeaderBlockNetLogCallback, &received_trailers())); | |
585 | |
586 *headers = received_trailers().Clone(); | |
587 *frame_len = trailing_headers_frame_len_; | |
588 return true; | |
589 } | |
590 | |
561 void QuicChromiumClientStream::NotifyHandleOfDataAvailableLater() { | 591 void QuicChromiumClientStream::NotifyHandleOfDataAvailableLater() { |
562 DCHECK(handle_); | 592 DCHECK(handle_); |
563 base::ThreadTaskRunnerHandle::Get()->PostTask( | 593 base::ThreadTaskRunnerHandle::Get()->PostTask( |
564 FROM_HERE, | 594 FROM_HERE, |
565 base::Bind(&QuicChromiumClientStream::NotifyHandleOfDataAvailable, | 595 base::Bind(&QuicChromiumClientStream::NotifyHandleOfDataAvailable, |
566 weak_factory_.GetWeakPtr())); | 596 weak_factory_.GetWeakPtr())); |
567 } | 597 } |
568 | 598 |
569 void QuicChromiumClientStream::NotifyHandleOfDataAvailable() { | 599 void QuicChromiumClientStream::NotifyHandleOfDataAvailable() { |
570 if (handle_) | 600 if (handle_) |
571 handle_->OnDataAvailable(); | 601 handle_->OnDataAvailable(); |
572 } | 602 } |
573 | 603 |
574 void QuicChromiumClientStream::DisableConnectionMigration() { | 604 void QuicChromiumClientStream::DisableConnectionMigration() { |
575 can_migrate_ = false; | 605 can_migrate_ = false; |
576 } | 606 } |
577 | 607 |
578 bool QuicChromiumClientStream::IsFirstStream() { | 608 bool QuicChromiumClientStream::IsFirstStream() { |
579 return id() == kHeadersStreamId + 2; | 609 return id() == kHeadersStreamId + 2; |
580 } | 610 } |
581 | 611 |
582 } // namespace net | 612 } // namespace net |
OLD | NEW |