| 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_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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |