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

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

Issue 2777333002: Simplify the the logic for setting the final response status for a (Closed)
Patch Set: Created 3 years, 8 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_http_stream.h" 5 #include "net/quic/chromium/quic_http_stream.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 } 43 }
44 44
45 } // namespace 45 } // namespace
46 46
47 QuicHttpStream::QuicHttpStream( 47 QuicHttpStream::QuicHttpStream(
48 const base::WeakPtr<QuicChromiumClientSession>& session) 48 const base::WeakPtr<QuicChromiumClientSession>& session)
49 : MultiplexedHttpStream(MultiplexedSessionHandle(session)), 49 : MultiplexedHttpStream(MultiplexedSessionHandle(session)),
50 next_state_(STATE_NONE), 50 next_state_(STATE_NONE),
51 session_(session), 51 session_(session),
52 quic_version_(session->GetQuicVersion()), 52 quic_version_(session->GetQuicVersion()),
53 session_error_(OK), 53 session_error_(ERR_UNEXPECTED),
54 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()), 54 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()),
55 stream_(nullptr), 55 stream_(nullptr),
56 request_info_(nullptr), 56 request_info_(nullptr),
57 request_body_stream_(nullptr), 57 request_body_stream_(nullptr),
58 priority_(MINIMUM_PRIORITY), 58 priority_(MINIMUM_PRIORITY),
59 response_info_(nullptr), 59 response_info_(nullptr),
60 response_status_(OK), 60 has_response_status_(false),
61 response_status_(ERR_UNEXPECTED),
61 response_headers_received_(false), 62 response_headers_received_(false),
62 headers_bytes_received_(0), 63 headers_bytes_received_(0),
63 headers_bytes_sent_(0), 64 headers_bytes_sent_(0),
64 closed_stream_received_bytes_(0), 65 closed_stream_received_bytes_(0),
65 closed_stream_sent_bytes_(0), 66 closed_stream_sent_bytes_(0),
66 closed_is_first_stream_(false), 67 closed_is_first_stream_(false),
67 user_buffer_len_(0), 68 user_buffer_len_(0),
68 quic_connection_error_(QUIC_NO_ERROR), 69 quic_connection_error_(QUIC_NO_ERROR),
70 quic_stream_error_(QUIC_STREAM_NO_ERROR),
69 port_migration_detected_(false), 71 port_migration_detected_(false),
70 found_promise_(false), 72 found_promise_(false),
71 push_handle_(nullptr), 73 push_handle_(nullptr),
72 in_loop_(false), 74 in_loop_(false),
73 weak_factory_(this) { 75 weak_factory_(this) {
74 DCHECK(session_); 76 DCHECK(session_);
75 session_->AddObserver(this); 77 session_->AddObserver(this);
76 } 78 }
77 79
78 QuicHttpStream::~QuicHttpStream() { 80 QuicHttpStream::~QuicHttpStream() {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION; 153 return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION;
152 } 154 }
153 155
154 int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info, 156 int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info,
155 RequestPriority priority, 157 RequestPriority priority,
156 const NetLogWithSource& stream_net_log, 158 const NetLogWithSource& stream_net_log,
157 const CompletionCallback& callback) { 159 const CompletionCallback& callback) {
158 CHECK(callback_.is_null()); 160 CHECK(callback_.is_null());
159 DCHECK(!stream_); 161 DCHECK(!stream_);
160 if (!session_) 162 if (!session_)
161 return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED 163 return GetResponseStatus();
162 : ERR_QUIC_HANDSHAKE_FAILED;
163 164
164 stream_net_log.AddEvent( 165 stream_net_log.AddEvent(
165 NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION, 166 NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION,
166 session_->net_log().source().ToEventParametersCallback()); 167 session_->net_log().source().ToEventParametersCallback());
167 168
168 stream_net_log_ = stream_net_log; 169 stream_net_log_ = stream_net_log;
169 request_info_ = request_info; 170 request_info_ = request_info;
170 request_time_ = base::Time::Now(); 171 request_time_ = base::Time::Now();
171 priority_ = priority; 172 priority_ = priority;
172 173
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 // TODO(rch): remove this once we figure out why channel ID is not being 244 // TODO(rch): remove this once we figure out why channel ID is not being
244 // sent when it should be. 245 // sent when it should be.
245 HostPortPair origin = HostPortPair::FromURL(request_info_->url); 246 HostPortPair origin = HostPortPair::FromURL(request_info_->url);
246 if (origin.Equals(HostPortPair("accounts.google.com", 443)) && 247 if (origin.Equals(HostPortPair("accounts.google.com", 443)) &&
247 request_headers.HasHeader(HttpRequestHeaders::kCookie)) { 248 request_headers.HasHeader(HttpRequestHeaders::kCookie)) {
248 SSLInfo ssl_info; 249 SSLInfo ssl_info;
249 GetSSLInfo(&ssl_info); 250 GetSSLInfo(&ssl_info);
250 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.CookieSentToAccountsOverChannelId", 251 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.CookieSentToAccountsOverChannelId",
251 ssl_info.channel_id_sent); 252 ssl_info.channel_id_sent);
252 } 253 }
253 if ((!found_promise_ && !stream_) || !session_) { 254
254 return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED 255 if ((!found_promise_ && !stream_) || !session_)
255 : ERR_QUIC_HANDSHAKE_FAILED; 256 return GetResponseStatus();
256 }
257 257
258 // Store the serialized request headers. 258 // Store the serialized request headers.
259 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, 259 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
260 /*direct=*/true, &request_headers_); 260 /*direct=*/true, &request_headers_);
261 261
262 // Store the request body. 262 // Store the request body.
263 request_body_stream_ = request_info_->upload_data_stream; 263 request_body_stream_ = request_info_->upload_data_stream;
264 if (request_body_stream_) { 264 if (request_body_stream_) {
265 // A request with a body is ineligible for push, so reset the 265 // A request with a body is ineligible for push, so reset the
266 // promised stream and request a new stream. 266 // promised stream and request a new stream.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 callback_ = callback; 303 callback_ = callback;
304 304
305 return rv > 0 ? OK : rv; 305 return rv > 0 ? OK : rv;
306 } 306 }
307 307
308 int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { 308 int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
309 CHECK(callback_.is_null()); 309 CHECK(callback_.is_null());
310 CHECK(!callback.is_null()); 310 CHECK(!callback.is_null());
311 311
312 if (stream_ == nullptr) 312 if (stream_ == nullptr)
313 return response_status_; 313 return GetResponseStatus();
314 314
315 // Check if we already have the response headers. If so, return synchronously. 315 // Check if we already have the response headers. If so, return synchronously.
316 if (response_headers_received_) 316 if (response_headers_received_)
317 return OK; 317 return OK;
318 318
319 // Still waiting for the response, return IO_PENDING. 319 // Still waiting for the response, return IO_PENDING.
320 CHECK(callback_.is_null()); 320 CHECK(callback_.is_null());
321 callback_ = callback; 321 callback_ = callback;
322 return ERR_IO_PENDING; 322 return ERR_IO_PENDING;
323 } 323 }
324 324
325 int QuicHttpStream::ReadResponseBody(IOBuffer* buf, 325 int QuicHttpStream::ReadResponseBody(IOBuffer* buf,
326 int buf_len, 326 int buf_len,
327 const CompletionCallback& callback) { 327 const CompletionCallback& callback) {
328 CHECK(callback_.is_null()); 328 CHECK(callback_.is_null());
329 CHECK(!callback.is_null()); 329 CHECK(!callback.is_null());
330 CHECK(!user_buffer_.get()); 330 CHECK(!user_buffer_.get());
331 CHECK_EQ(0, user_buffer_len_); 331 CHECK_EQ(0, user_buffer_len_);
332 332
333 // Invalidate HttpRequestInfo pointer. This is to allow the stream to be 333 // Invalidate HttpRequestInfo pointer. This is to allow the stream to be
334 // shared across multiple transactions which might require this 334 // shared across multiple transactions which might require this
335 // stream to outlive the request_info_'s owner. 335 // stream to outlive the request_info_'s owner.
336 // Only allowed when Read state machine starts. It is safe to reset it at 336 // Only allowed when Read state machine starts. It is safe to reset it at
337 // this point since request_info_->upload_data_stream is also not needed 337 // this point since request_info_->upload_data_stream is also not needed
338 // anymore. 338 // anymore.
339 request_info_ = nullptr; 339 request_info_ = nullptr;
340 340
341 if (!stream_) { 341 // If the stream is already closed, there is no body to read.
342 // If the stream is already closed, there is no body to read. 342 if (!stream_)
343 return response_status_; 343 return GetResponseStatus();
344 }
345 344
346 int rv = ReadAvailableData(buf, buf_len); 345 int rv = ReadAvailableData(buf, buf_len);
347 if (rv != ERR_IO_PENDING) 346 if (rv != ERR_IO_PENDING)
348 return rv; 347 return rv;
349 348
350 callback_ = callback; 349 callback_ = callback;
351 user_buffer_ = buf; 350 user_buffer_ = buf;
352 user_buffer_len_ = buf_len; 351 user_buffer_len_ = buf_len;
353 return ERR_IO_PENDING; 352 return ERR_IO_PENDING;
354 } 353 }
355 354
356 void QuicHttpStream::Close(bool not_reusable) { 355 void QuicHttpStream::Close(bool /*not_reusable*/) {
357 // Note: the not_reusable flag has no meaning for SPDY streams. 356 GetResponseStatus(); // Sets response_status_ if not already set.
357 // Note: the not_reusable flag has no meaning for QUIC streams.
358 if (stream_) { 358 if (stream_) {
359 stream_->SetDelegate(nullptr); 359 stream_->SetDelegate(nullptr);
360 stream_->Reset(QUIC_STREAM_CANCELLED); 360 stream_->Reset(QUIC_STREAM_CANCELLED);
361 response_status_ = was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED
362 : ERR_QUIC_HANDSHAKE_FAILED;
363 } 361 }
364 ResetStream(); 362 ResetStream();
365 } 363 }
366 364
367 bool QuicHttpStream::IsResponseBodyComplete() const { 365 bool QuicHttpStream::IsResponseBodyComplete() const {
368 return next_state_ == STATE_OPEN && !stream_; 366 return next_state_ == STATE_OPEN && !stream_;
369 } 367 }
370 368
371 bool QuicHttpStream::IsConnectionReused() const { 369 bool QuicHttpStream::IsConnectionReused() const {
372 // TODO(rch): do something smarter here. 370 // TODO(rch): do something smarter here.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 void QuicHttpStream::OnHeadersAvailable(const SpdyHeaderBlock& headers, 429 void QuicHttpStream::OnHeadersAvailable(const SpdyHeaderBlock& headers,
432 size_t frame_len) { 430 size_t frame_len) {
433 headers_bytes_received_ += frame_len; 431 headers_bytes_received_ += frame_len;
434 432
435 // QuicHttpStream ignores trailers. 433 // QuicHttpStream ignores trailers.
436 if (response_headers_received_) { 434 if (response_headers_received_) {
437 if (stream_->IsDoneReading()) { 435 if (stream_->IsDoneReading()) {
438 // Close the read side. If the write side has been closed, this will 436 // Close the read side. If the write side has been closed, this will
439 // invoke QuicHttpStream::OnClose to reset the stream. 437 // invoke QuicHttpStream::OnClose to reset the stream.
440 stream_->OnFinRead(); 438 stream_->OnFinRead();
439 SetResponseStatus(OK);
441 } 440 }
442 return; 441 return;
443 } 442 }
444 443
445 int rv = ProcessResponseHeaders(headers); 444 int rv = ProcessResponseHeaders(headers);
446 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 445 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
447 DoCallback(rv); 446 DoCallback(rv);
448 } 447 }
449 } 448 }
450 449
(...skipping 11 matching lines...) Expand all
462 return; 461 return;
463 } 462 }
464 463
465 CHECK(!callback_.is_null()); 464 CHECK(!callback_.is_null());
466 user_buffer_ = nullptr; 465 user_buffer_ = nullptr;
467 user_buffer_len_ = 0; 466 user_buffer_len_ = 0;
468 DoCallback(rv); 467 DoCallback(rv);
469 } 468 }
470 469
471 void QuicHttpStream::OnClose() { 470 void QuicHttpStream::OnClose() {
472 if (stream_->connection_error() != QUIC_NO_ERROR || 471 quic_connection_error_ = stream_->connection_error();
473 stream_->stream_error() != QUIC_STREAM_NO_ERROR) { 472 quic_stream_error_ = stream_->stream_error();
474 response_status_ = was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR 473 GetResponseStatus(); // Sets response_status_ if not already set.
475 : ERR_QUIC_HANDSHAKE_FAILED;
476 } else if (!response_headers_received_) {
477 response_status_ = ERR_ABORTED;
478 }
479 474
480 quic_connection_error_ = stream_->connection_error();
481 ResetStream(); 475 ResetStream();
482 if (in_loop_) { 476 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits.
483 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. 477 if (in_loop_)
484 return; 478 return;
485 } 479
486 if (!callback_.is_null()) { 480 if (!callback_.is_null()) {
487 DoCallback(response_status_); 481 DoCallback(GetResponseStatus());
Buck 2017/03/28 21:19:57 Why not use a cached result from the call above?
Ryan Hamilton 2017/03/28 21:54:03 Done. Good idea! (Well, and then it changed as a
488 } 482 }
489 } 483 }
490 484
491 void QuicHttpStream::OnError(int error) { 485 void QuicHttpStream::OnError(int error) {
492 ResetStream(); 486 ResetStream();
493 response_status_ = 487 session_error_ = error;
494 was_handshake_confirmed_ ? error : ERR_QUIC_HANDSHAKE_FAILED; 488 GetResponseStatus(); // Sets response_status_ if not already set.
495 if (in_loop_) { 489 if (in_loop_) {
496 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. 490 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits.
497 return; 491 return;
498 } 492 }
499 if (!callback_.is_null()) 493 if (!callback_.is_null())
500 DoCallback(response_status_); 494 DoCallback(GetResponseStatus());
501 } 495 }
502 496
503 bool QuicHttpStream::HasSendHeadersComplete() { 497 bool QuicHttpStream::HasSendHeadersComplete() {
504 return next_state_ > STATE_SEND_HEADERS_COMPLETE; 498 return next_state_ > STATE_SEND_HEADERS_COMPLETE;
505 } 499 }
506 500
507 void QuicHttpStream::OnCryptoHandshakeConfirmed() { 501 void QuicHttpStream::OnCryptoHandshakeConfirmed() {
508 was_handshake_confirmed_ = true; 502 was_handshake_confirmed_ = true;
509 if (next_state_ == STATE_WAIT_FOR_CONFIRMATION_COMPLETE) { 503 if (next_state_ == STATE_WAIT_FOR_CONFIRMATION_COMPLETE) {
510 // Post a task to avoid reentrant calls into the session. 504 // Post a task to avoid reentrant calls into the session.
511 base::ThreadTaskRunnerHandle::Get()->PostTask( 505 base::ThreadTaskRunnerHandle::Get()->PostTask(
512 FROM_HERE, base::Bind(&QuicHttpStream::OnIOComplete, 506 FROM_HERE, base::Bind(&QuicHttpStream::OnIOComplete,
513 weak_factory_.GetWeakPtr(), OK)); 507 weak_factory_.GetWeakPtr(), OK));
514 } 508 }
515 } 509 }
516 510
517 void QuicHttpStream::OnSuccessfulVersionNegotiation( 511 void QuicHttpStream::OnSuccessfulVersionNegotiation(
518 const QuicVersion& version) { 512 const QuicVersion& version) {
519 quic_version_ = version; 513 quic_version_ = version;
520 } 514 }
521 515
522 void QuicHttpStream::OnSessionClosed(int error, bool port_migration_detected) { 516 void QuicHttpStream::OnSessionClosed(int error, bool port_migration_detected) {
523 Close(false);
524 session_error_ = error; 517 session_error_ = error;
525 port_migration_detected_ = port_migration_detected; 518 port_migration_detected_ = port_migration_detected;
519 GetResponseStatus(); // Sets response_status_ if not already set.
520
521 Close(false);
526 session_.reset(); 522 session_.reset();
527 } 523 }
528 524
529 void QuicHttpStream::OnIOComplete(int rv) { 525 void QuicHttpStream::OnIOComplete(int rv) {
530 rv = DoLoop(rv); 526 rv = DoLoop(rv);
531 527
532 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 528 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
533 DoCallback(rv); 529 DoCallback(rv);
534 } 530 }
535 } 531 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 609
614 int QuicHttpStream::DoRequestStream() { 610 int QuicHttpStream::DoRequestStream() {
615 next_state_ = STATE_REQUEST_STREAM_COMPLETE; 611 next_state_ = STATE_REQUEST_STREAM_COMPLETE;
616 return stream_request_.StartRequest( 612 return stream_request_.StartRequest(
617 session_, &stream_, 613 session_, &stream_,
618 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); 614 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
619 } 615 }
620 616
621 int QuicHttpStream::DoRequestStreamComplete(int rv) { 617 int QuicHttpStream::DoRequestStreamComplete(int rv) {
622 DCHECK(rv == OK || !stream_); 618 DCHECK(rv == OK || !stream_);
623 if (rv != OK) 619 if (rv != OK) {
624 return was_handshake_confirmed_ ? rv : ERR_QUIC_HANDSHAKE_FAILED; 620 session_error_ = rv;
621 return GetResponseStatus();
622 }
625 623
626 stream_->SetDelegate(this); 624 stream_->SetDelegate(this);
627 if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) { 625 if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) {
628 stream_->DisableConnectionMigration(); 626 stream_->DisableConnectionMigration();
629 } 627 }
630 628
631 if (response_info_) { 629 if (response_info_) {
632 // This happens in the case of a asynchronous push rendezvous 630 // This happens in the case of a asynchronous push rendezvous
633 // that ultimately fails (e.g. vary failure). |response_info_| 631 // that ultimately fails (e.g. vary failure). |response_info_|
634 // non-null implies that |DoRequestStream()| was called via 632 // non-null implies that |DoRequestStream()| was called via
(...skipping 26 matching lines...) Expand all
661 int QuicHttpStream::DoWaitForConfirmationComplete(int rv) { 659 int QuicHttpStream::DoWaitForConfirmationComplete(int rv) {
662 if (rv < 0) 660 if (rv < 0)
663 return rv; 661 return rv;
664 662
665 next_state_ = STATE_SEND_HEADERS; 663 next_state_ = STATE_SEND_HEADERS;
666 return OK; 664 return OK;
667 } 665 }
668 666
669 int QuicHttpStream::DoSendHeaders() { 667 int QuicHttpStream::DoSendHeaders() {
670 if (!stream_) 668 if (!stream_)
671 return ERR_UNEXPECTED; 669 return GetResponseStatus();
672 670
673 // Log the actual request with the URL Request's net log. 671 // Log the actual request with the URL Request's net log.
674 stream_net_log_.AddEvent( 672 stream_net_log_.AddEvent(
675 NetLogEventType::HTTP_TRANSACTION_QUIC_SEND_REQUEST_HEADERS, 673 NetLogEventType::HTTP_TRANSACTION_QUIC_SEND_REQUEST_HEADERS,
676 base::Bind(&QuicRequestNetLogCallback, stream_->id(), &request_headers_, 674 base::Bind(&QuicRequestNetLogCallback, stream_->id(), &request_headers_,
677 priority_)); 675 priority_));
678 bool has_upload_data = request_body_stream_ != nullptr; 676 bool has_upload_data = request_body_stream_ != nullptr;
679 677
680 next_state_ = STATE_SEND_HEADERS_COMPLETE; 678 next_state_ = STATE_SEND_HEADERS_COMPLETE;
681 size_t frame_len = stream_->WriteHeaders(std::move(request_headers_), 679 size_t frame_len = stream_->WriteHeaders(std::move(request_headers_),
682 !has_upload_data, nullptr); 680 !has_upload_data, nullptr);
683 headers_bytes_sent_ += frame_len; 681 headers_bytes_sent_ += frame_len;
684 682
685 request_headers_ = SpdyHeaderBlock(); 683 request_headers_ = SpdyHeaderBlock();
686 return static_cast<int>(frame_len); 684 return static_cast<int>(frame_len);
687 } 685 }
688 686
689 int QuicHttpStream::DoSendHeadersComplete(int rv) { 687 int QuicHttpStream::DoSendHeadersComplete(int rv) {
690 if (rv < 0) 688 if (rv < 0)
691 return rv; 689 return rv;
692 690
693 // If the stream is already closed, don't read the request body. 691 // If the stream is already closed, don't read the request body.
694 if (!stream_) 692 if (!stream_)
695 return response_status_; 693 return GetResponseStatus();
696 694
697 next_state_ = request_body_stream_ ? STATE_READ_REQUEST_BODY : STATE_OPEN; 695 next_state_ = request_body_stream_ ? STATE_READ_REQUEST_BODY : STATE_OPEN;
698 696
699 return OK; 697 return OK;
700 } 698 }
701 699
702 int QuicHttpStream::DoReadRequestBody() { 700 int QuicHttpStream::DoReadRequestBody() {
703 next_state_ = STATE_READ_REQUEST_BODY_COMPLETE; 701 next_state_ = STATE_READ_REQUEST_BODY_COMPLETE;
704 return request_body_stream_->Read( 702 return request_body_stream_->Read(
705 raw_request_body_buf_.get(), raw_request_body_buf_->size(), 703 raw_request_body_buf_.get(), raw_request_body_buf_->size(),
706 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); 704 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
707 } 705 }
708 706
709 int QuicHttpStream::DoReadRequestBodyComplete(int rv) { 707 int QuicHttpStream::DoReadRequestBodyComplete(int rv) {
710 // If the stream is already closed, don't continue. 708 // If the stream is already closed, don't continue.
711 if (!stream_) 709 if (!stream_)
712 return response_status_; 710 return GetResponseStatus();
713 711
714 // |rv| is the result of read from the request body from the last call to 712 // |rv| is the result of read from the request body from the last call to
715 // DoSendBody(). 713 // DoSendBody().
716 if (rv < 0) { 714 if (rv < 0) {
717 stream_->SetDelegate(nullptr); 715 stream_->SetDelegate(nullptr);
718 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); 716 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM);
719 ResetStream(); 717 ResetStream();
720 return rv; 718 return rv;
721 } 719 }
722 720
723 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), rv); 721 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), rv);
724 if (rv == 0) { // Reached the end. 722 if (rv == 0) { // Reached the end.
725 DCHECK(request_body_stream_->IsEOF()); 723 DCHECK(request_body_stream_->IsEOF());
726 } 724 }
727 725
728 next_state_ = STATE_SEND_BODY; 726 next_state_ = STATE_SEND_BODY;
729 return OK; 727 return OK;
730 } 728 }
731 729
732 int QuicHttpStream::DoSendBody() { 730 int QuicHttpStream::DoSendBody() {
733 if (!stream_) 731 if (!stream_)
734 return ERR_UNEXPECTED; 732 return GetResponseStatus();
735 733
736 CHECK(request_body_stream_); 734 CHECK(request_body_stream_);
737 CHECK(request_body_buf_.get()); 735 CHECK(request_body_buf_.get());
738 const bool eof = request_body_stream_->IsEOF(); 736 const bool eof = request_body_stream_->IsEOF();
739 int len = request_body_buf_->BytesRemaining(); 737 int len = request_body_buf_->BytesRemaining();
740 if (len > 0 || eof) { 738 if (len > 0 || eof) {
741 next_state_ = STATE_SEND_BODY_COMPLETE; 739 next_state_ = STATE_SEND_BODY_COMPLETE;
742 QuicStringPiece data(request_body_buf_->data(), len); 740 QuicStringPiece data(request_body_buf_->data(), len);
743 return stream_->WriteStreamData( 741 return stream_->WriteStreamData(
744 data, eof, 742 data, eof,
745 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); 743 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
746 } 744 }
747 745
748 next_state_ = STATE_OPEN; 746 next_state_ = STATE_OPEN;
749 return OK; 747 return OK;
750 } 748 }
751 749
752 int QuicHttpStream::DoSendBodyComplete(int rv) { 750 int QuicHttpStream::DoSendBodyComplete(int rv) {
753 if (rv < 0) 751 if (rv < 0)
754 return rv; 752 return rv;
755 753
756 // If the stream is already closed, don't continue. 754 // If the stream is already closed, don't continue.
757 if (!stream_) 755 if (!stream_)
758 return response_status_; 756 return GetResponseStatus();
759 757
760 request_body_buf_->DidConsume(request_body_buf_->BytesRemaining()); 758 request_body_buf_->DidConsume(request_body_buf_->BytesRemaining());
761 759
762 if (!request_body_stream_->IsEOF()) { 760 if (!request_body_stream_->IsEOF()) {
763 next_state_ = STATE_READ_REQUEST_BODY; 761 next_state_ = STATE_READ_REQUEST_BODY;
764 return OK; 762 return OK;
765 } 763 }
766 764
767 next_state_ = STATE_OPEN; 765 next_state_ = STATE_OPEN;
768 return OK; 766 return OK;
(...skipping 29 matching lines...) Expand all
798 // TODO(rtenneti): Temporary fix for crbug.com/585591. Added a check for null 796 // TODO(rtenneti): Temporary fix for crbug.com/585591. Added a check for null
799 // |stream_| to fix crash bug. Delete |stream_| check and histogram after fix 797 // |stream_| to fix crash bug. Delete |stream_| check and histogram after fix
800 // is merged. 798 // is merged.
801 bool null_stream = stream_ == nullptr; 799 bool null_stream = stream_ == nullptr;
802 UMA_HISTOGRAM_BOOLEAN("Net.QuicReadAvailableData.NullStream", null_stream); 800 UMA_HISTOGRAM_BOOLEAN("Net.QuicReadAvailableData.NullStream", null_stream);
803 if (null_stream) 801 if (null_stream)
804 return rv; 802 return rv;
805 if (stream_->IsDoneReading()) { 803 if (stream_->IsDoneReading()) {
806 stream_->SetDelegate(nullptr); 804 stream_->SetDelegate(nullptr);
807 stream_->OnFinRead(); 805 stream_->OnFinRead();
806 SetResponseStatus(OK);
808 ResetStream(); 807 ResetStream();
809 } 808 }
810 return rv; 809 return rv;
811 } 810 }
812 811
813 void QuicHttpStream::ResetStream() { 812 void QuicHttpStream::ResetStream() {
814 if (push_handle_) { 813 if (push_handle_) {
815 push_handle_->Cancel(); 814 push_handle_->Cancel();
816 push_handle_ = nullptr; 815 push_handle_ = nullptr;
817 } 816 }
818 if (!stream_) 817 if (!stream_)
819 return; 818 return;
820 DCHECK_LE(stream_->sequencer()->NumBytesConsumed(), 819 DCHECK_LE(stream_->sequencer()->NumBytesConsumed(),
821 stream_->stream_bytes_read()); 820 stream_->stream_bytes_read());
822 // Only count the uniquely received bytes. 821 // Only count the uniquely received bytes.
823 closed_stream_received_bytes_ = stream_->sequencer()->NumBytesConsumed(); 822 closed_stream_received_bytes_ = stream_->sequencer()->NumBytesConsumed();
824 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); 823 closed_stream_sent_bytes_ = stream_->stream_bytes_written();
825 closed_is_first_stream_ = stream_->IsFirstStream(); 824 closed_is_first_stream_ = stream_->IsFirstStream();
826 stream_ = nullptr; 825 stream_ = nullptr;
827 826
828 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress 827 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress
829 // read. 828 // read.
830 if (request_body_stream_) 829 if (request_body_stream_)
831 request_body_stream_->Reset(); 830 request_body_stream_->Reset();
832 } 831 }
833 832
833 int QuicHttpStream::GetResponseStatus() {
834 if (!has_response_status_) {
835 SetResponseStatus(ComputeResponseStatus());
836 }
837
838 return response_status_;
839 }
840
841 void QuicHttpStream::SetResponseStatus(int response_status) {
842 has_response_status_ = true;
843 response_status_ = response_status;
844 }
845
846 int QuicHttpStream::ComputeResponseStatus() const {
847 DCHECK(!has_response_status_);
848
849 // If the handshake has failed this will be handled by the
850 // QuicStreamFactory and HttpStreamFactory to mark QUIC as broken.
851 if (!was_handshake_confirmed_)
852 return ERR_QUIC_HANDSHAKE_FAILED;
853
854 // If the session was aborted by a higher layer, simply use that error code.
855 if (session_error_ != ERR_UNEXPECTED)
856 return session_error_;
857
858 // For bening errors, return ERR_CONNECTION_CLOSED to permit
Buck 2017/03/28 21:19:57 s/bening/benign/
Ryan Hamilton 2017/03/28 21:54:03 Done.
859 // HttpNetworkTransaction to retry the request (assuming that
860 // headers have not been received, and this is not the firs stream).
Buck 2017/03/28 21:19:57 s/firs/first/
Ryan Hamilton 2017/03/28 21:54:03 Done.
861 if ((quic_connection_error_ == QUIC_CONNECTION_IP_POOLED ||
862 quic_connection_error_ == QUIC_NETWORK_IDLE_TIMEOUT ||
863 quic_connection_error_ == QUIC_NO_ERROR) &&
864 quic_stream_error_ == QUIC_STREAM_NO_ERROR) {
865 return ERR_CONNECTION_CLOSED;
866 }
867
868 return ERR_QUIC_PROTOCOL_ERROR;
869 }
870
834 } // namespace net 871 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698