| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 response_headers_received_(false), | 58 response_headers_received_(false), |
| 59 trailing_headers_received_(false), | 59 trailing_headers_received_(false), |
| 60 headers_bytes_received_(0), | 60 headers_bytes_received_(0), |
| 61 headers_bytes_sent_(0), | 61 headers_bytes_sent_(0), |
| 62 closed_stream_received_bytes_(0), | 62 closed_stream_received_bytes_(0), |
| 63 closed_stream_sent_bytes_(0), | 63 closed_stream_sent_bytes_(0), |
| 64 closed_is_first_stream_(false), | 64 closed_is_first_stream_(false), |
| 65 user_buffer_len_(0), | 65 user_buffer_len_(0), |
| 66 session_error_(ERR_UNEXPECTED), | 66 session_error_(ERR_UNEXPECTED), |
| 67 found_promise_(false), | 67 found_promise_(false), |
| 68 push_handle_(nullptr), | |
| 69 in_loop_(false), | 68 in_loop_(false), |
| 70 weak_factory_(this) {} | 69 weak_factory_(this) {} |
| 71 | 70 |
| 72 QuicHttpStream::~QuicHttpStream() { | 71 QuicHttpStream::~QuicHttpStream() { |
| 73 CHECK(!in_loop_); | 72 CHECK(!in_loop_); |
| 74 Close(false); | 73 Close(false); |
| 75 } | 74 } |
| 76 | 75 |
| 77 bool QuicHttpStream::CheckVary(const SpdyHeaderBlock& client_request, | |
| 78 const SpdyHeaderBlock& promise_request, | |
| 79 const SpdyHeaderBlock& promise_response) { | |
| 80 HttpResponseInfo promise_response_info; | |
| 81 | |
| 82 HttpRequestInfo promise_request_info; | |
| 83 ConvertHeaderBlockToHttpRequestHeaders(promise_request, | |
| 84 &promise_request_info.extra_headers); | |
| 85 HttpRequestInfo client_request_info; | |
| 86 ConvertHeaderBlockToHttpRequestHeaders(client_request, | |
| 87 &client_request_info.extra_headers); | |
| 88 | |
| 89 if (!SpdyHeadersToHttpResponse(promise_response, &promise_response_info)) { | |
| 90 DLOG(WARNING) << "Invalid headers"; | |
| 91 return false; | |
| 92 } | |
| 93 | |
| 94 HttpVaryData vary_data; | |
| 95 if (!vary_data.Init(promise_request_info, | |
| 96 *promise_response_info.headers.get())) { | |
| 97 // Promise didn't contain valid vary info, so URL match was sufficient. | |
| 98 return true; | |
| 99 } | |
| 100 // Now compare the client request for matching. | |
| 101 return vary_data.MatchesRequest(client_request_info, | |
| 102 *promise_response_info.headers.get()); | |
| 103 } | |
| 104 | |
| 105 void QuicHttpStream::OnRendezvousResult(QuicSpdyStream* stream) { | |
| 106 push_handle_ = nullptr; | |
| 107 if (stream) { | |
| 108 stream_ = static_cast<QuicChromiumClientStream*>(stream)->CreateHandle(); | |
| 109 } | |
| 110 | |
| 111 // callback_ should only be non-null in the case of asynchronous | |
| 112 // rendezvous; i.e. |Try()| returned QUIC_PENDING. | |
| 113 if (callback_.is_null()) | |
| 114 return; | |
| 115 | |
| 116 DCHECK_EQ(STATE_HANDLE_PROMISE_COMPLETE, next_state_); | |
| 117 if (!stream) { | |
| 118 // rendezvous has failed so proceed as with a non-push request. | |
| 119 next_state_ = STATE_REQUEST_STREAM; | |
| 120 } | |
| 121 | |
| 122 OnIOComplete(OK); | |
| 123 } | |
| 124 | |
| 125 HttpResponseInfo::ConnectionInfo QuicHttpStream::ConnectionInfoFromQuicVersion( | 76 HttpResponseInfo::ConnectionInfo QuicHttpStream::ConnectionInfoFromQuicVersion( |
| 126 QuicVersion quic_version) { | 77 QuicVersion quic_version) { |
| 127 switch (quic_version) { | 78 switch (quic_version) { |
| 128 case QUIC_VERSION_UNSUPPORTED: | 79 case QUIC_VERSION_UNSUPPORTED: |
| 129 return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION; | 80 return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION; |
| 130 case QUIC_VERSION_35: | 81 case QUIC_VERSION_35: |
| 131 return HttpResponseInfo::CONNECTION_INFO_QUIC_35; | 82 return HttpResponseInfo::CONNECTION_INFO_QUIC_35; |
| 132 case QUIC_VERSION_36: | 83 case QUIC_VERSION_36: |
| 133 return HttpResponseInfo::CONNECTION_INFO_QUIC_36; | 84 return HttpResponseInfo::CONNECTION_INFO_QUIC_36; |
| 134 case QUIC_VERSION_37: | 85 case QUIC_VERSION_37: |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 | 138 |
| 188 next_state_ = STATE_REQUEST_STREAM; | 139 next_state_ = STATE_REQUEST_STREAM; |
| 189 int rv = DoLoop(OK); | 140 int rv = DoLoop(OK); |
| 190 if (rv == ERR_IO_PENDING) | 141 if (rv == ERR_IO_PENDING) |
| 191 callback_ = callback; | 142 callback_ = callback; |
| 192 | 143 |
| 193 return MapStreamError(rv); | 144 return MapStreamError(rv); |
| 194 } | 145 } |
| 195 | 146 |
| 196 int QuicHttpStream::DoHandlePromise() { | 147 int QuicHttpStream::DoHandlePromise() { |
| 197 QuicAsyncStatus push_status = quic_session()->GetPushPromiseIndex()->Try( | 148 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; |
| 198 request_headers_, this, &this->push_handle_); | 149 return quic_session()->RendezvousWithPromised( |
| 199 | 150 request_headers_, |
| 200 switch (push_status) { | 151 base::Bind(&QuicHttpStream::OnIOComplete, weak_factory_.GetWeakPtr())); |
| 201 case QUIC_FAILURE: | |
| 202 // Push rendezvous failed. | |
| 203 next_state_ = STATE_REQUEST_STREAM; | |
| 204 break; | |
| 205 case QUIC_SUCCESS: | |
| 206 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; | |
| 207 break; | |
| 208 case QUIC_PENDING: | |
| 209 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; | |
| 210 return ERR_IO_PENDING; | |
| 211 } | |
| 212 return OK; | |
| 213 } | 152 } |
| 214 | 153 |
| 215 int QuicHttpStream::DoHandlePromiseComplete(int rv) { | 154 int QuicHttpStream::DoHandlePromiseComplete(int rv) { |
| 216 if (rv != OK) | 155 DCHECK_NE(ERR_IO_PENDING, rv); |
| 217 return rv; | 156 DCHECK_GE(OK, rv); |
| 157 if (rv != OK) { |
| 158 // rendezvous has failed so proceed as with a non-push request. |
| 159 next_state_ = STATE_REQUEST_STREAM; |
| 160 return OK; |
| 161 } |
| 162 |
| 163 stream_ = quic_session()->ReleasePromisedStream(); |
| 218 | 164 |
| 219 next_state_ = STATE_OPEN; | 165 next_state_ = STATE_OPEN; |
| 220 stream_net_log_.AddEvent( | 166 stream_net_log_.AddEvent( |
| 221 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, | 167 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, |
| 222 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), | 168 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), |
| 223 &request_info_->url)); | 169 &request_info_->url)); |
| 224 quic_session()->net_log().AddEvent( | 170 quic_session()->net_log().AddEvent( |
| 225 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, | 171 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, |
| 226 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), | 172 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), |
| 227 &request_info_->url)); | 173 &request_info_->url)); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 base::AutoReset<bool> auto_reset_in_loop(&in_loop_, true); | 450 base::AutoReset<bool> auto_reset_in_loop(&in_loop_, true); |
| 505 do { | 451 do { |
| 506 State state = next_state_; | 452 State state = next_state_; |
| 507 next_state_ = STATE_NONE; | 453 next_state_ = STATE_NONE; |
| 508 switch (state) { | 454 switch (state) { |
| 509 case STATE_HANDLE_PROMISE: | 455 case STATE_HANDLE_PROMISE: |
| 510 CHECK_EQ(OK, rv); | 456 CHECK_EQ(OK, rv); |
| 511 rv = DoHandlePromise(); | 457 rv = DoHandlePromise(); |
| 512 break; | 458 break; |
| 513 case STATE_HANDLE_PROMISE_COMPLETE: | 459 case STATE_HANDLE_PROMISE_COMPLETE: |
| 514 CHECK_EQ(OK, rv); | |
| 515 rv = DoHandlePromiseComplete(rv); | 460 rv = DoHandlePromiseComplete(rv); |
| 516 break; | 461 break; |
| 517 case STATE_REQUEST_STREAM: | 462 case STATE_REQUEST_STREAM: |
| 518 CHECK_EQ(OK, rv); | 463 CHECK_EQ(OK, rv); |
| 519 rv = DoRequestStream(); | 464 rv = DoRequestStream(); |
| 520 break; | 465 break; |
| 521 case STATE_REQUEST_STREAM_COMPLETE: | 466 case STATE_REQUEST_STREAM_COMPLETE: |
| 522 rv = DoRequestStreamComplete(rv); | 467 rv = DoRequestStreamComplete(rv); |
| 523 break; | 468 break; |
| 524 case STATE_SET_REQUEST_PRIORITY: | 469 case STATE_SET_REQUEST_PRIORITY: |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 int QuicHttpStream::HandleReadComplete(int rv) { | 679 int QuicHttpStream::HandleReadComplete(int rv) { |
| 735 if (stream_->IsDoneReading()) { | 680 if (stream_->IsDoneReading()) { |
| 736 stream_->OnFinRead(); | 681 stream_->OnFinRead(); |
| 737 SetResponseStatus(OK); | 682 SetResponseStatus(OK); |
| 738 ResetStream(); | 683 ResetStream(); |
| 739 } | 684 } |
| 740 return rv; | 685 return rv; |
| 741 } | 686 } |
| 742 | 687 |
| 743 void QuicHttpStream::ResetStream() { | 688 void QuicHttpStream::ResetStream() { |
| 744 if (push_handle_) { | |
| 745 push_handle_->Cancel(); | |
| 746 push_handle_ = nullptr; | |
| 747 } | |
| 748 | |
| 749 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress | 689 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress |
| 750 // read. | 690 // read. |
| 751 if (request_body_stream_) | 691 if (request_body_stream_) |
| 752 request_body_stream_->Reset(); | 692 request_body_stream_->Reset(); |
| 753 | 693 |
| 754 if (!stream_) | 694 if (!stream_) |
| 755 return; | 695 return; |
| 756 | 696 |
| 757 DCHECK_LE(stream_->NumBytesConsumed(), stream_->stream_bytes_read()); | 697 DCHECK_LE(stream_->NumBytesConsumed(), stream_->stream_bytes_read()); |
| 758 // Only count the uniquely received bytes. | 698 // Only count the uniquely received bytes. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 // Explicit stream error are always fatal. | 745 // Explicit stream error are always fatal. |
| 806 if (stream_->stream_error() != QUIC_STREAM_NO_ERROR && | 746 if (stream_->stream_error() != QUIC_STREAM_NO_ERROR && |
| 807 stream_->stream_error() != QUIC_STREAM_CONNECTION_ERROR) { | 747 stream_->stream_error() != QUIC_STREAM_CONNECTION_ERROR) { |
| 808 return ERR_QUIC_PROTOCOL_ERROR; | 748 return ERR_QUIC_PROTOCOL_ERROR; |
| 809 } | 749 } |
| 810 | 750 |
| 811 return ERR_QUIC_PROTOCOL_ERROR; | 751 return ERR_QUIC_PROTOCOL_ERROR; |
| 812 } | 752 } |
| 813 | 753 |
| 814 } // namespace net | 754 } // namespace net |
| OLD | NEW |