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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 if (stream) { | 110 if (stream) { |
111 stream_ = static_cast<QuicChromiumClientStream*>(stream); | 111 stream_ = static_cast<QuicChromiumClientStream*>(stream); |
112 stream_->SetDelegate(this); | 112 stream_->SetDelegate(this); |
113 } | 113 } |
114 | 114 |
115 // callback_ should only be non-null in the case of asynchronous | 115 // callback_ should only be non-null in the case of asynchronous |
116 // rendezvous; i.e. |Try()| returned QUIC_PENDING. | 116 // rendezvous; i.e. |Try()| returned QUIC_PENDING. |
117 if (callback_.is_null()) | 117 if (callback_.is_null()) |
118 return; | 118 return; |
119 | 119 |
120 if (stream) { | 120 DCHECK_EQ(STATE_HANDLE_PROMISE_COMPLETE, next_state_); |
121 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; | 121 if (!stream) { |
122 } else { | |
123 // rendezvous has failed so proceed as with a non-push request. | 122 // rendezvous has failed so proceed as with a non-push request. |
124 next_state_ = STATE_REQUEST_STREAM; | 123 next_state_ = STATE_REQUEST_STREAM; |
125 } | 124 } |
126 | 125 |
127 OnIOComplete(OK); | 126 OnIOComplete(OK); |
128 } | 127 } |
129 | 128 |
130 int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info, | 129 int QuicHttpStream::InitializeStream(const HttpRequestInfo* request_info, |
131 RequestPriority priority, | 130 RequestPriority priority, |
132 const BoundNetLog& stream_net_log, | 131 const BoundNetLog& stream_net_log, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 166 } |
168 | 167 |
169 next_state_ = STATE_REQUEST_STREAM; | 168 next_state_ = STATE_REQUEST_STREAM; |
170 int rv = DoLoop(OK); | 169 int rv = DoLoop(OK); |
171 if (rv == ERR_IO_PENDING) | 170 if (rv == ERR_IO_PENDING) |
172 callback_ = callback; | 171 callback_ = callback; |
173 | 172 |
174 return rv; | 173 return rv; |
175 } | 174 } |
176 | 175 |
177 bool QuicHttpStream::CancelPromiseIfHasBody() { | |
178 if (!request_body_stream_) | |
179 return false; | |
180 | |
181 // A request with a body is ineligble for push. | |
182 this->push_handle_->Cancel(); | |
183 this->push_handle_ = nullptr; | |
184 return true; | |
185 } | |
186 | |
187 int QuicHttpStream::DoHandlePromise() { | 176 int QuicHttpStream::DoHandlePromise() { |
188 QuicAsyncStatus push_status = session_->push_promise_index()->Try( | 177 QuicAsyncStatus push_status = session_->push_promise_index()->Try( |
189 request_headers_, this, &this->push_handle_); | 178 request_headers_, this, &this->push_handle_); |
190 | 179 |
191 switch (push_status) { | 180 switch (push_status) { |
192 case QUIC_FAILURE: | 181 case QUIC_FAILURE: |
193 // Push rendezvous failed. | 182 // Push rendezvous failed. |
194 next_state_ = STATE_REQUEST_STREAM; | 183 next_state_ = STATE_REQUEST_STREAM; |
195 break; | 184 break; |
196 case QUIC_SUCCESS: | 185 case QUIC_SUCCESS: |
197 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; | 186 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; |
198 break; | 187 break; |
199 case QUIC_PENDING: | 188 case QUIC_PENDING: |
200 if (!CancelPromiseIfHasBody()) { | 189 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; |
201 next_state_ = STATE_HANDLE_PROMISE_COMPLETE; | 190 return ERR_IO_PENDING; |
202 // Have a promise but the promised stream doesn't exist yet. | |
203 // Still have to do validation before accepting the promised | |
204 // stream for sure. | |
205 return ERR_IO_PENDING; | |
206 } | |
207 next_state_ = STATE_REQUEST_STREAM; | |
208 } | 191 } |
209 return OK; | 192 return OK; |
210 } | 193 } |
211 | 194 |
212 int QuicHttpStream::DoHandlePromiseComplete(int rv) { | 195 int QuicHttpStream::DoHandlePromiseComplete(int rv) { |
213 if (rv != OK) | 196 if (rv != OK) |
214 return rv; | 197 return rv; |
215 | 198 |
216 if (CancelPromiseIfHasBody()) { | |
217 next_state_ = STATE_REQUEST_STREAM; | |
218 return OK; | |
219 } | |
220 | |
221 next_state_ = STATE_OPEN; | 199 next_state_ = STATE_OPEN; |
222 stream_net_log_.AddEvent( | 200 stream_net_log_.AddEvent( |
223 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, | 201 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, |
224 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), | 202 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), |
225 &request_info_->url)); | 203 &request_info_->url)); |
226 session_->net_log().AddEvent( | 204 session_->net_log().AddEvent( |
227 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, | 205 NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM, |
228 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), | 206 base::Bind(&NetLogQuicPushStreamCallback, stream_->id(), |
229 &request_info_->url)); | 207 &request_info_->url)); |
230 return OK; | 208 return OK; |
(...skipping 21 matching lines...) Expand all Loading... |
252 : ERR_QUIC_HANDSHAKE_FAILED; | 230 : ERR_QUIC_HANDSHAKE_FAILED; |
253 } | 231 } |
254 | 232 |
255 // Store the serialized request headers. | 233 // Store the serialized request headers. |
256 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, | 234 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, |
257 /*direct=*/true, &request_headers_); | 235 /*direct=*/true, &request_headers_); |
258 | 236 |
259 // Store the request body. | 237 // Store the request body. |
260 request_body_stream_ = request_info_->upload_data_stream; | 238 request_body_stream_ = request_info_->upload_data_stream; |
261 if (request_body_stream_) { | 239 if (request_body_stream_) { |
| 240 // A request with a body is ineligible for push, so reset the |
| 241 // promised stream and request a new stream. |
| 242 if (found_promise_) { |
| 243 found_promise_ = false; |
| 244 std::string url(request_info_->url.spec()); |
| 245 QuicClientPromisedInfo* promised = |
| 246 session_->push_promise_index()->GetPromised(url); |
| 247 if (promised != nullptr) { |
| 248 session_->ResetPromised(promised->id(), QUIC_STREAM_CANCELLED); |
| 249 } |
| 250 } |
| 251 |
262 // TODO(rch): Can we be more precise about when to allocate | 252 // TODO(rch): Can we be more precise about when to allocate |
263 // raw_request_body_buf_. Removed the following check. DoReadRequestBody() | 253 // raw_request_body_buf_. Removed the following check. DoReadRequestBody() |
264 // was being called even if we didn't yet allocate raw_request_body_buf_. | 254 // was being called even if we didn't yet allocate raw_request_body_buf_. |
265 // && (request_body_stream_->size() || | 255 // && (request_body_stream_->size() || |
266 // request_body_stream_->is_chunked())) | 256 // request_body_stream_->is_chunked())) |
267 // Use 10 packets as the body buffer size to give enough space to | 257 // Use 10 packets as the body buffer size to give enough space to |
268 // help ensure we don't often send out partial packets. | 258 // help ensure we don't often send out partial packets. |
269 raw_request_body_buf_ = | 259 raw_request_body_buf_ = |
270 new IOBufferWithSize(static_cast<size_t>(10 * kMaxPacketSize)); | 260 new IOBufferWithSize(static_cast<size_t>(10 * kMaxPacketSize)); |
271 // The request body buffer is empty at first. | 261 // The request body buffer is empty at first. |
272 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), 0); | 262 request_body_buf_ = new DrainableIOBuffer(raw_request_body_buf_.get(), 0); |
273 } | 263 } |
274 | 264 |
275 // Store the response info. | 265 // Store the response info. |
276 response_info_ = response; | 266 response_info_ = response; |
277 | 267 |
278 int rv; | 268 int rv; |
279 | 269 |
280 if (found_promise_) { | 270 if (found_promise_) { |
281 // TODO(rch): If this request has a body, instead of waiting for the pushed | |
282 // headers to arrive before canceling the push we could cancel the pushed | |
283 // stream now and go straight to STATE_REQUEST_STREAM. | |
284 next_state_ = STATE_HANDLE_PROMISE; | 271 next_state_ = STATE_HANDLE_PROMISE; |
285 } else { | 272 } else { |
286 next_state_ = STATE_SET_REQUEST_PRIORITY; | 273 next_state_ = STATE_SET_REQUEST_PRIORITY; |
287 } | 274 } |
288 rv = DoLoop(OK); | 275 rv = DoLoop(OK); |
289 | 276 |
290 if (rv == ERR_IO_PENDING) | 277 if (rv == ERR_IO_PENDING) |
291 callback_ = callback; | 278 callback_ = callback; |
292 | 279 |
293 return rv > 0 ? OK : rv; | 280 return rv > 0 ? OK : rv; |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 closed_is_first_stream_ = stream_->IsFirstStream(); | 831 closed_is_first_stream_ = stream_->IsFirstStream(); |
845 stream_ = nullptr; | 832 stream_ = nullptr; |
846 | 833 |
847 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress | 834 // If |request_body_stream_| is non-NULL, Reset it, to abort any in progress |
848 // read. | 835 // read. |
849 if (request_body_stream_) | 836 if (request_body_stream_) |
850 request_body_stream_->Reset(); | 837 request_body_stream_->Reset(); |
851 } | 838 } |
852 | 839 |
853 } // namespace net | 840 } // namespace net |
OLD | NEW |