| 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 27 matching lines...) Expand all Loading... |
| 38 NetLogCaptureMode capture_mode) { | 38 NetLogCaptureMode capture_mode) { |
| 39 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 39 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 40 dict->SetInteger("stream_id", stream_id); | 40 dict->SetInteger("stream_id", stream_id); |
| 41 dict->SetString("url", url->spec()); | 41 dict->SetString("url", url->spec()); |
| 42 return std::move(dict); | 42 return std::move(dict); |
| 43 } | 43 } |
| 44 | 44 |
| 45 } // namespace | 45 } // namespace |
| 46 | 46 |
| 47 QuicHttpStream::QuicHttpStream( | 47 QuicHttpStream::QuicHttpStream( |
| 48 const base::WeakPtr<QuicChromiumClientSession>& session, | 48 std::unique_ptr<QuicChromiumClientSession::Handle> session, |
| 49 HttpServerProperties* http_server_properties) | 49 HttpServerProperties* http_server_properties) |
| 50 : MultiplexedHttpStream(MultiplexedSessionHandle(session)), | 50 : MultiplexedHttpStream(std::move(session)), |
| 51 next_state_(STATE_NONE), | 51 next_state_(STATE_NONE), |
| 52 session_(session), | |
| 53 server_id_(session->server_id()), | |
| 54 http_server_properties_(http_server_properties), | 52 http_server_properties_(http_server_properties), |
| 55 quic_version_(session->GetQuicVersion()), | |
| 56 session_error_(ERR_UNEXPECTED), | |
| 57 was_handshake_confirmed_(session->IsCryptoHandshakeConfirmed()), | |
| 58 stream_(nullptr), | 53 stream_(nullptr), |
| 59 request_info_(nullptr), | 54 request_info_(nullptr), |
| 60 request_body_stream_(nullptr), | 55 request_body_stream_(nullptr), |
| 61 priority_(MINIMUM_PRIORITY), | 56 priority_(MINIMUM_PRIORITY), |
| 62 response_info_(nullptr), | 57 response_info_(nullptr), |
| 63 has_response_status_(false), | 58 has_response_status_(false), |
| 64 response_status_(ERR_UNEXPECTED), | 59 response_status_(ERR_UNEXPECTED), |
| 65 response_headers_received_(false), | 60 response_headers_received_(false), |
| 66 headers_bytes_received_(0), | 61 headers_bytes_received_(0), |
| 67 headers_bytes_sent_(0), | 62 headers_bytes_sent_(0), |
| 68 closed_stream_received_bytes_(0), | 63 closed_stream_received_bytes_(0), |
| 69 closed_stream_sent_bytes_(0), | 64 closed_stream_sent_bytes_(0), |
| 70 closed_is_first_stream_(false), | 65 closed_is_first_stream_(false), |
| 71 user_buffer_len_(0), | 66 user_buffer_len_(0), |
| 67 session_error_(ERR_UNEXPECTED), |
| 72 quic_connection_error_(QUIC_NO_ERROR), | 68 quic_connection_error_(QUIC_NO_ERROR), |
| 73 quic_stream_error_(QUIC_STREAM_NO_ERROR), | 69 quic_stream_error_(QUIC_STREAM_NO_ERROR), |
| 74 port_migration_detected_(false), | |
| 75 found_promise_(false), | 70 found_promise_(false), |
| 76 push_handle_(nullptr), | 71 push_handle_(nullptr), |
| 77 in_loop_(false), | 72 in_loop_(false), |
| 78 weak_factory_(this) { | 73 weak_factory_(this) {} |
| 79 DCHECK(session_); | |
| 80 session_->AddObserver(this); | |
| 81 } | |
| 82 | 74 |
| 83 QuicHttpStream::~QuicHttpStream() { | 75 QuicHttpStream::~QuicHttpStream() { |
| 84 CHECK(!in_loop_); | 76 CHECK(!in_loop_); |
| 85 Close(false); | 77 Close(false); |
| 86 if (session_) | |
| 87 session_->RemoveObserver(this); | |
| 88 } | 78 } |
| 89 | 79 |
| 90 bool QuicHttpStream::CheckVary(const SpdyHeaderBlock& client_request, | 80 bool QuicHttpStream::CheckVary(const SpdyHeaderBlock& client_request, |
| 91 const SpdyHeaderBlock& promise_request, | 81 const SpdyHeaderBlock& promise_request, |
| 92 const SpdyHeaderBlock& promise_response) { | 82 const SpdyHeaderBlock& promise_response) { |
| 93 HttpResponseInfo promise_response_info; | 83 HttpResponseInfo promise_response_info; |
| 94 | 84 |
| 95 HttpRequestInfo promise_request_info; | 85 HttpRequestInfo promise_request_info; |
| 96 ConvertHeaderBlockToHttpRequestHeaders(promise_request, | 86 ConvertHeaderBlockToHttpRequestHeaders(promise_request, |
| 97 &promise_request_info.extra_headers); | 87 &promise_request_info.extra_headers); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 RequestPriority priority, | 150 RequestPriority priority, |
| 161 const NetLogWithSource& stream_net_log, | 151 const NetLogWithSource& stream_net_log, |
| 162 const CompletionCallback& callback) { | 152 const CompletionCallback& callback) { |
| 163 CHECK(callback_.is_null()); | 153 CHECK(callback_.is_null()); |
| 164 DCHECK(!stream_); | 154 DCHECK(!stream_); |
| 165 | 155 |
| 166 // HttpNetworkTransaction will retry any request that fails with | 156 // HttpNetworkTransaction will retry any request that fails with |
| 167 // ERR_QUIC_HANDSHAKE_FAILED. It will retry any request with | 157 // ERR_QUIC_HANDSHAKE_FAILED. It will retry any request with |
| 168 // ERR_CONNECTION_CLOSED so long as the connection has been used for other | 158 // ERR_CONNECTION_CLOSED so long as the connection has been used for other |
| 169 // streams first and headers have not yet been received. | 159 // streams first and headers have not yet been received. |
| 170 if (!session_) | 160 if (!quic_session()->IsConnected()) |
| 171 return GetResponseStatus(); | 161 return GetResponseStatus(); |
| 172 | 162 |
| 173 stream_net_log.AddEvent( | 163 stream_net_log.AddEvent( |
| 174 NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION, | 164 NetLogEventType::HTTP_STREAM_REQUEST_BOUND_TO_QUIC_SESSION, |
| 175 session_->net_log().source().ToEventParametersCallback()); | 165 quic_session()->net_log().source().ToEventParametersCallback()); |
| 176 | 166 |
| 177 stream_net_log_ = stream_net_log; | 167 stream_net_log_ = stream_net_log; |
| 178 request_info_ = request_info; | 168 request_info_ = request_info; |
| 179 request_time_ = base::Time::Now(); | 169 request_time_ = base::Time::Now(); |
| 180 priority_ = priority; | 170 priority_ = priority; |
| 181 | 171 |
| 182 SaveSSLInfo(); | 172 SaveSSLInfo(); |
| 183 | 173 |
| 184 std::string url(request_info->url.spec()); | 174 std::string url(request_info->url.spec()); |
| 185 QuicClientPromisedInfo* promised = | 175 QuicClientPromisedInfo* promised = |
| 186 session_->push_promise_index()->GetPromised(url); | 176 quic_session()->GetPushPromiseIndex()->GetPromised(url); |
| 187 if (promised) { | 177 if (promised) { |
| 188 found_promise_ = true; | 178 found_promise_ = true; |
| 189 stream_net_log_.AddEvent( | 179 stream_net_log_.AddEvent( |
| 190 NetLogEventType::QUIC_HTTP_STREAM_PUSH_PROMISE_RENDEZVOUS, | 180 NetLogEventType::QUIC_HTTP_STREAM_PUSH_PROMISE_RENDEZVOUS, |
| 191 base::Bind(&NetLogQuicPushStreamCallback, promised->id(), | 181 base::Bind(&NetLogQuicPushStreamCallback, promised->id(), |
| 192 &request_info_->url)); | 182 &request_info_->url)); |
| 193 session_->net_log().AddEvent( | 183 quic_session()->net_log().AddEvent( |
| 194 NetLogEventType::QUIC_HTTP_STREAM_PUSH_PROMISE_RENDEZVOUS, | 184 NetLogEventType::QUIC_HTTP_STREAM_PUSH_PROMISE_RENDEZVOUS, |
| 195 base::Bind(&NetLogQuicPushStreamCallback, promised->id(), | 185 base::Bind(&NetLogQuicPushStreamCallback, promised->id(), |
| 196 &request_info_->url)); | 186 &request_info_->url)); |
| 197 return OK; | 187 return OK; |
| 198 } | 188 } |
| 199 | 189 |
| 200 next_state_ = STATE_REQUEST_STREAM; | 190 next_state_ = STATE_REQUEST_STREAM; |
| 201 int rv = DoLoop(OK); | 191 int rv = DoLoop(OK); |
| 202 if (rv == ERR_IO_PENDING) | 192 if (rv == ERR_IO_PENDING) |
| 203 callback_ = callback; | 193 callback_ = callback; |
| 204 | 194 |
| 205 return rv; | 195 return rv; |
| 206 } | 196 } |
| 207 | 197 |
| 208 int QuicHttpStream::DoHandlePromise() { | 198 int QuicHttpStream::DoHandlePromise() { |
| 209 QuicAsyncStatus push_status = session_->push_promise_index()->Try( | 199 QuicAsyncStatus push_status = quic_session()->GetPushPromiseIndex()->Try( |
| 210 request_headers_, this, &this->push_handle_); | 200 request_headers_, this, &this->push_handle_); |
| 211 | 201 |
| 212 switch (push_status) { | 202 switch (push_status) { |
| 213 case QUIC_FAILURE: | 203 case QUIC_FAILURE: |
| 214 // Push rendezvous failed. | 204 // Push rendezvous failed. |
| 215 next_state_ = STATE_REQUEST_STREAM; | 205 next_state_ = STATE_REQUEST_STREAM; |
| 216 break; | 206 break; |
| 217 case QUIC_SUCCESS: | 207 case QUIC_SUCCESS: |
| 218 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; | 208 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; |
| 219 break; | 209 break; |
| 220 case QUIC_PENDING: | 210 case QUIC_PENDING: |
| 221 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; | 211 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; |
| 222 return ERR_IO_PENDING; | 212 return ERR_IO_PENDING; |
| 223 } | 213 } |
| 224 return OK; | 214 return OK; |
| 225 } | 215 } |
| 226 | 216 |
| 227 int QuicHttpStream::DoHandlePromiseComplete(int rv) { | 217 int QuicHttpStream::DoHandlePromiseComplete(int rv) { |
| 228 if (rv != OK) | 218 if (rv != OK) |
| 229 return rv; | 219 return rv; |
| 230 | 220 |
| 231 next_state_ = STATE_OPEN; | 221 next_state_ = STATE_OPEN; |
| 232 stream_net_log_.AddEvent( | 222 stream_net_log_.AddEvent( |
| 233 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, | 223 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, |
| 234 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), | 224 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), |
| 235 &request_info_->url)); | 225 &request_info_->url)); |
| 236 session_->net_log().AddEvent( | 226 quic_session()->net_log().AddEvent( |
| 237 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, | 227 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, |
| 238 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), | 228 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), |
| 239 &request_info_->url)); | 229 &request_info_->url)); |
| 240 return OK; | 230 return OK; |
| 241 } | 231 } |
| 242 | 232 |
| 243 int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers, | 233 int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers, |
| 244 HttpResponseInfo* response, | 234 HttpResponseInfo* response, |
| 245 const CompletionCallback& callback) { | 235 const CompletionCallback& callback) { |
| 246 CHECK(!request_body_stream_); | 236 CHECK(!request_body_stream_); |
| 247 CHECK(!response_info_); | 237 CHECK(!response_info_); |
| 248 CHECK(callback_.is_null()); | 238 CHECK(callback_.is_null()); |
| 249 CHECK(!callback.is_null()); | 239 CHECK(!callback.is_null()); |
| 250 CHECK(response); | 240 CHECK(response); |
| 251 | 241 |
| 252 // TODO(rch): remove this once we figure out why channel ID is not being | 242 // TODO(rch): remove this once we figure out why channel ID is not being |
| 253 // sent when it should be. | 243 // sent when it should be. |
| 254 HostPortPair origin = HostPortPair::FromURL(request_info_->url); | 244 HostPortPair origin = HostPortPair::FromURL(request_info_->url); |
| 255 if (origin.Equals(HostPortPair("accounts.google.com", 443)) && | 245 if (origin.Equals(HostPortPair("accounts.google.com", 443)) && |
| 256 request_headers.HasHeader(HttpRequestHeaders::kCookie)) { | 246 request_headers.HasHeader(HttpRequestHeaders::kCookie)) { |
| 257 SSLInfo ssl_info; | 247 SSLInfo ssl_info; |
| 258 GetSSLInfo(&ssl_info); | 248 GetSSLInfo(&ssl_info); |
| 259 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.CookieSentToAccountsOverChannelId", | 249 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.CookieSentToAccountsOverChannelId", |
| 260 ssl_info.channel_id_sent); | 250 ssl_info.channel_id_sent); |
| 261 } | 251 } |
| 262 | 252 |
| 263 // In order to rendezvous with a push stream, the session still needs to be | 253 // In order to rendezvous with a push stream, the session still needs to be |
| 264 // available. Otherwise the stream needs to be available. | 254 // available. Otherwise the stream needs to be available. |
| 265 if ((!found_promise_ && !stream_) || !session_) | 255 if ((!found_promise_ && !stream_) || !quic_session()->IsConnected()) |
| 266 return GetResponseStatus(); | 256 return GetResponseStatus(); |
| 267 | 257 |
| 268 // Store the serialized request headers. | 258 // Store the serialized request headers. |
| 269 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, | 259 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, |
| 270 /*direct=*/true, &request_headers_); | 260 /*direct=*/true, &request_headers_); |
| 271 | 261 |
| 272 // Store the request body. | 262 // Store the request body. |
| 273 request_body_stream_ = request_info_->upload_data_stream; | 263 request_body_stream_ = request_info_->upload_data_stream; |
| 274 if (request_body_stream_) { | 264 if (request_body_stream_) { |
| 275 // 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 |
| 276 // promised stream and request a new stream. | 266 // promised stream and request a new stream. |
| 277 if (found_promise_) { | 267 if (found_promise_) { |
| 278 std::string url(request_info_->url.spec()); | 268 std::string url(request_info_->url.spec()); |
| 279 QuicClientPromisedInfo* promised = | 269 QuicClientPromisedInfo* promised = |
| 280 session_->push_promise_index()->GetPromised(url); | 270 quic_session()->GetPushPromiseIndex()->GetPromised(url); |
| 281 if (promised != nullptr) { | 271 if (promised != nullptr) { |
| 282 session_->ResetPromised(promised->id(), QUIC_STREAM_CANCELLED); | 272 quic_session()->ResetPromised(promised->id(), QUIC_STREAM_CANCELLED); |
| 283 } | 273 } |
| 284 } | 274 } |
| 285 | 275 |
| 286 // TODO(rch): Can we be more precise about when to allocate | 276 // TODO(rch): Can we be more precise about when to allocate |
| 287 // raw_request_body_buf_. Removed the following check. DoReadRequestBody() | 277 // raw_request_body_buf_. Removed the following check. DoReadRequestBody() |
| 288 // was being called even if we didn't yet allocate raw_request_body_buf_. | 278 // was being called even if we didn't yet allocate raw_request_body_buf_. |
| 289 // && (request_body_stream_->size() || | 279 // && (request_body_stream_->size() || |
| 290 // request_body_stream_->is_chunked())) | 280 // request_body_stream_->is_chunked())) |
| 291 // Use 10 packets as the body buffer size to give enough space to | 281 // Use 10 packets as the body buffer size to give enough space to |
| 292 // help ensure we don't often send out partial packets. | 282 // help ensure we don't often send out partial packets. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 load_timing_info->connect_timing = connect_timing_; | 409 load_timing_info->connect_timing = connect_timing_; |
| 420 } else { | 410 } else { |
| 421 load_timing_info->socket_reused = true; | 411 load_timing_info->socket_reused = true; |
| 422 } | 412 } |
| 423 return true; | 413 return true; |
| 424 } | 414 } |
| 425 | 415 |
| 426 bool QuicHttpStream::GetAlternativeService( | 416 bool QuicHttpStream::GetAlternativeService( |
| 427 AlternativeService* alternative_service) const { | 417 AlternativeService* alternative_service) const { |
| 428 alternative_service->protocol = kProtoQUIC; | 418 alternative_service->protocol = kProtoQUIC; |
| 429 alternative_service->host = server_id_.host(); | 419 alternative_service->host = quic_session()->server_id().host(); |
| 430 alternative_service->port = server_id_.port(); | 420 alternative_service->port = quic_session()->server_id().port(); |
| 431 return true; | 421 return true; |
| 432 } | 422 } |
| 433 | 423 |
| 434 void QuicHttpStream::PopulateNetErrorDetails(NetErrorDetails* details) { | 424 void QuicHttpStream::PopulateNetErrorDetails(NetErrorDetails* details) { |
| 435 details->connection_info = ConnectionInfoFromQuicVersion(quic_version_); | 425 details->connection_info = |
| 436 if (was_handshake_confirmed_) | 426 ConnectionInfoFromQuicVersion(quic_session()->GetQuicVersion()); |
| 427 quic_session()->PopulateNetErrorDetails(details); |
| 428 if (quic_session()->IsCryptoHandshakeConfirmed()) |
| 437 details->quic_connection_error = quic_connection_error_; | 429 details->quic_connection_error = quic_connection_error_; |
| 438 if (session_) { | |
| 439 session_->PopulateNetErrorDetails(details); | |
| 440 } else { | |
| 441 details->quic_port_migration_detected = port_migration_detected_; | |
| 442 } | |
| 443 } | 430 } |
| 444 | 431 |
| 445 void QuicHttpStream::SetPriority(RequestPriority priority) { | 432 void QuicHttpStream::SetPriority(RequestPriority priority) { |
| 446 priority_ = priority; | 433 priority_ = priority; |
| 447 } | 434 } |
| 448 | 435 |
| 449 void QuicHttpStream::OnHeadersAvailable(const SpdyHeaderBlock& headers, | 436 void QuicHttpStream::OnHeadersAvailable(const SpdyHeaderBlock& headers, |
| 450 size_t frame_len) { | 437 size_t frame_len) { |
| 451 headers_bytes_received_ += frame_len; | 438 headers_bytes_received_ += frame_len; |
| 452 | 439 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 session_error_ = error; | 494 session_error_ = error; |
| 508 SaveResponseStatus(); | 495 SaveResponseStatus(); |
| 509 if (in_loop_) { | 496 if (in_loop_) { |
| 510 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. | 497 // If already in DoLoop(), |callback_| will be handled when DoLoop() exits. |
| 511 return; | 498 return; |
| 512 } | 499 } |
| 513 if (!callback_.is_null()) | 500 if (!callback_.is_null()) |
| 514 DoCallback(GetResponseStatus()); | 501 DoCallback(GetResponseStatus()); |
| 515 } | 502 } |
| 516 | 503 |
| 517 void QuicHttpStream::OnCryptoHandshakeConfirmed() { | |
| 518 was_handshake_confirmed_ = true; | |
| 519 } | |
| 520 | |
| 521 void QuicHttpStream::OnSuccessfulVersionNegotiation( | |
| 522 const QuicVersion& version) { | |
| 523 quic_version_ = version; | |
| 524 } | |
| 525 | |
| 526 void QuicHttpStream::OnSessionClosed(int error, bool port_migration_detected) { | |
| 527 session_error_ = error; | |
| 528 port_migration_detected_ = port_migration_detected; | |
| 529 SaveResponseStatus(); | |
| 530 | |
| 531 Close(false); | |
| 532 session_.reset(); | |
| 533 } | |
| 534 | |
| 535 void QuicHttpStream::OnIOComplete(int rv) { | 504 void QuicHttpStream::OnIOComplete(int rv) { |
| 536 rv = DoLoop(rv); | 505 rv = DoLoop(rv); |
| 537 | 506 |
| 538 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 507 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 539 DoCallback(rv); | 508 DoCallback(rv); |
| 540 } | 509 } |
| 541 } | 510 } |
| 542 | 511 |
| 543 void QuicHttpStream::DoCallback(int rv) { | 512 void QuicHttpStream::DoCallback(int rv) { |
| 544 CHECK_NE(rv, ERR_IO_PENDING); | 513 CHECK_NE(rv, ERR_IO_PENDING); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 break; | 574 break; |
| 606 } | 575 } |
| 607 } while (next_state_ != STATE_NONE && next_state_ != STATE_OPEN && | 576 } while (next_state_ != STATE_NONE && next_state_ != STATE_OPEN && |
| 608 rv != ERR_IO_PENDING); | 577 rv != ERR_IO_PENDING); |
| 609 | 578 |
| 610 return rv; | 579 return rv; |
| 611 } | 580 } |
| 612 | 581 |
| 613 int QuicHttpStream::DoRequestStream() { | 582 int QuicHttpStream::DoRequestStream() { |
| 614 next_state_ = STATE_REQUEST_STREAM_COMPLETE; | 583 next_state_ = STATE_REQUEST_STREAM_COMPLETE; |
| 615 stream_request_ = | 584 return quic_session()->RequestStream( |
| 616 session_->CreateStreamRequest(request_info_->method == "POST"); | 585 request_info_->method == "POST", |
| 617 return stream_request_->StartRequest( | |
| 618 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); | 586 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); |
| 619 } | 587 } |
| 620 | 588 |
| 621 int QuicHttpStream::DoRequestStreamComplete(int rv) { | 589 int QuicHttpStream::DoRequestStreamComplete(int rv) { |
| 622 DCHECK(rv == OK || !stream_); | 590 DCHECK(rv == OK || !stream_); |
| 623 if (rv != OK) { | 591 if (rv != OK) { |
| 624 session_error_ = rv; | 592 session_error_ = rv; |
| 625 return GetResponseStatus(); | 593 return GetResponseStatus(); |
| 626 } | 594 } |
| 627 | 595 |
| 628 stream_ = stream_request_->ReleaseStream(); | 596 stream_ = quic_session()->ReleaseStream(); |
| 629 stream_request_.reset(); | |
| 630 stream_->SetDelegate(this); | 597 stream_->SetDelegate(this); |
| 631 if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) { | 598 if (request_info_->load_flags & LOAD_DISABLE_CONNECTION_MIGRATION) { |
| 632 stream_->DisableConnectionMigration(); | 599 stream_->DisableConnectionMigration(); |
| 633 } | 600 } |
| 634 | 601 |
| 635 if (response_info_) { | 602 if (response_info_) { |
| 636 // This happens in the case of a asynchronous push rendezvous | 603 // This happens in the case of a asynchronous push rendezvous |
| 637 // that ultimately fails (e.g. vary failure). |response_info_| | 604 // that ultimately fails (e.g. vary failure). |response_info_| |
| 638 // non-null implies that |DoRequestStream()| was called via | 605 // non-null implies that |DoRequestStream()| was called via |
| 639 // |SendRequest()|. | 606 // |SendRequest()|. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 next_state_ = STATE_OPEN; | 721 next_state_ = STATE_OPEN; |
| 755 return OK; | 722 return OK; |
| 756 } | 723 } |
| 757 | 724 |
| 758 int QuicHttpStream::ProcessResponseHeaders(const SpdyHeaderBlock& headers) { | 725 int QuicHttpStream::ProcessResponseHeaders(const SpdyHeaderBlock& headers) { |
| 759 if (!SpdyHeadersToHttpResponse(headers, response_info_)) { | 726 if (!SpdyHeadersToHttpResponse(headers, response_info_)) { |
| 760 DLOG(WARNING) << "Invalid headers"; | 727 DLOG(WARNING) << "Invalid headers"; |
| 761 return ERR_QUIC_PROTOCOL_ERROR; | 728 return ERR_QUIC_PROTOCOL_ERROR; |
| 762 } | 729 } |
| 763 // Put the peer's IP address and port into the response. | 730 // Put the peer's IP address and port into the response. |
| 764 IPEndPoint address = session_->peer_address().impl().socket_address(); | 731 IPEndPoint address; |
| 732 int rv = quic_session()->GetPeerAddress(&address); |
| 733 if (rv != OK) |
| 734 return rv; |
| 735 |
| 765 response_info_->socket_address = HostPortPair::FromIPEndPoint(address); | 736 response_info_->socket_address = HostPortPair::FromIPEndPoint(address); |
| 766 response_info_->connection_info = | 737 response_info_->connection_info = |
| 767 ConnectionInfoFromQuicVersion(quic_version_); | 738 ConnectionInfoFromQuicVersion(quic_session()->GetQuicVersion()); |
| 768 response_info_->vary_data.Init(*request_info_, | 739 response_info_->vary_data.Init(*request_info_, |
| 769 *response_info_->headers.get()); | 740 *response_info_->headers.get()); |
| 770 response_info_->was_alpn_negotiated = true; | 741 response_info_->was_alpn_negotiated = true; |
| 771 response_info_->alpn_negotiated_protocol = | 742 response_info_->alpn_negotiated_protocol = |
| 772 HttpResponseInfo::ConnectionInfoToString(response_info_->connection_info); | 743 HttpResponseInfo::ConnectionInfoToString(response_info_->connection_info); |
| 773 response_info_->response_time = base::Time::Now(); | 744 response_info_->response_time = base::Time::Now(); |
| 774 response_info_->request_time = request_time_; | 745 response_info_->request_time = request_time_; |
| 775 response_headers_received_ = true; | 746 response_headers_received_ = true; |
| 776 | 747 |
| 777 // Populate |connect_timing_| when response headers are received. This should | 748 // Populate |connect_timing_| when response headers are received. This should |
| 778 // take care of 0-RTT where request is sent before handshake is confirmed. | 749 // take care of 0-RTT where request is sent before handshake is confirmed. |
| 779 connect_timing_ = session_->GetConnectTiming(); | 750 connect_timing_ = quic_session()->GetConnectTiming(); |
| 780 return OK; | 751 return OK; |
| 781 } | 752 } |
| 782 | 753 |
| 783 int QuicHttpStream::ReadAvailableData(IOBuffer* buf, int buf_len) { | 754 int QuicHttpStream::ReadAvailableData(IOBuffer* buf, int buf_len) { |
| 784 int rv = stream_->Read(buf, buf_len); | 755 int rv = stream_->Read(buf, buf_len); |
| 785 // TODO(rtenneti): Temporary fix for crbug.com/585591. Added a check for null | 756 // TODO(rtenneti): Temporary fix for crbug.com/585591. Added a check for null |
| 786 // |stream_| to fix crash bug. Delete |stream_| check and histogram after fix | 757 // |stream_| to fix crash bug. Delete |stream_| check and histogram after fix |
| 787 // is merged. | 758 // is merged. |
| 788 bool null_stream = stream_ == nullptr; | 759 bool null_stream = stream_ == nullptr; |
| 789 UMA_HISTOGRAM_BOOLEAN("Net.QuicReadAvailableData.NullStream", null_stream); | 760 UMA_HISTOGRAM_BOOLEAN("Net.QuicReadAvailableData.NullStream", null_stream); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 void QuicHttpStream::SetResponseStatus(int response_status) { | 803 void QuicHttpStream::SetResponseStatus(int response_status) { |
| 833 has_response_status_ = true; | 804 has_response_status_ = true; |
| 834 response_status_ = response_status; | 805 response_status_ = response_status; |
| 835 } | 806 } |
| 836 | 807 |
| 837 int QuicHttpStream::ComputeResponseStatus() const { | 808 int QuicHttpStream::ComputeResponseStatus() const { |
| 838 DCHECK(!has_response_status_); | 809 DCHECK(!has_response_status_); |
| 839 | 810 |
| 840 // If the handshake has failed this will be handled by the QuicStreamFactory | 811 // If the handshake has failed this will be handled by the QuicStreamFactory |
| 841 // and HttpStreamFactory to mark QUIC as broken if TCP is actually working. | 812 // and HttpStreamFactory to mark QUIC as broken if TCP is actually working. |
| 842 if (!was_handshake_confirmed_) | 813 if (!quic_session()->IsCryptoHandshakeConfirmed()) |
| 843 return ERR_QUIC_HANDSHAKE_FAILED; | 814 return ERR_QUIC_HANDSHAKE_FAILED; |
| 844 | 815 |
| 845 // If the session was aborted by a higher layer, simply use that error code. | 816 // If the session was aborted by a higher layer, simply use that error code. |
| 846 if (session_error_ != ERR_UNEXPECTED) | 817 if (session_error_ != ERR_UNEXPECTED) |
| 847 return session_error_; | 818 return session_error_; |
| 848 | 819 |
| 849 // If |response_info_| is null then the request has not been sent, so | 820 // If |response_info_| is null then the request has not been sent, so |
| 850 // return ERR_CONNECTION_CLOSED to permit HttpNetworkTransaction to | 821 // return ERR_CONNECTION_CLOSED to permit HttpNetworkTransaction to |
| 851 // retry the request. | 822 // retry the request. |
| 852 if (!response_info_) | 823 if (!response_info_) |
| 853 return ERR_CONNECTION_CLOSED; | 824 return ERR_CONNECTION_CLOSED; |
| 854 | 825 |
| 855 // Explicit stream error are always fatal. | 826 // Explicit stream error are always fatal. |
| 856 if (quic_stream_error_ != QUIC_STREAM_NO_ERROR && | 827 if (quic_stream_error_ != QUIC_STREAM_NO_ERROR && |
| 857 quic_stream_error_ != QUIC_STREAM_CONNECTION_ERROR) { | 828 quic_stream_error_ != QUIC_STREAM_CONNECTION_ERROR) { |
| 858 return ERR_QUIC_PROTOCOL_ERROR; | 829 return ERR_QUIC_PROTOCOL_ERROR; |
| 859 } | 830 } |
| 860 | 831 |
| 861 DCHECK_NE(QUIC_HANDSHAKE_TIMEOUT, quic_connection_error_); | 832 DCHECK_NE(QUIC_HANDSHAKE_TIMEOUT, quic_connection_error_); |
| 862 | 833 |
| 863 return ERR_QUIC_PROTOCOL_ERROR; | 834 return ERR_QUIC_PROTOCOL_ERROR; |
| 864 } | 835 } |
| 865 | 836 |
| 866 } // namespace net | 837 } // namespace net |
| OLD | NEW |