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

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

Issue 6800009: Attn: Mike Belshe Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 9 years, 8 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
« net/spdy/spdy_framer.cc ('K') | « net/spdy/spdy_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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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_stream.h" 5 #include "net/spdy/spdy_stream.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "net/spdy/spdy_session.h" 10 #include "net/spdy/spdy_session.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 priority_(0), 44 priority_(0),
45 stalled_by_flow_control_(false), 45 stalled_by_flow_control_(false),
46 send_window_size_(spdy::kSpdyStreamInitialWindowSize), 46 send_window_size_(spdy::kSpdyStreamInitialWindowSize),
47 recv_window_size_(spdy::kSpdyStreamInitialWindowSize), 47 recv_window_size_(spdy::kSpdyStreamInitialWindowSize),
48 pushed_(pushed), 48 pushed_(pushed),
49 response_received_(false), 49 response_received_(false),
50 session_(session), 50 session_(session),
51 delegate_(NULL), 51 delegate_(NULL),
52 request_time_(base::Time::Now()), 52 request_time_(base::Time::Now()),
53 response_(new spdy::SpdyHeaderBlock), 53 response_(new spdy::SpdyHeaderBlock),
54 syn_reply_received_(false),
55 metrics_started_(false),
56 close_pending_(false),
54 io_state_(STATE_NONE), 57 io_state_(STATE_NONE),
55 response_status_(OK), 58 response_status_(OK),
56 cancelled_(false), 59 cancelled_(false),
57 has_upload_data_(false), 60 has_upload_data_(false),
58 net_log_(net_log), 61 net_log_(net_log),
59 send_bytes_(0), 62 send_bytes_(0),
60 recv_bytes_(0) { 63 recv_bytes_(0) {
61 } 64 }
62 65
63 SpdyStream::~SpdyStream() { 66 SpdyStream::~SpdyStream() {
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 226 }
224 227
225 base::Time SpdyStream::GetRequestTime() const { 228 base::Time SpdyStream::GetRequestTime() const {
226 return request_time_; 229 return request_time_;
227 } 230 }
228 231
229 void SpdyStream::SetRequestTime(base::Time t) { 232 void SpdyStream::SetRequestTime(base::Time t) {
230 request_time_ = t; 233 request_time_ = t;
231 } 234 }
232 235
236 bool SpdyStream::using_sctp() {
237 return session_->using_sctp();
238 }
239
240 bool SpdyStream::using_sctp_control_stream() {
241 return session_->using_sctp_control_stream();
242 }
243
233 int SpdyStream::OnResponseReceived(const spdy::SpdyHeaderBlock& response) { 244 int SpdyStream::OnResponseReceived(const spdy::SpdyHeaderBlock& response) {
234 int rv = OK; 245 int rv = OK;
235 246
236 metrics_.StartStream(); 247 // We need to avoid starting metrics a second time. If we are using SCTP
248 // with a single dictionary, and the SYN_REPLY was delayed or lost, we may
249 // have already started metrics when the first DATA frame arrived.
250 if ( !(using_sctp() &&
251 using_sctp_control_stream() &&
252 metrics_started())
253 ) {
254 set_metrics_started();
255 metrics_.StartStream();
256 }
237 257
238 DCHECK(response_->empty()); 258 DCHECK(response_->empty());
239 *response_ = response; // TODO(ukai): avoid copy. 259 *response_ = response; // TODO(ukai): avoid copy.
240 260
241 recv_first_byte_time_ = base::TimeTicks::Now(); 261 recv_first_byte_time_ = base::TimeTicks::Now();
242 response_time_ = base::Time::Now(); 262 response_time_ = base::Time::Now();
243 263
244 // If we receive a response before we are in STATE_WAITING_FOR_RESPONSE, then 264 // If we receive a response before we are in STATE_WAITING_FOR_RESPONSE, then
245 // the server has sent the SYN_REPLY too early. 265 // the server has sent the SYN_REPLY too early.
246 if (!pushed_ && io_state_ != STATE_WAITING_FOR_RESPONSE) 266 if (!pushed_ && io_state_ != STATE_WAITING_FOR_RESPONSE)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 // ERR_INCOMPLETE_SPDY_HEADERS means that we are waiting for more 299 // ERR_INCOMPLETE_SPDY_HEADERS means that we are waiting for more
280 // headers before the response header block is complete. 300 // headers before the response header block is complete.
281 if (rv == ERR_INCOMPLETE_SPDY_HEADERS) 301 if (rv == ERR_INCOMPLETE_SPDY_HEADERS)
282 rv = OK; 302 rv = OK;
283 } 303 }
284 return rv; 304 return rv;
285 } 305 }
286 306
287 void SpdyStream::OnDataReceived(const char* data, int length) { 307 void SpdyStream::OnDataReceived(const char* data, int length) {
288 DCHECK_GE(length, 0); 308 DCHECK_GE(length, 0);
309 // TODO(jtl): revisit this
310 // We need to start metrics here if we are using SCTP without multiple
311 // dictionaries, the SYN_REPLY has not yet arrived and metrics have not yet
312 // been started.
313 if (using_sctp() &&
314 using_sctp_control_stream() &&
315 !syn_reply_received() &&
316 !metrics_started()) {
317 set_metrics_started();
318 metrics_.StartStream();
319 }
289 320
290 // If we don't have a response, then the SYN_REPLY did not come through. 321 // If we don't have a response, then the SYN_REPLY did not come through.
291 // We cannot pass data up to the caller unless the reply headers have been 322 // We cannot pass data up to the caller unless the reply headers have been
292 // received. 323 // received.
293 if (!response_received()) { 324 // Exception - when using SCTP with a single dictionary, all SPDY CONTROL
325 // frames are sent on SCTP stream 0, while all SPDY DATA frames are sent on
326 // SCTP stream n > 0. This means that data can arrive before a SYN_REPLY,
327 // due to reordering or loss. In this case we can't require response_received
328 // to be true.
329 if (!response_received() &&
330 !(using_sctp() && using_sctp_control_stream())) {
331 printf("SpdyStream::OnDataReceived: closing stream %d\n", stream_id_);
294 session_->CloseStream(stream_id_, ERR_SYN_REPLY_NOT_RECEIVED); 332 session_->CloseStream(stream_id_, ERR_SYN_REPLY_NOT_RECEIVED);
295 return; 333 return;
296 } 334 }
297 335
298 if (!delegate_ || continue_buffering_data_) { 336 if (!delegate_ || continue_buffering_data_) {
299 // It should be valid for this to happen in the server push case. 337 // It should be valid for this to happen in the server push case.
300 // We'll return received data when delegate gets attached to the stream. 338 // We'll return received data when delegate gets attached to the stream.
301 if (length > 0) { 339 if (length > 0) {
302 IOBufferWithSize* buf = new IOBufferWithSize(length); 340 IOBufferWithSize* buf = new IOBufferWithSize(length);
303 memcpy(buf->data(), data, length); 341 memcpy(buf->data(), data, length);
304 pending_buffers_.push_back(make_scoped_refptr(buf)); 342 pending_buffers_.push_back(make_scoped_refptr(buf));
305 } else { 343 } else {
306 pending_buffers_.push_back(NULL); 344 pending_buffers_.push_back(NULL);
307 metrics_.StopStream(); 345 metrics_.StopStream();
308 // Note: we leave the stream open in the session until the stream 346 // Note: we leave the stream open in the session until the stream
309 // is claimed. 347 // is claimed.
310 } 348 }
311 return; 349 return;
312 } 350 }
313 351
314 CHECK(!closed()); 352 CHECK(!closed());
315 353
316 // A zero-length read means that the stream is being closed. 354 // A zero-length read means that the stream is being closed.
317 if (!length) { 355 // Exception - if using SCTP and sending all SPDY control framed on SCTP
356 // stream 0, we can't close the stream if we haven't received the SYN_REPLY
357 // yet.
358 if (!length && using_sctp() && using_sctp_control_stream() &&
359 !syn_reply_received()) {
360 printf("SpdyStream::OnDataReceived: marking stream %d as ** close_pending "
361 "*** because !length.\n", stream_id_);
362 set_close_pending(); // mark stream for closure once SYN_REPLY arrives.
363 return;
364 } else if (!length) {
318 metrics_.StopStream(); 365 metrics_.StopStream();
366 printf("SpdyStream::OnDataReceived: closing stream %d because !length.\n",
367 stream_id_);
319 session_->CloseStream(stream_id_, net::OK); 368 session_->CloseStream(stream_id_, net::OK);
320 // Note: |this| may be deleted after calling CloseStream. 369 // Note: |this| may be deleted after calling CloseStream.
321 return; 370 return;
322 } 371 }
323 372
324 if (session_->flow_control()) 373 if (session_->flow_control())
325 DecreaseRecvWindowSize(length); 374 DecreaseRecvWindowSize(length);
326 375
327 // Track our bandwidth. 376 // Track our bandwidth.
328 metrics_.RecordBytes(length); 377 metrics_.RecordBytes(length);
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", 639 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime",
591 recv_last_byte_time_ - recv_first_byte_time_); 640 recv_last_byte_time_ - recv_first_byte_time_);
592 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", 641 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime",
593 recv_last_byte_time_ - send_time_); 642 recv_last_byte_time_ - send_time_);
594 643
595 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); 644 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_);
596 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); 645 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_);
597 } 646 }
598 647
599 } // namespace net 648 } // namespace net
OLDNEW
« net/spdy/spdy_framer.cc ('K') | « net/spdy/spdy_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698