OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include "base/auto_reset.h" | |
7 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
8 #include "base/logging.h" | 9 #include "base/logging.h" |
9 #include "base/memory/linked_ptr.h" | 10 #include "base/memory/linked_ptr.h" |
10 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
11 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
12 #include "base/metrics/stats_counters.h" | 13 #include "base/metrics/stats_counters.h" |
13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
14 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
16 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 } | 166 } |
166 | 167 |
167 private: | 168 private: |
168 ~NetLogSpdyRstParameter() {} | 169 ~NetLogSpdyRstParameter() {} |
169 const spdy::SpdyStreamId stream_id_; | 170 const spdy::SpdyStreamId stream_id_; |
170 const int status_; | 171 const int status_; |
171 | 172 |
172 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyRstParameter); | 173 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyRstParameter); |
173 }; | 174 }; |
174 | 175 |
176 class NetLogSpdyPingParameter : public NetLog::EventParameters { | |
177 public: | |
178 explicit NetLogSpdyPingParameter(uint32 unique_id) : unique_id_(unique_id) {} | |
179 | |
180 virtual Value* ToValue() const { | |
181 DictionaryValue* dict = new DictionaryValue(); | |
182 dict->SetInteger("unique_id", unique_id_); | |
183 return dict; | |
184 } | |
185 | |
186 private: | |
187 ~NetLogSpdyPingParameter() {} | |
jar (doing other things)
2011/10/14 19:59:07
Question for WillChan: Does making this private pr
willchan no longer on Chromium
2011/10/14 22:49:21
Refcounted
ramant (doing other things)
2011/10/14 23:42:45
Done.
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
188 const uint32 unique_id_; | |
189 | |
190 DISALLOW_COPY_AND_ASSIGN(NetLogSpdyPingParameter); | |
191 }; | |
192 | |
175 class NetLogSpdyGoAwayParameter : public NetLog::EventParameters { | 193 class NetLogSpdyGoAwayParameter : public NetLog::EventParameters { |
176 public: | 194 public: |
177 NetLogSpdyGoAwayParameter(spdy::SpdyStreamId last_stream_id, | 195 NetLogSpdyGoAwayParameter(spdy::SpdyStreamId last_stream_id, |
178 int active_streams, | 196 int active_streams, |
179 int unclaimed_streams) | 197 int unclaimed_streams) |
180 : last_stream_id_(last_stream_id), | 198 : last_stream_id_(last_stream_id), |
181 active_streams_(active_streams), | 199 active_streams_(active_streams), |
182 unclaimed_streams_(unclaimed_streams) {} | 200 unclaimed_streams_(unclaimed_streams) {} |
183 | 201 |
184 virtual Value* ToValue() const { | 202 virtual Value* ToValue() const { |
(...skipping 21 matching lines...) Expand all Loading... | |
206 | 224 |
207 // static | 225 // static |
208 bool SpdySession::use_flow_control_ = false; | 226 bool SpdySession::use_flow_control_ = false; |
209 | 227 |
210 // static | 228 // static |
211 size_t SpdySession::init_max_concurrent_streams_ = 10; | 229 size_t SpdySession::init_max_concurrent_streams_ = 10; |
212 | 230 |
213 // static | 231 // static |
214 size_t SpdySession::max_concurrent_stream_limit_ = 256; | 232 size_t SpdySession::max_concurrent_stream_limit_ = 256; |
215 | 233 |
234 // static | |
235 bool SpdySession::send_ping_for_every_request_ = false; | |
236 | |
237 // static | |
238 int SpdySession::post_ping_delay_time_ms_ = 1000; | |
239 | |
240 // static | |
241 int SpdySession::check_status_delay_time_ms_ = 10000; | |
242 | |
243 // static | |
244 int SpdySession::hung_interval_ms_ = 10000; | |
245 | |
216 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, | 246 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, |
217 SpdySessionPool* spdy_session_pool, | 247 SpdySessionPool* spdy_session_pool, |
218 SpdySettingsStorage* spdy_settings, | 248 SpdySettingsStorage* spdy_settings, |
219 bool verify_domain_authentication, | 249 bool verify_domain_authentication, |
220 NetLog* net_log) | 250 NetLog* net_log) |
221 : ALLOW_THIS_IN_INITIALIZER_LIST( | 251 : ALLOW_THIS_IN_INITIALIZER_LIST( |
222 read_callback_(this, &SpdySession::OnReadComplete)), | 252 read_callback_(this, &SpdySession::OnReadComplete)), |
223 ALLOW_THIS_IN_INITIALIZER_LIST( | 253 ALLOW_THIS_IN_INITIALIZER_LIST( |
224 write_callback_(this, &SpdySession::OnWriteComplete)), | 254 write_callback_(this, &SpdySession::OnWriteComplete)), |
225 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 255 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
(...skipping 13 matching lines...) Expand all Loading... | |
239 max_concurrent_streams_(init_max_concurrent_streams_), | 269 max_concurrent_streams_(init_max_concurrent_streams_), |
240 streams_initiated_count_(0), | 270 streams_initiated_count_(0), |
241 streams_pushed_count_(0), | 271 streams_pushed_count_(0), |
242 streams_pushed_and_claimed_count_(0), | 272 streams_pushed_and_claimed_count_(0), |
243 streams_abandoned_count_(0), | 273 streams_abandoned_count_(0), |
244 frames_received_(0), | 274 frames_received_(0), |
245 bytes_received_(0), | 275 bytes_received_(0), |
246 sent_settings_(false), | 276 sent_settings_(false), |
247 received_settings_(false), | 277 received_settings_(false), |
248 stalled_streams_(0), | 278 stalled_streams_(0), |
279 pings_in_flight_(0), | |
280 unique_id_counter_(1), | |
281 post_ping_pending_(false), | |
282 check_status_pending_(false), | |
283 last_sent_was_ping_(false), | |
249 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize), | 284 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize), |
250 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize), | 285 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize), |
251 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)), | 286 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)), |
252 verify_domain_authentication_(verify_domain_authentication) { | 287 verify_domain_authentication_(verify_domain_authentication) { |
jar (doing other things)
2011/10/14 19:59:07
Since we just got data over the underlying TCP/IP
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
253 DCHECK(HttpStreamFactory::spdy_enabled()); | 288 DCHECK(HttpStreamFactory::spdy_enabled()); |
254 net_log_.BeginEvent( | 289 net_log_.BeginEvent( |
255 NetLog::TYPE_SPDY_SESSION, | 290 NetLog::TYPE_SPDY_SESSION, |
256 make_scoped_refptr( | 291 make_scoped_refptr( |
257 new NetLogSpdySessionParameter(host_port_proxy_pair_))); | 292 new NetLogSpdySessionParameter(host_port_proxy_pair_))); |
258 | 293 |
259 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. | 294 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. |
260 | 295 |
261 spdy_framer_.set_visitor(this); | 296 spdy_framer_.set_visitor(this); |
262 | 297 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 spdy::SpdyStreamId stream_id, | 502 spdy::SpdyStreamId stream_id, |
468 RequestPriority priority, | 503 RequestPriority priority, |
469 spdy::SpdyControlFlags flags, | 504 spdy::SpdyControlFlags flags, |
470 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 505 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
471 // Find our stream | 506 // Find our stream |
472 if (!IsStreamActive(stream_id)) | 507 if (!IsStreamActive(stream_id)) |
473 return ERR_INVALID_SPDY_STREAM; | 508 return ERR_INVALID_SPDY_STREAM; |
474 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; | 509 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; |
475 CHECK_EQ(stream->stream_id(), stream_id); | 510 CHECK_EQ(stream->stream_id(), stream_id); |
476 | 511 |
512 SendPing(); | |
jar (doing other things)
2011/10/14 19:59:07
We need a better name, since this confused me into
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
513 | |
477 scoped_ptr<spdy::SpdySynStreamControlFrame> syn_frame( | 514 scoped_ptr<spdy::SpdySynStreamControlFrame> syn_frame( |
478 spdy_framer_.CreateSynStream( | 515 spdy_framer_.CreateSynStream( |
479 stream_id, 0, | 516 stream_id, 0, |
480 ConvertRequestPriorityToSpdyPriority(priority), | 517 ConvertRequestPriorityToSpdyPriority(priority), |
481 flags, false, headers.get())); | 518 flags, false, headers.get())); |
482 QueueFrame(syn_frame.get(), priority, stream); | 519 QueueFrame(syn_frame.get(), priority, stream); |
483 | 520 |
484 base::StatsCounter spdy_requests("spdy.requests"); | 521 base::StatsCounter spdy_requests("spdy.requests"); |
485 spdy_requests.Increment(); | 522 spdy_requests.Increment(); |
486 streams_initiated_count_++; | 523 streams_initiated_count_++; |
487 | 524 |
488 if (net_log().IsLoggingAllEvents()) { | 525 if (net_log().IsLoggingAllEvents()) { |
489 net_log().AddEvent( | 526 net_log().AddEvent( |
490 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, | 527 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, |
491 make_scoped_refptr( | 528 make_scoped_refptr( |
492 new NetLogSpdySynParameter(headers, flags, stream_id, 0))); | 529 new NetLogSpdySynParameter(headers, flags, stream_id, 0))); |
493 } | 530 } |
531 last_sent_was_ping_ = false; | |
494 | 532 |
495 return ERR_IO_PENDING; | 533 return ERR_IO_PENDING; |
496 } | 534 } |
497 | 535 |
498 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, | 536 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, |
499 net::IOBuffer* data, int len, | 537 net::IOBuffer* data, int len, |
500 spdy::SpdyDataFlags flags) { | 538 spdy::SpdyDataFlags flags) { |
501 // Find our stream | 539 // Find our stream |
jar (doing other things)
2011/10/14 19:59:07
We should probably (just for safety and correctnes
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
502 DCHECK(IsStreamActive(stream_id)); | 540 DCHECK(IsStreamActive(stream_id)); |
503 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 541 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
504 CHECK_EQ(stream->stream_id(), stream_id); | 542 CHECK_EQ(stream->stream_id(), stream_id); |
505 if (!stream) | 543 if (!stream) |
506 return ERR_INVALID_SPDY_STREAM; | 544 return ERR_INVALID_SPDY_STREAM; |
507 | 545 |
508 if (len > kMaxSpdyFrameChunkSize) { | 546 if (len > kMaxSpdyFrameChunkSize) { |
509 len = kMaxSpdyFrameChunkSize; | 547 len = kMaxSpdyFrameChunkSize; |
510 flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN); | 548 flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN); |
511 } | 549 } |
(...skipping 25 matching lines...) Expand all Loading... | |
537 if (net_log().IsLoggingAllEvents()) { | 575 if (net_log().IsLoggingAllEvents()) { |
538 net_log().AddEvent( | 576 net_log().AddEvent( |
539 NetLog::TYPE_SPDY_SESSION_SEND_DATA, | 577 NetLog::TYPE_SPDY_SESSION_SEND_DATA, |
540 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); | 578 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); |
541 } | 579 } |
542 | 580 |
543 // TODO(mbelshe): reduce memory copies here. | 581 // TODO(mbelshe): reduce memory copies here. |
544 scoped_ptr<spdy::SpdyDataFrame> frame( | 582 scoped_ptr<spdy::SpdyDataFrame> frame( |
545 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); | 583 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); |
546 QueueFrame(frame.get(), stream->priority(), stream); | 584 QueueFrame(frame.get(), stream->priority(), stream); |
585 last_sent_was_ping_ = false; | |
547 return ERR_IO_PENDING; | 586 return ERR_IO_PENDING; |
548 } | 587 } |
549 | 588 |
550 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { | 589 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { |
551 // TODO(mbelshe): We should send a RST_STREAM control frame here | 590 // TODO(mbelshe): We should send a RST_STREAM control frame here |
552 // so that the server can cancel a large send. | 591 // so that the server can cancel a large send. |
553 | 592 |
554 DeleteStream(stream_id, status); | 593 DeleteStream(stream_id, status); |
555 } | 594 } |
556 | 595 |
557 void SpdySession::ResetStream( | 596 void SpdySession::ResetStream( |
558 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { | 597 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { |
559 | 598 |
560 net_log().AddEvent( | 599 net_log().AddEvent( |
561 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, | 600 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, |
562 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status))); | 601 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status))); |
563 | 602 |
564 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( | 603 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( |
565 spdy_framer_.CreateRstStream(stream_id, status)); | 604 spdy_framer_.CreateRstStream(stream_id, status)); |
566 | 605 |
567 // Default to lowest priority unless we know otherwise. | 606 // Default to lowest priority unless we know otherwise. |
568 int priority = 3; | 607 int priority = 3; |
569 if(IsStreamActive(stream_id)) { | 608 if(IsStreamActive(stream_id)) { |
570 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 609 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
571 priority = stream->priority(); | 610 priority = stream->priority(); |
572 } | 611 } |
573 QueueFrame(rst_frame.get(), priority, NULL); | 612 QueueFrame(rst_frame.get(), priority, NULL); |
574 | 613 last_sent_was_ping_ = false; |
575 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 614 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
576 } | 615 } |
577 | 616 |
578 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { | 617 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { |
579 return ContainsKey(active_streams_, stream_id); | 618 return ContainsKey(active_streams_, stream_id); |
580 } | 619 } |
581 | 620 |
582 LoadState SpdySession::GetLoadState() const { | 621 LoadState SpdySession::GetLoadState() const { |
583 // NOTE: The application only queries the LoadState via the | 622 // NOTE: The application only queries the LoadState via the |
584 // SpdyNetworkTransaction, and details are only needed when | 623 // SpdyNetworkTransaction, and details are only needed when |
(...skipping 20 matching lines...) Expand all Loading... | |
605 // Session is tearing down. | 644 // Session is tearing down. |
606 net::Error error = static_cast<net::Error>(bytes_read); | 645 net::Error error = static_cast<net::Error>(bytes_read); |
607 if (bytes_read == 0) | 646 if (bytes_read == 0) |
608 error = ERR_CONNECTION_CLOSED; | 647 error = ERR_CONNECTION_CLOSED; |
609 CloseSessionOnError(error, true); | 648 CloseSessionOnError(error, true); |
610 return; | 649 return; |
611 } | 650 } |
612 | 651 |
613 bytes_received_ += bytes_read; | 652 bytes_received_ += bytes_read; |
614 | 653 |
654 received_data_time_ = base::TimeTicks::Now(); | |
655 | |
615 // The SpdyFramer will use callbacks onto |this| as it parses frames. | 656 // The SpdyFramer will use callbacks onto |this| as it parses frames. |
616 // When errors occur, those callbacks can lead to teardown of all references | 657 // When errors occur, those callbacks can lead to teardown of all references |
617 // to |this|, so maintain a reference to self during this call for safe | 658 // to |this|, so maintain a reference to self during this call for safe |
618 // cleanup. | 659 // cleanup. |
619 scoped_refptr<SpdySession> self(this); | 660 scoped_refptr<SpdySession> self(this); |
620 | 661 |
621 char *data = read_buffer_->data(); | 662 char *data = read_buffer_->data(); |
622 while (bytes_read && | 663 while (bytes_read && |
623 spdy_framer_.error_code() == spdy::SpdyFramer::SPDY_NO_ERROR) { | 664 spdy_framer_.error_code() == spdy::SpdyFramer::SPDY_NO_ERROR) { |
624 uint32 bytes_processed = spdy_framer_.ProcessInput(data, bytes_read); | 665 uint32 bytes_processed = spdy_framer_.ProcessInput(data, bytes_read); |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1222 return; | 1263 return; |
1223 } | 1264 } |
1224 } | 1265 } |
1225 | 1266 |
1226 frames_received_++; | 1267 frames_received_++; |
1227 | 1268 |
1228 switch (type) { | 1269 switch (type) { |
1229 case spdy::GOAWAY: | 1270 case spdy::GOAWAY: |
1230 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); | 1271 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); |
1231 break; | 1272 break; |
1273 case spdy::PING: | |
1274 OnPing(*reinterpret_cast<const spdy::SpdyPingControlFrame*>(frame)); | |
1275 break; | |
1232 case spdy::SETTINGS: | 1276 case spdy::SETTINGS: |
1233 OnSettings( | 1277 OnSettings( |
1234 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); | 1278 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); |
1235 break; | 1279 break; |
1236 case spdy::RST_STREAM: | 1280 case spdy::RST_STREAM: |
1237 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); | 1281 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); |
1238 break; | 1282 break; |
1239 case spdy::SYN_STREAM: | 1283 case spdy::SYN_STREAM: |
1240 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), | 1284 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), |
1241 headers); | 1285 headers); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1310 CloseAllStreams(net::ERR_ABORTED); | 1354 CloseAllStreams(net::ERR_ABORTED); |
1311 | 1355 |
1312 // TODO(willchan): Cancel any streams that are past the GoAway frame's | 1356 // TODO(willchan): Cancel any streams that are past the GoAway frame's |
1313 // |last_accepted_stream_id|. | 1357 // |last_accepted_stream_id|. |
1314 | 1358 |
1315 // Don't bother killing any streams that are still reading. They'll either | 1359 // Don't bother killing any streams that are still reading. They'll either |
1316 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is | 1360 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is |
1317 // closed. | 1361 // closed. |
1318 } | 1362 } |
1319 | 1363 |
1364 void SpdySession::OnPing(const spdy::SpdyPingControlFrame& frame) { | |
1365 net_log_.AddEvent( | |
1366 NetLog::TYPE_SPDY_SESSION_PING, | |
1367 make_scoped_refptr(new NetLogSpdyPingParameter(frame.unique_id()))); | |
jar (doing other things)
2011/10/14 19:59:07
We probably need to condition this on logging... e
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
1368 | |
1369 // Send reponse to a PING from Server. | |
1370 if (frame.unique_id() % 2 == 0) { | |
1371 WritePingFrame(); | |
jar (doing other things)
2011/10/14 19:59:07
You need to pass the frame.unique_id
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
1372 return; | |
1373 } | |
1374 | |
1375 --pings_in_flight_; | |
1376 if (pings_in_flight_ < 0) { | |
1377 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true); | |
1378 return; | |
1379 } | |
1380 | |
1381 if (pings_in_flight_ > 0) | |
1382 return; | |
1383 | |
1384 if (last_sent_was_ping_) | |
1385 return; | |
1386 | |
1387 PlanToSendPostPing(); | |
1388 } | |
1389 | |
1320 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { | 1390 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { |
1321 spdy::SpdySettings settings; | 1391 spdy::SpdySettings settings; |
1322 if (spdy_framer_.ParseSettings(&frame, &settings)) { | 1392 if (spdy_framer_.ParseSettings(&frame, &settings)) { |
1323 HandleSettings(settings); | 1393 HandleSettings(settings); |
1324 spdy_settings_->Set(host_port_pair(), settings); | 1394 spdy_settings_->Set(host_port_pair(), settings); |
1325 } | 1395 } |
1326 | 1396 |
1327 received_settings_ = true; | 1397 received_settings_ = true; |
1328 | 1398 |
1329 net_log_.AddEvent( | 1399 net_log_.AddEvent( |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1367 CHECK_EQ(stream->stream_id(), stream_id); | 1437 CHECK_EQ(stream->stream_id(), stream_id); |
1368 | 1438 |
1369 net_log_.AddEvent( | 1439 net_log_.AddEvent( |
1370 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE, | 1440 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE, |
1371 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( | 1441 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( |
1372 stream_id, delta_window_size, stream->recv_window_size()))); | 1442 stream_id, delta_window_size, stream->recv_window_size()))); |
1373 | 1443 |
1374 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame( | 1444 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame( |
1375 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size)); | 1445 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size)); |
1376 QueueFrame(window_update_frame.get(), stream->priority(), stream); | 1446 QueueFrame(window_update_frame.get(), stream->priority(), stream); |
1447 last_sent_was_ping_ = false; | |
willchan no longer on Chromium
2011/10/14 22:49:21
Why don't we just call this in QueueFrame()? You c
ramant (doing other things)
2011/10/14 23:42:45
We don't want to set last_sent_was_ping_ to true w
| |
1377 } | 1448 } |
1378 | 1449 |
1379 // Given a cwnd that we would have sent to the server, modify it based on the | 1450 // Given a cwnd that we would have sent to the server, modify it based on the |
1380 // field trial policy. | 1451 // field trial policy. |
1381 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { | 1452 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { |
1382 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); | 1453 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); |
1383 if (!trial) { | 1454 if (!trial) { |
1384 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; | 1455 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; |
1385 return cwnd; | 1456 return cwnd; |
1386 } | 1457 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1431 | 1502 |
1432 net_log_.AddEvent( | 1503 net_log_.AddEvent( |
1433 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, | 1504 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, |
1434 make_scoped_refptr(new NetLogSpdySettingsParameter(settings))); | 1505 make_scoped_refptr(new NetLogSpdySettingsParameter(settings))); |
1435 | 1506 |
1436 // Create the SETTINGS frame and send it. | 1507 // Create the SETTINGS frame and send it. |
1437 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( | 1508 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( |
1438 spdy_framer_.CreateSettings(settings)); | 1509 spdy_framer_.CreateSettings(settings)); |
1439 sent_settings_ = true; | 1510 sent_settings_ = true; |
1440 QueueFrame(settings_frame.get(), 0, NULL); | 1511 QueueFrame(settings_frame.get(), 0, NULL); |
1512 last_sent_was_ping_ = false; | |
1441 } | 1513 } |
1442 | 1514 |
1443 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) { | 1515 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) { |
1444 for (spdy::SpdySettings::const_iterator i = settings.begin(), | 1516 for (spdy::SpdySettings::const_iterator i = settings.begin(), |
1445 end = settings.end(); i != end; ++i) { | 1517 end = settings.end(); i != end; ++i) { |
1446 const uint32 id = i->first.id(); | 1518 const uint32 id = i->first.id(); |
1447 const uint32 val = i->second; | 1519 const uint32 val = i->second; |
1448 switch (id) { | 1520 switch (id) { |
1449 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS: | 1521 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS: |
1450 max_concurrent_streams_ = std::min(static_cast<size_t>(val), | 1522 max_concurrent_streams_ = std::min(static_cast<size_t>(val), |
1451 max_concurrent_stream_limit_); | 1523 max_concurrent_stream_limit_); |
1452 ProcessPendingCreateStreams(); | 1524 ProcessPendingCreateStreams(); |
1453 break; | 1525 break; |
1454 } | 1526 } |
1455 } | 1527 } |
1456 } | 1528 } |
1457 | 1529 |
1530 void SpdySession::SendPing() { | |
1531 if (pings_in_flight_ || post_ping_pending_ || !send_ping_for_every_request_) | |
willchan no longer on Chromium
2011/10/14 22:49:21
So, if we are sending a ping for every request, ho
ramant (doing other things)
2011/10/14 23:42:45
The variable name is wrong. We don't send ping for
| |
1532 return; | |
1533 | |
1534 const base::TimeDelta kInterval = | |
1535 base::TimeDelta::FromMilliseconds(hung_interval_ms_); | |
jar (doing other things)
2011/10/14 19:59:07
This needs a different timer name. It is really m
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
1536 | |
1537 base::TimeTicks now = base::TimeTicks::Now(); | |
1538 // If we haven't heard from server, then send a pre-PING. | |
1539 if ((now - received_data_time_) > kInterval) | |
1540 SendPrePing(); | |
1541 | |
1542 PlanToSendPostPing(); | |
1543 } | |
1544 | |
1545 void SpdySession::SendPrePing() { | |
1546 AutoReset<bool> reset(&delayed_write_pending_, true); | |
willchan no longer on Chromium
2011/10/14 22:49:21
Please explain how this works. How does this coale
ramant (doing other things)
2011/10/14 23:42:45
Deleted the AutoReset. You are right, we are writ
| |
1547 WritePingFrame(); | |
1548 PlanToCheckStatus(); | |
1549 ++pings_in_flight_; | |
jar (doing other things)
2011/10/14 19:59:07
You should pass the next_ping_id_ to WritePingFram
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
1550 last_sent_was_ping_ = true; | |
1551 } | |
1552 | |
1553 void SpdySession::SendPostPing() { | |
1554 DCHECK(post_ping_pending_); | |
1555 post_ping_pending_ = false; | |
1556 WritePingFrame(); | |
1557 PlanToCheckStatus(); | |
1558 ++pings_in_flight_; | |
1559 last_sent_was_ping_ = true; | |
1560 } | |
1561 | |
1562 void SpdySession::PlanToSendPostPing() { | |
1563 if (post_ping_pending_) | |
1564 return; | |
1565 | |
1566 post_ping_pending_ = true; | |
1567 MessageLoop::current()->PostDelayedTask( | |
1568 FROM_HERE, | |
1569 method_factory_.NewRunnableMethod(&SpdySession::SendPostPing), | |
1570 post_ping_delay_time_ms_); | |
1571 } | |
1572 | |
1573 void SpdySession::PlanToCheckStatus() { | |
1574 if (check_status_pending_) | |
1575 return; | |
1576 | |
1577 check_status_pending_ = true; | |
1578 MessageLoop::current()->PostDelayedTask( | |
1579 FROM_HERE, | |
1580 method_factory_.NewRunnableMethod( | |
1581 &SpdySession::CheckStatus, base::TimeTicks::Now()), | |
1582 check_status_delay_time_ms_); | |
jar (doing other things)
2011/10/14 19:59:07
This should be our hung_interval_ms (or newer name
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
1583 } | |
1584 | |
1585 void SpdySession::WritePingFrame() { | |
1586 scoped_ptr<spdy::SpdyPingControlFrame> ping_frame( | |
1587 spdy_framer_.CreatePingFrame(unique_id_counter_)); | |
1588 QueueFrame(ping_frame.get(), SPDY_PRIORITY_HIGHEST, NULL); | |
1589 | |
1590 if (net_log().IsLoggingAllEvents()) { | |
1591 net_log().AddEvent( | |
1592 NetLog::TYPE_SPDY_SESSION_PING, | |
1593 make_scoped_refptr(new NetLogSpdyPingParameter(unique_id_counter_))); | |
1594 } | |
1595 unique_id_counter_ += 2; | |
jar (doing other things)
2011/10/14 19:59:07
This is only done if we were sending (an odd numbe
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
1596 } | |
1597 | |
1598 void SpdySession::CheckStatus(base::TimeTicks last_check_time) { | |
1599 // Check if we got a response back for all PINGs we had sent. | |
1600 if (pings_in_flight_ == 0) { | |
1601 check_status_pending_ = false; | |
1602 return; | |
1603 } | |
1604 | |
1605 DCHECK(check_status_pending_); | |
1606 | |
1607 const base::TimeDelta kHungInterval = | |
1608 base::TimeDelta::FromMilliseconds(hung_interval_ms_); | |
1609 if (received_data_time_ < last_check_time) { | |
1610 DCHECK(base::TimeTicks::Now() - received_data_time_ > kHungInterval); | |
jar (doing other things)
2011/10/14 19:59:07
I think this should be >= kHungInterval
willchan no longer on Chromium
2011/10/14 23:13:11
Can you use DCHECK_GT?
ramant (doing other things)
2011/10/14 23:42:45
Done.
ramant (doing other things)
2011/10/14 23:42:45
DCHECK_GE was giving errors for TimeDelta argument
| |
1611 CloseSessionOnError(net::ERR_SPDY_PING_FAILED, true); | |
1612 return; | |
1613 } | |
1614 | |
1615 // Check the status of connection after a delay. | |
1616 base::TimeTicks now = base::TimeTicks::Now(); | |
jar (doing other things)
2011/10/14 19:59:07
You mentioned this code might be clearer if you ju
ramant (doing other things)
2011/10/14 23:42:45
Done.
| |
1617 base::TimeDelta delay = kHungInterval - (now - received_data_time_); | |
1618 MessageLoop::current()->PostDelayedTask( | |
1619 FROM_HERE, | |
1620 method_factory_.NewRunnableMethod(&SpdySession::CheckStatus, now), | |
1621 delay.InMilliseconds()); | |
1622 } | |
1623 | |
1458 void SpdySession::RecordHistograms() { | 1624 void SpdySession::RecordHistograms() { |
1459 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession", | 1625 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession", |
1460 streams_initiated_count_, | 1626 streams_initiated_count_, |
1461 0, 300, 50); | 1627 0, 300, 50); |
1462 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession", | 1628 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession", |
1463 streams_pushed_count_, | 1629 streams_pushed_count_, |
1464 0, 300, 50); | 1630 0, 300, 50); |
1465 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession", | 1631 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession", |
1466 streams_pushed_and_claimed_count_, | 1632 streams_pushed_and_claimed_count_, |
1467 0, 300, 50); | 1633 0, 300, 50); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1536 if (it == pending_callback_map_.end()) | 1702 if (it == pending_callback_map_.end()) |
1537 return; | 1703 return; |
1538 | 1704 |
1539 OldCompletionCallback* callback = it->second.callback; | 1705 OldCompletionCallback* callback = it->second.callback; |
1540 int result = it->second.result; | 1706 int result = it->second.result; |
1541 pending_callback_map_.erase(it); | 1707 pending_callback_map_.erase(it); |
1542 callback->Run(result); | 1708 callback->Run(result); |
1543 } | 1709 } |
1544 | 1710 |
1545 } // namespace net | 1711 } // namespace net |
OLD | NEW |