Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: net/quic/chromium/quic_chromium_client_stream.cc

Issue 2873963003: Add an async ReadInitialHeaders method to QuicChromiumClientStream::Handle (Closed)
Patch Set: Rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
13 #include "net/base/io_buffer.h" 13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h" 14 #include "net/base/net_errors.h"
15 #include "net/log/net_log_event_type.h" 15 #include "net/log/net_log_event_type.h"
16 #include "net/quic/chromium/quic_chromium_client_session.h" 16 #include "net/quic/chromium/quic_chromium_client_session.h"
17 #include "net/quic/chromium/quic_http_utils.h" 17 #include "net/quic/chromium/quic_http_utils.h"
18 #include "net/quic/core/quic_spdy_session.h" 18 #include "net/quic/core/quic_spdy_session.h"
19 #include "net/quic/core/quic_write_blocked_list.h" 19 #include "net/quic/core/quic_write_blocked_list.h"
20 #include "net/quic/core/spdy_utils.h" 20 #include "net/quic/core/spdy_utils.h"
21 21
22 namespace net { 22 namespace net {
23 23
24 QuicChromiumClientStream::Handle::Handle(QuicChromiumClientStream* stream, 24 QuicChromiumClientStream::Handle::Handle(QuicChromiumClientStream* stream,
25 Delegate* delegate) 25 Delegate* delegate)
26 : stream_(stream), delegate_(delegate) { 26 : stream_(stream), delegate_(delegate), read_headers_buffer_(nullptr) {
27 SaveState(); 27 SaveState();
28 } 28 }
29 29
30 QuicChromiumClientStream::Handle::~Handle() { 30 QuicChromiumClientStream::Handle::~Handle() {
31 if (stream_) { 31 if (stream_) {
32 stream_->ClearHandle(); 32 stream_->ClearHandle();
33 // TODO(rch): If stream_ is still valid, it should probably be Reset() 33 // TODO(rch): If stream_ is still valid, it should probably be Reset()
34 // so that it does not leak. 34 // so that it does not leak.
35 // stream_->Reset(QUIC_STREAM_CANCELLED); 35 // stream_->Reset(QUIC_STREAM_CANCELLED);
36 } 36 }
37 } 37 }
38 38
39 void QuicChromiumClientStream::Handle::ClearDelegate() { 39 void QuicChromiumClientStream::Handle::ClearDelegate() {
40 delegate_ = nullptr; 40 delegate_ = nullptr;
41 } 41 }
42 42
43 void QuicChromiumClientStream::Handle::OnInitialHeadersAvailable( 43 void QuicChromiumClientStream::Handle::OnInitialHeadersAvailable() {
44 const SpdyHeaderBlock& headers, 44 if (!read_headers_callback_)
45 size_t frame_len) { 45 return; // Wait for ReadInitialHeaders to be called.
46 delegate_->OnInitialHeadersAvailable(headers, frame_len); 46
47 int rv = ERR_QUIC_PROTOCOL_ERROR;
48 if (!stream_->DeliverInitialHeaders(read_headers_buffer_, &rv))
49 rv = ERR_QUIC_PROTOCOL_ERROR;
50
51 ResetAndReturn(&read_headers_callback_).Run(rv);
47 } 52 }
48 53
49 void QuicChromiumClientStream::Handle::OnTrailingHeadersAvailable( 54 void QuicChromiumClientStream::Handle::OnTrailingHeadersAvailable(
50 const SpdyHeaderBlock& headers, 55 const SpdyHeaderBlock& headers,
51 size_t frame_len) { 56 size_t frame_len) {
52 delegate_->OnTrailingHeadersAvailable(headers, frame_len); 57 delegate_->OnTrailingHeadersAvailable(headers, frame_len);
53 } 58 }
54 59
55 void QuicChromiumClientStream::Handle::OnDataAvailable() { 60 void QuicChromiumClientStream::Handle::OnDataAvailable() {
56 delegate_->OnDataAvailable(); 61 delegate_->OnDataAvailable();
(...skipping 14 matching lines...) Expand all
71 if (stream_) 76 if (stream_)
72 SaveState(); 77 SaveState();
73 stream_ = nullptr; 78 stream_ = nullptr;
74 if (delegate_) { 79 if (delegate_) {
75 auto* delegate = delegate_; 80 auto* delegate = delegate_;
76 delegate_ = nullptr; 81 delegate_ = nullptr;
77 delegate->OnError(error); 82 delegate->OnError(error);
78 } 83 }
79 } 84 }
80 85
86 int QuicChromiumClientStream::Handle::ReadInitialHeaders(
87 SpdyHeaderBlock* header_block,
88 const CompletionCallback& callback) {
89 if (!stream_)
90 return ERR_CONNECTION_CLOSED;
91
92 int frame_len = 0;
93 if (stream_->DeliverInitialHeaders(header_block, &frame_len))
94 return frame_len;
95
96 read_headers_buffer_ = header_block;
97 read_headers_callback_ = callback;
98 return ERR_IO_PENDING;
99 }
100
81 size_t QuicChromiumClientStream::Handle::WriteHeaders( 101 size_t QuicChromiumClientStream::Handle::WriteHeaders(
82 SpdyHeaderBlock header_block, 102 SpdyHeaderBlock header_block,
83 bool fin, 103 bool fin,
84 QuicReferenceCountedPointer<QuicAckListenerInterface> 104 QuicReferenceCountedPointer<QuicAckListenerInterface>
85 ack_notifier_delegate) { 105 ack_notifier_delegate) {
86 if (!stream_) 106 if (!stream_)
87 return 0; 107 return 0;
88 return stream_->WriteHeaders(std::move(header_block), fin, 108 return stream_->WriteHeaders(std::move(header_block), fin,
89 ack_notifier_delegate); 109 ack_notifier_delegate);
90 } 110 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &length, &header_block)) { 284 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &length, &header_block)) {
265 DLOG(ERROR) << "Failed to parse header list: " << header_list.DebugString(); 285 DLOG(ERROR) << "Failed to parse header list: " << header_list.DebugString();
266 ConsumeHeaderList(); 286 ConsumeHeaderList();
267 Reset(QUIC_BAD_APPLICATION_PAYLOAD); 287 Reset(QUIC_BAD_APPLICATION_PAYLOAD);
268 return; 288 return;
269 } 289 }
270 290
271 ConsumeHeaderList(); 291 ConsumeHeaderList();
272 session_->OnInitialHeadersComplete(id(), header_block); 292 session_->OnInitialHeadersComplete(id(), header_block);
273 293
274 if (handle_) {
275 // The handle will receive the headers via a posted task.
276 NotifyHandleOfInitialHeadersAvailableLater(std::move(header_block),
277 frame_len);
278 return;
279 }
280
281 // Buffer the headers and deliver them when the handle arrives. 294 // Buffer the headers and deliver them when the handle arrives.
282 initial_headers_ = std::move(header_block); 295 initial_headers_ = std::move(header_block);
283 initial_headers_frame_len_ = frame_len; 296 initial_headers_frame_len_ = frame_len;
297
298 if (handle_) {
299 // The handle will be notified of the headers via a posted task.
300 NotifyHandleOfInitialHeadersAvailableLater();
301 }
284 } 302 }
285 303
286 void QuicChromiumClientStream::OnTrailingHeadersComplete( 304 void QuicChromiumClientStream::OnTrailingHeadersComplete(
287 bool fin, 305 bool fin,
288 size_t frame_len, 306 size_t frame_len,
289 const QuicHeaderList& header_list) { 307 const QuicHeaderList& header_list) {
290 QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list); 308 QuicSpdyStream::OnTrailingHeadersComplete(fin, frame_len, header_list);
291 NotifyHandleOfTrailingHeadersAvailableLater(received_trailers().Clone(), 309 NotifyHandleOfTrailingHeadersAvailableLater(received_trailers().Clone(),
292 frame_len); 310 frame_len);
293 } 311 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 425
408 std::unique_ptr<QuicChromiumClientStream::Handle> 426 std::unique_ptr<QuicChromiumClientStream::Handle>
409 QuicChromiumClientStream::CreateHandle( 427 QuicChromiumClientStream::CreateHandle(
410 QuicChromiumClientStream::Delegate* delegate) { 428 QuicChromiumClientStream::Delegate* delegate) {
411 DCHECK(!handle_); 429 DCHECK(!handle_);
412 auto handle = std::unique_ptr<QuicChromiumClientStream::Handle>( 430 auto handle = std::unique_ptr<QuicChromiumClientStream::Handle>(
413 new QuicChromiumClientStream::Handle(this, delegate)); 431 new QuicChromiumClientStream::Handle(this, delegate));
414 handle_ = handle.get(); 432 handle_ = handle.get();
415 433
416 // Should this perhaps be via PostTask to make reasoning simpler? 434 // Should this perhaps be via PostTask to make reasoning simpler?
417 if (!initial_headers_.empty()) { 435 if (!initial_headers_.empty())
418 handle_->OnInitialHeadersAvailable(std::move(initial_headers_), 436 handle_->OnInitialHeadersAvailable();
419 initial_headers_frame_len_);
420 }
421 437
422 return handle; 438 return handle;
423 } 439 }
424 440
425 void QuicChromiumClientStream::ClearHandle() { 441 void QuicChromiumClientStream::ClearHandle() {
426 handle_ = nullptr; 442 handle_ = nullptr;
427 } 443 }
428 444
429 void QuicChromiumClientStream::OnError(int error) { 445 void QuicChromiumClientStream::OnError(int error) {
430 if (handle_) { 446 if (handle_) {
(...skipping 12 matching lines...) Expand all
443 459
444 iovec iov; 460 iovec iov;
445 iov.iov_base = buf->data(); 461 iov.iov_base = buf->data();
446 iov.iov_len = buf_len; 462 iov.iov_len = buf_len;
447 size_t bytes_read = Readv(&iov, 1); 463 size_t bytes_read = Readv(&iov, 1);
448 // Since HasBytesToRead is true, Readv() must of read some data. 464 // Since HasBytesToRead is true, Readv() must of read some data.
449 DCHECK_NE(0u, bytes_read); 465 DCHECK_NE(0u, bytes_read);
450 return bytes_read; 466 return bytes_read;
451 } 467 }
452 468
453 void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailableLater( 469 void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailableLater() {
454 SpdyHeaderBlock headers,
455 size_t frame_len) {
456 DCHECK(handle_); 470 DCHECK(handle_);
457 base::ThreadTaskRunnerHandle::Get()->PostTask( 471 base::ThreadTaskRunnerHandle::Get()->PostTask(
458 FROM_HERE, 472 FROM_HERE,
459 base::Bind( 473 base::Bind(
460 &QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable, 474 &QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable,
461 weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)), 475 weak_factory_.GetWeakPtr()));
462 frame_len));
463 } 476 }
464 477
465 void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable( 478 void QuicChromiumClientStream::NotifyHandleOfInitialHeadersAvailable() {
466 SpdyHeaderBlock headers,
467 size_t frame_len) {
468 if (!handle_) 479 if (!handle_)
469 return; 480 return;
470 481
471 DCHECK(!headers_delivered_); 482 if (!headers_delivered_)
472 headers_delivered_ = true; 483 handle_->OnInitialHeadersAvailable();
473 net_log_.AddEvent(
474 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS,
475 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
476
477 handle_->OnInitialHeadersAvailable(headers, frame_len);
478 } 484 }
479 485
480 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailableLater( 486 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailableLater(
481 SpdyHeaderBlock headers, 487 SpdyHeaderBlock headers,
482 size_t frame_len) { 488 size_t frame_len) {
483 DCHECK(handle_); 489 DCHECK(handle_);
484 base::ThreadTaskRunnerHandle::Get()->PostTask( 490 base::ThreadTaskRunnerHandle::Get()->PostTask(
485 FROM_HERE, 491 FROM_HERE,
486 base::Bind( 492 base::Bind(
487 &QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable, 493 &QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable,
488 weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)), 494 weak_factory_.GetWeakPtr(), base::Passed(std::move(headers)),
489 frame_len)); 495 frame_len));
490 } 496 }
491 497
492 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable( 498 void QuicChromiumClientStream::NotifyHandleOfTrailingHeadersAvailable(
493 SpdyHeaderBlock headers, 499 SpdyHeaderBlock headers,
494 size_t frame_len) { 500 size_t frame_len) {
495 if (!handle_) 501 if (!handle_)
496 return; 502 return;
497 503
498 DCHECK(headers_delivered_); 504 DCHECK(headers_delivered_);
499 // Only mark trailers consumed when we are about to notify delegate. 505 // Only mark trailers consumed when we are about to notify delegate.
500 MarkTrailersConsumed(); 506 MarkTrailersConsumed();
501 // Post an async task to notify delegate of the FIN flag. 507 // Post an async task to notify delegate of the FIN flag.
502 NotifyHandleOfDataAvailableLater(); 508 NotifyHandleOfDataAvailableLater();
503 net_log_.AddEvent( 509 net_log_.AddEvent(
504 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS, 510 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_TRAILERS,
505 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers)); 511 base::Bind(&SpdyHeaderBlockNetLogCallback, &headers));
512 handle_->OnTrailingHeadersAvailable(headers, frame_len);
513 }
506 514
507 handle_->OnTrailingHeadersAvailable(headers, frame_len); 515 bool QuicChromiumClientStream::DeliverInitialHeaders(SpdyHeaderBlock* headers,
516 int* frame_len) {
517 if (initial_headers_.empty())
518 return false;
519
520 headers_delivered_ = true;
521 net_log_.AddEvent(
522 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS,
523 base::Bind(&SpdyHeaderBlockNetLogCallback, &initial_headers_));
524
525 *headers = std::move(initial_headers_);
526 *frame_len = initial_headers_frame_len_;
527 return true;
508 } 528 }
509 529
510 void QuicChromiumClientStream::NotifyHandleOfDataAvailableLater() { 530 void QuicChromiumClientStream::NotifyHandleOfDataAvailableLater() {
511 DCHECK(handle_); 531 DCHECK(handle_);
512 base::ThreadTaskRunnerHandle::Get()->PostTask( 532 base::ThreadTaskRunnerHandle::Get()->PostTask(
513 FROM_HERE, 533 FROM_HERE,
514 base::Bind(&QuicChromiumClientStream::NotifyHandleOfDataAvailable, 534 base::Bind(&QuicChromiumClientStream::NotifyHandleOfDataAvailable,
515 weak_factory_.GetWeakPtr())); 535 weak_factory_.GetWeakPtr()));
516 } 536 }
517 537
518 void QuicChromiumClientStream::NotifyHandleOfDataAvailable() { 538 void QuicChromiumClientStream::NotifyHandleOfDataAvailable() {
519 if (handle_) 539 if (handle_)
520 handle_->OnDataAvailable(); 540 handle_->OnDataAvailable();
521 } 541 }
522 542
523 void QuicChromiumClientStream::DisableConnectionMigration() { 543 void QuicChromiumClientStream::DisableConnectionMigration() {
524 can_migrate_ = false; 544 can_migrate_ = false;
525 } 545 }
526 546
527 bool QuicChromiumClientStream::IsFirstStream() { 547 bool QuicChromiumClientStream::IsFirstStream() {
528 return id() == kHeadersStreamId + 2; 548 return id() == kHeadersStreamId + 2;
529 } 549 }
530 550
531 } // namespace net 551 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/chromium/quic_chromium_client_stream.h ('k') | net/quic/chromium/quic_chromium_client_stream_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698