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

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: Rebase 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
« no previous file with comments | « net/quic/chromium/quic_http_stream.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 HttpServerProperties* http_server_properties) 49 HttpServerProperties* http_server_properties)
50 : MultiplexedHttpStream(MultiplexedSessionHandle(session)), 50 : MultiplexedHttpStream(MultiplexedSessionHandle(session)),
51 next_state_(STATE_NONE), 51 next_state_(STATE_NONE),
52 session_(session), 52 session_(session),
53 http_server_properties_(http_server_properties), 53 http_server_properties_(http_server_properties),
54 quic_version_(session->GetQuicVersion()), 54 quic_version_(session->GetQuicVersion()),
55 session_error_(OK), 55 session_error_(ERR_UNEXPECTED),
56 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()), 56 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()),
57 stream_(nullptr), 57 stream_(nullptr),
58 request_info_(nullptr), 58 request_info_(nullptr),
59 request_body_stream_(nullptr), 59 request_body_stream_(nullptr),
60 priority_(MINIMUM_PRIORITY), 60 priority_(MINIMUM_PRIORITY),
61 response_info_(nullptr), 61 response_info_(nullptr),
62 response_status_(OK), 62 has_response_status_(false),
63 response_status_(ERR_UNEXPECTED),
63 response_headers_received_(false), 64 response_headers_received_(false),
64 headers_bytes_received_(0), 65 headers_bytes_received_(0),
65 headers_bytes_sent_(0), 66 headers_bytes_sent_(0),
66 closed_stream_received_bytes_(0), 67 closed_stream_received_bytes_(0),
67 closed_stream_sent_bytes_(0), 68 closed_stream_sent_bytes_(0),
68 closed_is_first_stream_(false), 69 closed_is_first_stream_(false),
69 user_buffer_len_(0), 70 user_buffer_len_(0),
70 quic_connection_error_(QUIC_NO_ERROR), 71 quic_connection_error_(QUIC_NO_ERROR),
72 quic_stream_error_(QUIC_STREAM_NO_ERROR),
71 port_migration_detected_(false), 73 port_migration_detected_(false),
72 found_promise_(false), 74 found_promise_(false),
73 push_handle_(nullptr), 75 push_handle_(nullptr),
74 in_loop_(false), 76 in_loop_(false),
75 weak_factory_(this) { 77 weak_factory_(this) {
76 DCHECK(session_); 78 DCHECK(session_);
77 session_->AddObserver(this); 79 session_->AddObserver(this);
78 } 80 }
79 81
80 QuicHttpStream::~QuicHttpStream() { 82 QuicHttpStream::~QuicHttpStream() {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 const NetLogWithSource& stream_net_log, 160 const NetLogWithSource& stream_net_log,
159 const CompletionCallback& callback) { 161 const CompletionCallback& callback) {
160 CHECK(callback_.is_null()); 162 CHECK(callback_.is_null());
161 DCHECK(!stream_); 163 DCHECK(!stream_);
162 164
163 // HttpNetworkTransaction will retry any request that fails with 165 // HttpNetworkTransaction will retry any request that fails with
164 // ERR_QUIC_HANDSHAKE_FAILED. It will retry any request with 166 // ERR_QUIC_HANDSHAKE_FAILED. It will retry any request with
165 // ERR_CONNECTION_CLOSED so long as the connection has been used for other 167 // ERR_CONNECTION_CLOSED so long as the connection has been used for other
166 // streams first and headers have not yet been received. 168 // streams first and headers have not yet been received.
167 if (!session_) 169 if (!session_)
168 return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED 170 return GetResponseStatus();
169 : ERR_QUIC_HANDSHAKE_FAILED;
170 171
171 stream_net_log.AddEvent( 172 stream_net_log.AddEvent(
172 NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION, 173 NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION,
173 session_->net_log().source().ToEventParametersCallback()); 174 session_->net_log().source().ToEventParametersCallback());
174 175
175 stream_net_log_ = stream_net_log; 176 stream_net_log_ = stream_net_log;
176 request_info_ = request_info; 177 request_info_ = request_info;
177 request_time_ = base::Time::Now(); 178 request_time_ = base::Time::Now();
178 priority_ = priority; 179 priority_ = priority;
179 180
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 if (origin.Equals(HostPortPair("accounts.google.com", 443)) && 254 if (origin.Equals(HostPortPair("accounts.google.com", 443)) &&
254 request_headers.HasHeader(HttpRequestHeaders::kCookie)) { 255 request_headers.HasHeader(HttpRequestHeaders::kCookie)) {
255 SSLInfo ssl_info; 256 SSLInfo ssl_info;
256 GetSSLInfo(&ssl_info); 257 GetSSLInfo(&ssl_info);
257 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.CookieSentToAccountsOverChannelId", 258 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.CookieSentToAccountsOverChannelId",
258 ssl_info.channel_id_sent); 259 ssl_info.channel_id_sent);
259 } 260 }
260 261
261 // In order to rendezvous with a push stream, the session still needs to be 262 // In order to rendezvous with a push stream, the session still needs to be
262 // available. Otherwise the stream needs to be available. 263 // available. Otherwise the stream needs to be available.
263 if ((!found_promise_ && !stream_) || !session_) { 264 if ((!found_promise_ && !stream_) || !session_)
264 return was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED 265 return GetResponseStatus();
265 : ERR_QUIC_HANDSHAKE_FAILED;
266 }
267 266
268 // Store the serialized request headers. 267 // Store the serialized request headers.
269 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, 268 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers,
270 /*direct=*/true, &request_headers_); 269 /*direct=*/true, &request_headers_);
271 270
272 // Store the request body. 271 // Store the request body.
273 request_body_stream_ = request_info_->upload_data_stream; 272 request_body_stream_ = request_info_->upload_data_stream;
274 if (request_body_stream_) { 273 if (request_body_stream_) {
275 // A request with a body is ineligible for push, so reset the 274 // A request with a body is ineligible for push, so reset the
276 // promised stream and request a new stream. 275 // promised stream and request a new stream.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 callback_ = callback; 312 callback_ = callback;
314 313
315 return rv > 0 ? OK : rv; 314 return rv > 0 ? OK : rv;
316 } 315 }
317 316
318 int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { 317 int QuicHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
319 CHECK(callback_.is_null()); 318 CHECK(callback_.is_null());
320 CHECK(!callback.is_null()); 319 CHECK(!callback.is_null());
321 320
322 if (stream_ == nullptr) 321 if (stream_ == nullptr)
323 return response_status_; 322 return GetResponseStatus();
324 323
325 // Check if we already have the response headers. If so, return synchronously. 324 // Check if we already have the response headers. If so, return synchronously.
326 if (response_headers_received_) 325 if (response_headers_received_)
327 return OK; 326 return OK;
328 327
329 // Still waiting for the response, return IO_PENDING. 328 // Still waiting for the response, return IO_PENDING.
330 CHECK(callback_.is_null()); 329 CHECK(callback_.is_null());
331 callback_ = callback; 330 callback_ = callback;
332 return ERR_IO_PENDING; 331 return ERR_IO_PENDING;
333 } 332 }
334 333
335 int QuicHttpStream::ReadResponseBody(IOBuffer* buf, 334 int QuicHttpStream::ReadResponseBody(IOBuffer* buf,
336 int buf_len, 335 int buf_len,
337 const CompletionCallback& callback) { 336 const CompletionCallback& callback) {
338 CHECK(callback_.is_null()); 337 CHECK(callback_.is_null());
339 CHECK(!callback.is_null()); 338 CHECK(!callback.is_null());
340 CHECK(!user_buffer_.get()); 339 CHECK(!user_buffer_.get());
341 CHECK_EQ(0, user_buffer_len_); 340 CHECK_EQ(0, user_buffer_len_);
342 341
343 // Invalidate HttpRequestInfo pointer. This is to allow the stream to be 342 // Invalidate HttpRequestInfo pointer. This is to allow the stream to be
344 // shared across multiple transactions which might require this 343 // shared across multiple transactions which might require this
345 // stream to outlive the request_info_'s owner. 344 // stream to outlive the request_info_'s owner.
346 // Only allowed when Read state machine starts. It is safe to reset it at 345 // Only allowed when Read state machine starts. It is safe to reset it at
347 // this point since request_info_->upload_data_stream is also not needed 346 // this point since request_info_->upload_data_stream is also not needed
348 // anymore. 347 // anymore.
349 request_info_ = nullptr; 348 request_info_ = nullptr;
350 349
351 if (!stream_) { 350 // If the stream is already closed, there is no body to read.
352 // If the stream is already closed, there is no body to read. 351 if (!stream_)
353 return response_status_; 352 return GetResponseStatus();
354 }
355 353
356 int rv = ReadAvailableData(buf, buf_len); 354 int rv = ReadAvailableData(buf, buf_len);
357 if (rv != ERR_IO_PENDING) 355 if (rv != ERR_IO_PENDING)
358 return rv; 356 return rv;
359 357
360 callback_ = callback; 358 callback_ = callback;
361 user_buffer_ = buf; 359 user_buffer_ = buf;
362 user_buffer_len_ = buf_len; 360 user_buffer_len_ = buf_len;
363 return ERR_IO_PENDING; 361 return ERR_IO_PENDING;
364 } 362 }
365 363
366 void QuicHttpStream::Close(bool not_reusable) { 364 void QuicHttpStream::Close(bool /*not_reusable*/) {
367 // Note: the not_reusable flag has no meaning for SPDY streams. 365 SaveResponseStatus();
366 // Note: the not_reusable flag has no meaning for QUIC streams.
368 if (stream_) { 367 if (stream_) {
369 stream_->SetDelegate(nullptr); 368 stream_->SetDelegate(nullptr);
370 stream_->Reset(QUIC_STREAM_CANCELLED); 369 stream_->Reset(QUIC_STREAM_CANCELLED);
371 response_status_ = was_handshake_confirmed_ ? ERR_CONNECTION_CLOSED
372 : ERR_QUIC_HANDSHAKE_FAILED;
373 } 370 }
374 ResetStream(); 371 ResetStream();
375 } 372 }
376 373
377 bool QuicHttpStream::IsResponseBodyComplete() const { 374 bool QuicHttpStream::IsResponseBodyComplete() const {
378 return next_state_ == STATE_OPEN && !stream_; 375 return next_state_ == STATE_OPEN && !stream_;
379 } 376 }
380 377
381 bool QuicHttpStream::IsConnectionReused() const { 378 bool QuicHttpStream::IsConnectionReused() const {
382 // TODO(rch): do something smarter here. 379 // TODO(rch): do something smarter here.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 void QuicHttpStream::OnHeadersAvailable(const SpdyHeaderBlock& headers, 438 void QuicHttpStream::OnHeadersAvailable(const SpdyHeaderBlock& headers,
442 size_t frame_len) { 439 size_t frame_len) {
443 headers_bytes_received_ += frame_len; 440 headers_bytes_received_ += frame_len;
444 441
445 // QuicHttpStream ignores trailers. 442 // QuicHttpStream ignores trailers.
446 if (response_headers_received_) { 443 if (response_headers_received_) {
447 if (stream_->IsDoneReading()) { 444 if (stream_->IsDoneReading()) {
448 // Close the read side. If the write side has been closed, this will 445 // Close the read side. If the write side has been closed, this will
449 // invoke QuicHttpStream::OnClose to reset the stream. 446 // invoke QuicHttpStream::OnClose to reset the stream.
450 stream_->OnFinRead(); 447 stream_->OnFinRead();
448 SetResponseStatus(OK);
451 } 449 }
452 return; 450 return;
453 } 451 }
454 452
455 int rv = ProcessResponseHeaders(headers); 453 int rv = ProcessResponseHeaders(headers);
456 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 454 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
457 DoCallback(rv); 455 DoCallback(rv);
458 } 456 }
459 } 457 }
460 458
(...skipping 11 matching lines...) Expand all
472 return; 470 return;
473 } 471 }
474 472
475 CHECK(!callback_.is_null()); 473 CHECK(!callback_.is_null());
476 user_buffer_ = nullptr; 474 user_buffer_ = nullptr;
477 user_buffer_len_ = 0; 475 user_buffer_len_ = 0;
478 DoCallback(rv); 476 DoCallback(rv);
479 } 477 }
480 478
481 void QuicHttpStream::OnClose() { 479 void QuicHttpStream::OnClose() {
482 if (stream_->connection_error() != QUIC_NO_ERROR || 480 quic_connection_error_ = stream_->connection_error();
483 stream_->stream_error() != QUIC_STREAM_NO_ERROR) { 481 quic_stream_error_ = stream_->stream_error();
484 response_status_ = was_handshake_confirmed_ ? ERR_QUIC_PROTOCOL_ERROR 482 SaveResponseStatus();
485 : ERR_QUIC_HANDSHAKE_FAILED;
486 } else if (!response_headers_received_) {
487 response_status_ = ERR_ABORTED;
488 }
489 483
490 quic_connection_error_ = stream_->connection_error();
491 ResetStream(); 484 ResetStream();
492 if (in_loop_) { 485 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits.
493 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. 486 if (in_loop_)
494 return; 487 return;
495 } 488
496 if (!callback_.is_null()) { 489 if (!callback_.is_null()) {
497 DoCallback(response_status_); 490 DoCallback(GetResponseStatus());
498 } 491 }
499 } 492 }
500 493
501 void QuicHttpStream::OnError(int error) { 494 void QuicHttpStream::OnError(int error) {
502 ResetStream(); 495 ResetStream();
503 response_status_ = 496 session_error_ = error;
504 was_handshake_confirmed_ ? error : ERR_QUIC_HANDSHAKE_FAILED; 497 SaveResponseStatus();
505 if (in_loop_) { 498 if (in_loop_) {
506 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. 499 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits.
507 return; 500 return;
508 } 501 }
509 if (!callback_.is_null()) 502 if (!callback_.is_null())
510 DoCallback(response_status_); 503 DoCallback(GetResponseStatus());
511 } 504 }
512 505
513 bool QuicHttpStream::HasSendHeadersComplete() { 506 bool QuicHttpStream::HasSendHeadersComplete() {
514 return next_state_ > STATE_SEND_HEADERS_COMPLETE; 507 return next_state_ > STATE_SEND_HEADERS_COMPLETE;
515 } 508 }
516 509
517 void QuicHttpStream::OnCryptoHandshakeConfirmed() { 510 void QuicHttpStream::OnCryptoHandshakeConfirmed() {
518 was_handshake_confirmed_ = true; 511 was_handshake_confirmed_ = true;
519 if (next_state_ == STATE_WAIT_FOR_CONFIRMATION_COMPLETE) { 512 if (next_state_ == STATE_WAIT_FOR_CONFIRMATION_COMPLETE) {
520 // Post a task to avoid reentrant calls into the session. 513 // Post a task to avoid reentrant calls into the session.
521 base::ThreadTaskRunnerHandle::Get()->PostTask( 514 base::ThreadTaskRunnerHandle::Get()->PostTask(
522 FROM_HERE, base::Bind(&QuicHttpStream::OnIOComplete, 515 FROM_HERE, base::Bind(&QuicHttpStream::OnIOComplete,
523 weak_factory_.GetWeakPtr(), OK)); 516 weak_factory_.GetWeakPtr(), OK));
524 } 517 }
525 } 518 }
526 519
527 void QuicHttpStream::OnSuccessfulVersionNegotiation( 520 void QuicHttpStream::OnSuccessfulVersionNegotiation(
528 const QuicVersion& version) { 521 const QuicVersion& version) {
529 quic_version_ = version; 522 quic_version_ = version;
530 } 523 }
531 524
532 void QuicHttpStream::OnSessionClosed(int error, bool port_migration_detected) { 525 void QuicHttpStream::OnSessionClosed(int error, bool port_migration_detected) {
533 Close(false);
534 session_error_ = error; 526 session_error_ = error;
535 port_migration_detected_ = port_migration_detected; 527 port_migration_detected_ = port_migration_detected;
528 SaveResponseStatus();
529
530 Close(false);
536 session_.reset(); 531 session_.reset();
537 } 532 }
538 533
539 void QuicHttpStream::OnIOComplete(int rv) { 534 void QuicHttpStream::OnIOComplete(int rv) {
540 rv = DoLoop(rv); 535 rv = DoLoop(rv);
541 536
542 if (rv != ERR_IO_PENDING && !callback_.is_null()) { 537 if (rv != ERR_IO_PENDING && !callback_.is_null()) {
543 DoCallback(rv); 538 DoCallback(rv);
544 } 539 }
545 } 540 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 618
624 int QuicHttpStream::DoRequestStream() { 619 int QuicHttpStream::DoRequestStream() {
625 next_state_ = STATE_REQUEST_STREAM_COMPLETE; 620 next_state_ = STATE_REQUEST_STREAM_COMPLETE;
626 return stream_request_.StartRequest( 621 return stream_request_.StartRequest(
627 session_, &stream_, 622 session_, &stream_,
628 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); 623 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
629 } 624 }
630 625
631 int QuicHttpStream::DoRequestStreamComplete(int rv) { 626 int QuicHttpStream::DoRequestStreamComplete(int rv) {
632 DCHECK(rv == OK || !stream_); 627 DCHECK(rv == OK || !stream_);
633 if (rv != OK) 628 if (rv != OK) {
634 return was_handshake_confirmed_ ? rv : ERR_QUIC_HANDSHAKE_FAILED; 629 session_error_ = rv;
630 return GetResponseStatus();
631 }
635 632
636 stream_->SetDelegate(this); 633 stream_->SetDelegate(this);
637 if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) { 634 if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) {
638 stream_->DisableConnectionMigration(); 635 stream_->DisableConnectionMigration();
639 } 636 }
640 637
641 if (response_info_) { 638 if (response_info_) {
642 // This happens in the case of a asynchronous push rendezvous 639 // This happens in the case of a asynchronous push rendezvous
643 // that ultimately fails (e.g. vary failure). |response_info_| 640 // that ultimately fails (e.g. vary failure). |response_info_|
644 // non-null implies that |DoRequestStream()| was called via 641 // non-null implies that |DoRequestStream()| was called via
(...skipping 26 matching lines...) Expand all
671 int QuicHttpStream::DoWaitForConfirmationComplete(int rv) { 668 int QuicHttpStream::DoWaitForConfirmationComplete(int rv) {
672 if (rv < 0) 669 if (rv < 0)
673 return rv; 670 return rv;
674 671
675 next_state_ = STATE_SEND_HEADERS; 672 next_state_ = STATE_SEND_HEADERS;
676 return OK; 673 return OK;
677 } 674 }
678 675
679 int QuicHttpStream::DoSendHeaders() { 676 int QuicHttpStream::DoSendHeaders() {
680 if (!stream_) 677 if (!stream_)
681 return ERR_UNEXPECTED; 678 return GetResponseStatus();
682 679
683 // Log the actual request with the URL Request's net log. 680 // Log the actual request with the URL Request's net log.
684 stream_net_log_.AddEvent( 681 stream_net_log_.AddEvent(
685 NetLogEventType::HTTP_TRANSACTION_QUIC_SEND_REQUEST_HEADERS, 682 NetLogEventType::HTTP_TRANSACTION_QUIC_SEND_REQUEST_HEADERS,
686 base::Bind(&QuicRequestNetLogCallback, stream_->id(), &request_headers_, 683 base::Bind(&QuicRequestNetLogCallback, stream_->id(), &request_headers_,
687 priority_)); 684 priority_));
688 bool has_upload_data = request_body_stream_ != nullptr; 685 bool has_upload_data = request_body_stream_ != nullptr;
689 686
690 next_state_ = STATE_SEND_HEADERS_COMPLETE; 687 next_state_ = STATE_SEND_HEADERS_COMPLETE;
691 size_t frame_len = stream_->WriteHeaders(std::move(request_headers_), 688 size_t frame_len = stream_->WriteHeaders(std::move(request_headers_),
692 !has_upload_data, nullptr); 689 !has_upload_data, nullptr);
693 headers_bytes_sent_ += frame_len; 690 headers_bytes_sent_ += frame_len;
694 691
695 request_headers_ = SpdyHeaderBlock(); 692 request_headers_ = SpdyHeaderBlock();
696 return static_cast<int>(frame_len); 693 return static_cast<int>(frame_len);
697 } 694 }
698 695
699 int QuicHttpStream::DoSendHeadersComplete(int rv) { 696 int QuicHttpStream::DoSendHeadersComplete(int rv) {
700 if (rv < 0) 697 if (rv < 0)
701 return rv; 698 return rv;
702 699
703 // If the stream is already closed, don't read the request body. 700 // If the stream is already closed, don't read the request body.
704 if (!stream_) 701 if (!stream_)
705 return response_status_; 702 return GetResponseStatus();
706 703
707 next_state_ = request_body_stream_ ? STATE_READ_REQUEST_BODY : STATE_OPEN; 704 next_state_ = request_body_stream_ ? STATE_READ_REQUEST_BODY : STATE_OPEN;
708 705
709 return OK; 706 return OK;
710 } 707 }
711 708
712 int QuicHttpStream::DoReadRequestBody() { 709 int QuicHttpStream::DoReadRequestBody() {
713 next_state_ = STATE_READ_REQUEST_BODY_COMPLETE; 710 next_state_ = STATE_READ_REQUEST_BODY_COMPLETE;
714 return request_body_stream_->Read( 711 return request_body_stream_->Read(
715 raw_request_body_buf_.get(), raw_request_body_buf_->size(), 712 raw_request_body_buf_.get(), raw_request_body_buf_->size(),
716 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); 713 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
717 } 714 }
718 715
719 int QuicHttpStream::DoReadRequestBodyComplete(int rv) { 716 int QuicHttpStream::DoReadRequestBodyComplete(int rv) {
720 // If the stream is already closed, don't continue. 717 // If the stream is already closed, don't continue.
721 if (!stream_) 718 if (!stream_)
722 return response_status_; 719 return GetResponseStatus();
723 720
724 // |rv| is the result of read from the request body from the last call to 721 // |rv| is the result of read from the request body from the last call to
725 // DoSendBody(). 722 // DoSendBody().
726 if (rv < 0) { 723 if (rv < 0) {
727 stream_->SetDelegate(nullptr); 724 stream_->SetDelegate(nullptr);
728 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); 725 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM);
729 ResetStream(); 726 ResetStream();
730 return rv; 727 return rv;
731 } 728 }
732 729
733 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), rv); 730 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), rv);
734 if (rv == 0) { // Reached the end. 731 if (rv == 0) { // Reached the end.
735 DCHECK(request_body_stream_->IsEOF()); 732 DCHECK(request_body_stream_->IsEOF());
736 } 733 }
737 734
738 next_state_ = STATE_SEND_BODY; 735 next_state_ = STATE_SEND_BODY;
739 return OK; 736 return OK;
740 } 737 }
741 738
742 int QuicHttpStream::DoSendBody() { 739 int QuicHttpStream::DoSendBody() {
743 if (!stream_) 740 if (!stream_)
744 return ERR_UNEXPECTED; 741 return GetResponseStatus();
745 742
746 CHECK(request_body_stream_); 743 CHECK(request_body_stream_);
747 CHECK(request_body_buf_.get()); 744 CHECK(request_body_buf_.get());
748 const bool eof = request_body_stream_->IsEOF(); 745 const bool eof = request_body_stream_->IsEOF();
749 int len = request_body_buf_->BytesRemaining(); 746 int len = request_body_buf_->BytesRemaining();
750 if (len > 0 || eof) { 747 if (len > 0 || eof) {
751 next_state_ = STATE_SEND_BODY_COMPLETE; 748 next_state_ = STATE_SEND_BODY_COMPLETE;
752 QuicStringPiece data(request_body_buf_->data(), len); 749 QuicStringPiece data(request_body_buf_->data(), len);
753 return stream_->WriteStreamData( 750 return stream_->WriteStreamData(
754 data, eof, 751 data, eof,
755 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); 752 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr()));
756 } 753 }
757 754
758 next_state_ = STATE_OPEN; 755 next_state_ = STATE_OPEN;
759 return OK; 756 return OK;
760 } 757 }
761 758
762 int QuicHttpStream::DoSendBodyComplete(int rv) { 759 int QuicHttpStream::DoSendBodyComplete(int rv) {
763 if (rv < 0) 760 if (rv < 0)
764 return rv; 761 return rv;
765 762
766 // If the stream is already closed, don't continue. 763 // If the stream is already closed, don't continue.
767 if (!stream_) 764 if (!stream_)
768 return response_status_; 765 return GetResponseStatus();
769 766
770 request_body_buf_->DidConsume(request_body_buf_->BytesRemaining()); 767 request_body_buf_->DidConsume(request_body_buf_->BytesRemaining());
771 768
772 if (!request_body_stream_->IsEOF()) { 769 if (!request_body_stream_->IsEOF()) {
773 next_state_ = STATE_READ_REQUEST_BODY; 770 next_state_ = STATE_READ_REQUEST_BODY;
774 return OK; 771 return OK;
775 } 772 }
776 773
777 next_state_ = STATE_OPEN; 774 next_state_ = STATE_OPEN;
778 return OK; 775 return OK;
(...skipping 29 matching lines...) Expand all
808 // TODO(rtenneti): Temporary fix for crbug.com/585591. Added a check for null 805 // TODO(rtenneti): Temporary fix for crbug.com/585591. Added a check for null
809 // |stream_| to fix crash bug. Delete |stream_| check and histogram after fix 806 // |stream_| to fix crash bug. Delete |stream_| check and histogram after fix
810 // is merged. 807 // is merged.
811 bool null_stream = stream_ == nullptr; 808 bool null_stream = stream_ == nullptr;
812 UMA_HISTOGRAM_BOOLEAN("Net.QuicReadAvailableData.NullStream", null_stream); 809 UMA_HISTOGRAM_BOOLEAN("Net.QuicReadAvailableData.NullStream", null_stream);
813 if (null_stream) 810 if (null_stream)
814 return rv; 811 return rv;
815 if (stream_->IsDoneReading()) { 812 if (stream_->IsDoneReading()) {
816 stream_->SetDelegate(nullptr); 813 stream_->SetDelegate(nullptr);
817 stream_->OnFinRead(); 814 stream_->OnFinRead();
815 SetResponseStatus(OK);
818 ResetStream(); 816 ResetStream();
819 } 817 }
820 return rv; 818 return rv;
821 } 819 }
822 820
823 void QuicHttpStream::ResetStream() { 821 void QuicHttpStream::ResetStream() {
824 if (push_handle_) { 822 if (push_handle_) {
825 push_handle_->Cancel(); 823 push_handle_->Cancel();
826 push_handle_ = nullptr; 824 push_handle_ = nullptr;
827 } 825 }
828 if (!stream_) 826 if (!stream_)
829 return; 827 return;
830 DCHECK_LE(stream_->sequencer()->NumBytesConsumed(), 828 DCHECK_LE(stream_->sequencer()->NumBytesConsumed(),
831 stream_->stream_bytes_read()); 829 stream_->stream_bytes_read());
832 // Only count the uniquely received bytes. 830 // Only count the uniquely received bytes.
833 closed_stream_received_bytes_ = stream_->sequencer()->NumBytesConsumed(); 831 closed_stream_received_bytes_ = stream_->sequencer()->NumBytesConsumed();
834 closed_stream_sent_bytes_ = stream_->stream_bytes_written(); 832 closed_stream_sent_bytes_ = stream_->stream_bytes_written();
835 closed_is_first_stream_ = stream_->IsFirstStream(); 833 closed_is_first_stream_ = stream_->IsFirstStream();
836 stream_ = nullptr; 834 stream_ = nullptr;
837 835
838 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress 836 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress
839 // read. 837 // read.
840 if (request_body_stream_) 838 if (request_body_stream_)
841 request_body_stream_->Reset(); 839 request_body_stream_->Reset();
842 } 840 }
843 841
842 int QuicHttpStream::GetResponseStatus() {
843 SaveResponseStatus();
844 return response_status_;
845 }
846
847 void QuicHttpStream::SaveResponseStatus() {
848 if (!has_response_status_)
849 SetResponseStatus(ComputeResponseStatus());
850 }
851
852 void QuicHttpStream::SetResponseStatus(int response_status) {
853 has_response_status_ = true;
854 response_status_ = response_status;
855 }
856
857 int QuicHttpStream::ComputeResponseStatus() const {
858 DCHECK(!has_response_status_);
859
860 // If the handshake has failed this will be handled by the
861 // QuicStreamFactory and HttpStreamFactory to mark QUIC as broken.
862 if (!was_handshake_confirmed_)
863 return ERR_QUIC_HANDSHAKE_FAILED;
864
865 // If the session was aborted by a higher layer, simply use that error code.
866 if (session_error_ != ERR_UNEXPECTED)
867 return session_error_;
868
869 // If |response_info_| is null then the request has not been sent, so
870 // return ERR_CONNECTION_CLOSED to permit HttpNetworkTransaction to
871 // retry the request.
872 if (!response_info_)
873 return ERR_CONNECTION_CLOSED;
874
875 return ERR_QUIC_PROTOCOL_ERROR;
876 }
877
844 } // namespace net 878 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/chromium/quic_http_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698