Chromium Code Reviews| 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 |