Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: net/quic/chromium/quic_http_stream.cc

Issue 2345663002: Cancel a promised stream if it is for a request with a body in QuicHttpStream. (Closed)
Patch Set: fix comment Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/chromium/quic_http_stream.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/chromium/quic_http_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698