| 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 |