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

Side by Side Diff: net/spdy/spdy_http_stream.cc

Issue 17382012: [SPDY] Refactor SpdyStream's handling of response headers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More updates from rebase Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_http_stream.h ('k') | net/spdy/spdy_http_utils.cc » ('j') | 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/spdy/spdy_http_stream.h" 5 #include "net/spdy/spdy_http_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <list> 8 #include <list>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 15 matching lines...) Expand all
26 namespace net { 26 namespace net {
27 27
28 SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session, bool direct) 28 SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session, bool direct)
29 : weak_factory_(this), 29 : weak_factory_(this),
30 spdy_session_(spdy_session), 30 spdy_session_(spdy_session),
31 stream_closed_(false), 31 stream_closed_(false),
32 closed_stream_status_(ERR_FAILED), 32 closed_stream_status_(ERR_FAILED),
33 closed_stream_id_(0), 33 closed_stream_id_(0),
34 request_info_(NULL), 34 request_info_(NULL),
35 response_info_(NULL), 35 response_info_(NULL),
36 response_headers_received_(false), 36 response_headers_status_(RESPONSE_HEADERS_ARE_INCOMPLETE),
37 user_buffer_len_(0), 37 user_buffer_len_(0),
38 request_body_buf_size_(0), 38 request_body_buf_size_(0),
39 buffered_read_callback_pending_(false), 39 buffered_read_callback_pending_(false),
40 more_read_data_pending_(false), 40 more_read_data_pending_(false),
41 direct_(direct) { 41 direct_(direct) {
42 DCHECK(spdy_session_); 42 DCHECK(spdy_session_);
43 } 43 }
44 44
45 SpdyHttpStream::~SpdyHttpStream() { 45 SpdyHttpStream::~SpdyHttpStream() {
46 if (stream_.get()) { 46 if (stream_.get()) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 100
101 int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) { 101 int SpdyHttpStream::ReadResponseHeaders(const CompletionCallback& callback) {
102 CHECK(!callback.is_null()); 102 CHECK(!callback.is_null());
103 if (stream_closed_) 103 if (stream_closed_)
104 return closed_stream_status_; 104 return closed_stream_status_;
105 105
106 CHECK(stream_.get()); 106 CHECK(stream_.get());
107 107
108 // Check if we already have the response headers. If so, return synchronously. 108 // Check if we already have the response headers. If so, return synchronously.
109 if(stream_->response_received()) { 109 if (response_headers_status_ == RESPONSE_HEADERS_ARE_COMPLETE) {
110 CHECK(stream_->is_idle()); 110 CHECK(stream_->is_idle());
111 return OK; 111 return OK;
112 } 112 }
113 113
114 // Still waiting for the response, return IO_PENDING. 114 // Still waiting for the response, return IO_PENDING.
115 CHECK(callback_.is_null()); 115 CHECK(callback_.is_null());
116 callback_ = callback; 116 callback_ = callback;
117 return ERR_IO_PENDING; 117 return ERR_IO_PENDING;
118 } 118 }
119 119
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 void SpdyHttpStream::OnRequestHeadersSent() { 285 void SpdyHttpStream::OnRequestHeadersSent() {
286 if (!callback_.is_null()) 286 if (!callback_.is_null())
287 DoCallback(OK); 287 DoCallback(OK);
288 288
289 // TODO(akalin): Do this immediately after sending the request 289 // TODO(akalin): Do this immediately after sending the request
290 // headers. 290 // headers.
291 if (HasUploadData()) 291 if (HasUploadData())
292 ReadAndSendRequestBodyData(); 292 ReadAndSendRequestBodyData();
293 } 293 }
294 294
295 int SpdyHttpStream::OnResponseHeadersReceived(const SpdyHeaderBlock& response, 295 SpdyResponseHeadersStatus SpdyHttpStream::OnResponseHeadersUpdated(
296 base::Time response_time, 296 const SpdyHeaderBlock& response_headers) {
297 int status) { 297 CHECK_EQ(response_headers_status_, RESPONSE_HEADERS_ARE_INCOMPLETE);
298
298 if (!response_info_) { 299 if (!response_info_) {
299 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM); 300 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM);
300 push_response_info_.reset(new HttpResponseInfo); 301 push_response_info_.reset(new HttpResponseInfo);
301 response_info_ = push_response_info_.get(); 302 response_info_ = push_response_info_.get();
302 } 303 }
303 304
304 // If the response is already received, these headers are too late. 305 if (!SpdyHeadersToHttpResponse(
305 if (response_headers_received_) { 306 response_headers, stream_->GetProtocolVersion(), response_info_)) {
306 LOG(WARNING) << "SpdyHttpStream headers received after response started."; 307 // We do not have complete headers yet.
307 return OK; 308 return RESPONSE_HEADERS_ARE_INCOMPLETE;
308 } 309 }
309 310
310 // TODO(mbelshe): This is the time of all headers received, not just time 311 response_info_->response_time = stream_->response_time();
311 // to first byte. 312 response_headers_status_ = RESPONSE_HEADERS_ARE_COMPLETE;
312 response_info_->response_time = base::Time::Now();
313
314 if (!SpdyHeadersToHttpResponse(response, stream_->GetProtocolVersion(),
315 response_info_)) {
316 // We might not have complete headers yet.
317 return ERR_INCOMPLETE_SPDY_HEADERS;
318 }
319
320 response_headers_received_ = true;
321 // Don't store the SSLInfo in the response here, HttpNetworkTransaction 313 // Don't store the SSLInfo in the response here, HttpNetworkTransaction
322 // will take care of that part. 314 // will take care of that part.
323 SSLInfo ssl_info; 315 SSLInfo ssl_info;
324 NextProto protocol_negotiated = kProtoUnknown; 316 NextProto protocol_negotiated = kProtoUnknown;
325 stream_->GetSSLInfo(&ssl_info, 317 stream_->GetSSLInfo(&ssl_info,
326 &response_info_->was_npn_negotiated, 318 &response_info_->was_npn_negotiated,
327 &protocol_negotiated); 319 &protocol_negotiated);
328 response_info_->npn_negotiated_protocol = 320 response_info_->npn_negotiated_protocol =
329 SSLClientSocket::NextProtoToString(protocol_negotiated); 321 SSLClientSocket::NextProtoToString(protocol_negotiated);
330 response_info_->request_time = stream_->GetRequestTime(); 322 response_info_->request_time = stream_->GetRequestTime();
331 switch (spdy_session_->GetProtocolVersion()) { 323 switch (spdy_session_->GetProtocolVersion()) {
332 case SPDY2: 324 case SPDY2:
333 response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY2; 325 response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY2;
334 break; 326 break;
335 case SPDY3: 327 case SPDY3:
336 response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY3; 328 response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY3;
337 break; 329 break;
338 case SPDY4: 330 case SPDY4:
339 response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY4; 331 response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY4;
340 break; 332 break;
341 default: 333 default:
342 NOTREACHED(); 334 NOTREACHED();
343 } 335 }
344 response_info_->vary_data 336 response_info_->vary_data
345 .Init(*request_info_, *response_info_->headers.get()); 337 .Init(*request_info_, *response_info_->headers.get());
346 // TODO(ahendrickson): This is recorded after the entire SYN_STREAM control
347 // frame has been received and processed. Move to framer?
348 response_info_->response_time = response_time;
349 338
350 if (!callback_.is_null()) 339 if (!callback_.is_null())
351 DoCallback(status); 340 DoCallback(OK);
352 341
353 return status; 342 return RESPONSE_HEADERS_ARE_COMPLETE;
354 } 343 }
355 344
356 int SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { 345 void SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {
357 // SpdyStream won't call us with data if the header block didn't contain a 346 CHECK_EQ(response_headers_status_, RESPONSE_HEADERS_ARE_COMPLETE);
358 // valid set of headers. So we don't expect to not have headers received
359 // here.
360 if (!response_headers_received_)
361 return ERR_INCOMPLETE_SPDY_HEADERS;
362 347
363 // Note that data may be received for a SpdyStream prior to the user calling 348 // Note that data may be received for a SpdyStream prior to the user calling
364 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often 349 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often
365 // happen for server initiated streams. 350 // happen for server initiated streams.
366 DCHECK(stream_.get()); 351 DCHECK(stream_.get());
367 DCHECK(!stream_->closed() || stream_->type() == SPDY_PUSH_STREAM); 352 DCHECK(!stream_->closed() || stream_->type() == SPDY_PUSH_STREAM);
368 if (buffer) { 353 if (buffer) {
369 response_body_queue_.Enqueue(buffer.Pass()); 354 response_body_queue_.Enqueue(buffer.Pass());
370 355
371 if (user_buffer_.get()) { 356 if (user_buffer_.get()) {
372 // Handing small chunks of data to the caller creates measurable overhead. 357 // Handing small chunks of data to the caller creates measurable overhead.
373 // We buffer data in short time-spans and send a single read notification. 358 // We buffer data in short time-spans and send a single read notification.
374 ScheduleBufferedReadCallback(); 359 ScheduleBufferedReadCallback();
375 } 360 }
376 } 361 }
377 return OK;
378 } 362 }
379 363
380 void SpdyHttpStream::OnDataSent() { 364 void SpdyHttpStream::OnDataSent() {
381 request_body_buf_size_ = 0; 365 request_body_buf_size_ = 0;
382 ReadAndSendRequestBodyData(); 366 ReadAndSendRequestBodyData();
383 } 367 }
384 368
385 void SpdyHttpStream::OnClose(int status) { 369 void SpdyHttpStream::OnClose(int status) {
386 if (stream_.get()) { 370 if (stream_.get()) {
387 stream_closed_ = true; 371 stream_closed_ = true;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 bool SpdyHttpStream::IsSpdyHttpStream() const { 524 bool SpdyHttpStream::IsSpdyHttpStream() const {
541 return true; 525 return true;
542 } 526 }
543 527
544 void SpdyHttpStream::Drain(HttpNetworkSession* session) { 528 void SpdyHttpStream::Drain(HttpNetworkSession* session) {
545 Close(false); 529 Close(false);
546 delete this; 530 delete this;
547 } 531 }
548 532
549 } // namespace net 533 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_http_stream.h ('k') | net/spdy/spdy_http_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698