Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/chromium/quic_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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |