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 |