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/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 size_t max_concurrent_streams_limit, | 307 size_t max_concurrent_streams_limit, |
308 TimeFunc time_func, | 308 TimeFunc time_func, |
309 const HostPortPair& trusted_spdy_proxy, | 309 const HostPortPair& trusted_spdy_proxy, |
310 NetLog* net_log) | 310 NetLog* net_log) |
311 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 311 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
312 host_port_proxy_pair_(host_port_proxy_pair), | 312 host_port_proxy_pair_(host_port_proxy_pair), |
313 spdy_session_pool_(spdy_session_pool), | 313 spdy_session_pool_(spdy_session_pool), |
314 http_server_properties_(http_server_properties), | 314 http_server_properties_(http_server_properties), |
315 connection_(new ClientSocketHandle), | 315 connection_(new ClientSocketHandle), |
316 read_buffer_(new IOBuffer(kReadBufferSize)), | 316 read_buffer_(new IOBuffer(kReadBufferSize)), |
317 read_pending_(false), | |
318 stream_hi_water_mark_(kFirstStreamId), | 317 stream_hi_water_mark_(kFirstStreamId), |
319 write_pending_(false), | 318 write_pending_(false), |
320 delayed_write_pending_(false), | 319 delayed_write_pending_(false), |
321 is_secure_(false), | 320 is_secure_(false), |
322 certificate_error_code_(OK), | 321 certificate_error_code_(OK), |
323 error_(OK), | 322 error_(OK), |
324 state_(IDLE), | 323 state_(STATE_IDLE), |
325 max_concurrent_streams_(initial_max_concurrent_streams == 0 ? | 324 max_concurrent_streams_(initial_max_concurrent_streams == 0 ? |
326 kInitialMaxConcurrentStreams : | 325 kInitialMaxConcurrentStreams : |
327 initial_max_concurrent_streams), | 326 initial_max_concurrent_streams), |
328 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ? | 327 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ? |
329 kMaxConcurrentStreamLimit : | 328 kMaxConcurrentStreamLimit : |
330 max_concurrent_streams_limit), | 329 max_concurrent_streams_limit), |
331 streams_initiated_count_(0), | 330 streams_initiated_count_(0), |
332 streams_pushed_count_(0), | 331 streams_pushed_count_(0), |
333 streams_pushed_and_claimed_count_(0), | 332 streams_pushed_and_claimed_count_(0), |
334 streams_abandoned_count_(0), | 333 streams_abandoned_count_(0), |
335 bytes_received_(0), | 334 total_bytes_received_(0), |
| 335 bytes_read_(0), |
336 sent_settings_(false), | 336 sent_settings_(false), |
337 received_settings_(false), | 337 received_settings_(false), |
338 stalled_streams_(0), | 338 stalled_streams_(0), |
339 pings_in_flight_(0), | 339 pings_in_flight_(0), |
340 next_ping_id_(1), | 340 next_ping_id_(1), |
341 last_activity_time_(base::TimeTicks::Now()), | 341 last_activity_time_(base::TimeTicks::Now()), |
342 check_ping_status_pending_(false), | 342 check_ping_status_pending_(false), |
343 flow_control_state_(FLOW_CONTROL_NONE), | 343 flow_control_state_(FLOW_CONTROL_NONE), |
344 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize), | 344 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize), |
345 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ? | 345 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ? |
(...skipping 20 matching lines...) Expand all Loading... |
366 DCHECK(HttpStreamFactory::spdy_enabled()); | 366 DCHECK(HttpStreamFactory::spdy_enabled()); |
367 net_log_.BeginEvent( | 367 net_log_.BeginEvent( |
368 NetLog::TYPE_SPDY_SESSION, | 368 NetLog::TYPE_SPDY_SESSION, |
369 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair_)); | 369 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair_)); |
370 next_unclaimed_push_stream_sweep_time_ = time_func_() + | 370 next_unclaimed_push_stream_sweep_time_ = time_func_() + |
371 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); | 371 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); |
372 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. | 372 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. |
373 } | 373 } |
374 | 374 |
375 SpdySession::~SpdySession() { | 375 SpdySession::~SpdySession() { |
376 if (state_ != CLOSED) { | 376 if (state_ != STATE_CLOSED) { |
377 state_ = CLOSED; | 377 state_ = STATE_CLOSED; |
378 | 378 |
379 // Cleanup all the streams. | 379 // Cleanup all the streams. |
380 CloseAllStreams(net::ERR_ABORTED); | 380 CloseAllStreams(net::ERR_ABORTED); |
381 } | 381 } |
382 | 382 |
383 if (connection_->is_initialized()) { | 383 if (connection_->is_initialized()) { |
384 // With SPDY we can't recycle sockets. | 384 // With SPDY we can't recycle sockets. |
385 connection_->socket()->Disconnect(); | 385 connection_->socket()->Disconnect(); |
386 } | 386 } |
387 | 387 |
(...skipping 11 matching lines...) Expand all Loading... |
399 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); | 399 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); |
400 } | 400 } |
401 | 401 |
402 net::Error SpdySession::InitializeWithSocket( | 402 net::Error SpdySession::InitializeWithSocket( |
403 ClientSocketHandle* connection, | 403 ClientSocketHandle* connection, |
404 bool is_secure, | 404 bool is_secure, |
405 int certificate_error_code) { | 405 int certificate_error_code) { |
406 base::StatsCounter spdy_sessions("spdy.sessions"); | 406 base::StatsCounter spdy_sessions("spdy.sessions"); |
407 spdy_sessions.Increment(); | 407 spdy_sessions.Increment(); |
408 | 408 |
409 state_ = CONNECTED; | 409 state_ = STATE_DO_READ; |
410 connection_.reset(connection); | 410 connection_.reset(connection); |
411 is_secure_ = is_secure; | 411 is_secure_ = is_secure; |
412 certificate_error_code_ = certificate_error_code; | 412 certificate_error_code_ = certificate_error_code; |
413 | 413 |
414 NextProto protocol = default_protocol_; | 414 NextProto protocol = default_protocol_; |
415 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol(); | 415 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol(); |
416 if (protocol_negotiated != kProtoUnknown) { | 416 if (protocol_negotiated != kProtoUnknown) { |
417 protocol = protocol_negotiated; | 417 protocol = protocol_negotiated; |
418 } | 418 } |
419 | 419 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_); | 451 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_); |
452 // This condition implies that |kDefaultInitialRecvWindowSize| - | 452 // This condition implies that |kDefaultInitialRecvWindowSize| - |
453 // |session_recv_window_size_| doesn't overflow. | 453 // |session_recv_window_size_| doesn't overflow. |
454 DCHECK_GT(session_recv_window_size_, 0); | 454 DCHECK_GT(session_recv_window_size_, 0); |
455 IncreaseRecvWindowSize( | 455 IncreaseRecvWindowSize( |
456 kDefaultInitialRecvWindowSize - session_recv_window_size_); | 456 kDefaultInitialRecvWindowSize - session_recv_window_size_); |
457 } | 457 } |
458 | 458 |
459 // Write out any data that we might have to send, such as the settings frame. | 459 // Write out any data that we might have to send, such as the settings frame. |
460 WriteSocketLater(); | 460 WriteSocketLater(); |
461 net::Error error = ReadSocket(); | 461 int error = DoLoop(OK); |
462 if (error == ERR_IO_PENDING) | 462 if (error == ERR_IO_PENDING) |
463 return OK; | 463 return OK; |
464 return error; | 464 return static_cast<net::Error>(error); |
465 } | 465 } |
466 | 466 |
467 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) { | 467 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) { |
468 if (!verify_domain_authentication_) | 468 if (!verify_domain_authentication_) |
469 return true; | 469 return true; |
470 | 470 |
471 if (state_ != CONNECTED) | 471 if (!IsConnected()) |
472 return false; | 472 return false; |
473 | 473 |
474 SSLInfo ssl_info; | 474 SSLInfo ssl_info; |
475 bool was_npn_negotiated; | 475 bool was_npn_negotiated; |
476 NextProto protocol_negotiated = kProtoUnknown; | 476 NextProto protocol_negotiated = kProtoUnknown; |
477 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) | 477 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) |
478 return true; // This is not a secure session, so all domains are okay. | 478 return true; // This is not a secure session, so all domains are okay. |
479 | 479 |
480 return !ssl_info.client_cert_sent && | 480 return !ssl_info.client_cert_sent && |
481 (enable_credential_frames_ || !ssl_info.channel_id_sent || | 481 (enable_credential_frames_ || !ssl_info.channel_id_sent || |
482 ServerBoundCertService::GetDomainForHost(domain) == | 482 ServerBoundCertService::GetDomainForHost(domain) == |
483 ServerBoundCertService::GetDomainForHost( | 483 ServerBoundCertService::GetDomainForHost( |
484 host_port_proxy_pair_.first.host())) && | 484 host_port_proxy_pair_.first.host())) && |
485 ssl_info.cert->VerifyNameMatch(domain); | 485 ssl_info.cert->VerifyNameMatch(domain); |
486 } | 486 } |
487 | 487 |
488 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream, | 488 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream, |
489 SpdyIOBufferProducer* producer) { | 489 SpdyIOBufferProducer* producer) { |
490 write_queue_.push(producer); | 490 write_queue_.push(producer); |
491 stream_producers_[producer] = stream; | 491 stream_producers_[producer] = stream; |
492 WriteSocketLater(); | 492 WriteSocketLater(); |
493 } | 493 } |
494 | 494 |
495 int SpdySession::GetPushStream( | 495 int SpdySession::GetPushStream( |
496 const GURL& url, | 496 const GURL& url, |
497 scoped_refptr<SpdyStream>* stream, | 497 scoped_refptr<SpdyStream>* stream, |
498 const BoundNetLog& stream_net_log) { | 498 const BoundNetLog& stream_net_log) { |
499 CHECK_NE(state_, CLOSED); | 499 CHECK_NE(state_, STATE_CLOSED); |
500 | 500 |
501 *stream = NULL; | 501 *stream = NULL; |
502 | 502 |
503 // Don't allow access to secure push streams over an unauthenticated, but | 503 // Don't allow access to secure push streams over an unauthenticated, but |
504 // encrypted SSL socket. | 504 // encrypted SSL socket. |
505 if (is_secure_ && certificate_error_code_ != OK && | 505 if (is_secure_ && certificate_error_code_ != OK && |
506 (url.SchemeIs("https") || url.SchemeIs("wss"))) { | 506 (url.SchemeIs("https") || url.SchemeIs("wss"))) { |
507 RecordProtocolErrorHistogram( | 507 RecordProtocolErrorHistogram( |
508 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION); | 508 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION); |
509 CloseSessionOnError( | 509 CloseSessionOnError( |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 return ContainsKey(active_streams_, stream_id); | 859 return ContainsKey(active_streams_, stream_id); |
860 } | 860 } |
861 | 861 |
862 LoadState SpdySession::GetLoadState() const { | 862 LoadState SpdySession::GetLoadState() const { |
863 // NOTE: The application only queries the LoadState via the | 863 // NOTE: The application only queries the LoadState via the |
864 // SpdyNetworkTransaction, and details are only needed when | 864 // SpdyNetworkTransaction, and details are only needed when |
865 // we're in the process of connecting. | 865 // we're in the process of connecting. |
866 | 866 |
867 // If we're connecting, defer to the connection to give us the actual | 867 // If we're connecting, defer to the connection to give us the actual |
868 // LoadState. | 868 // LoadState. |
869 if (state_ == CONNECTING) | 869 if (state_ == STATE_CONNECTING) |
870 return connection_->GetLoadState(); | 870 return connection_->GetLoadState(); |
871 | 871 |
872 // Just report that we're idle since the session could be doing | 872 // Just report that we're idle since the session could be doing |
873 // many things concurrently. | 873 // many things concurrently. |
874 return LOAD_STATE_IDLE; | 874 return LOAD_STATE_IDLE; |
875 } | 875 } |
876 | 876 |
877 void SpdySession::OnReadComplete(int bytes_read) { | 877 void SpdySession::OnReadComplete(int bytes_read) { |
878 // Parse a frame. For now this code requires that the frame fit into our | 878 DCHECK_NE(state_, STATE_DO_READ); |
879 // buffer (32KB). | 879 DoLoop(bytes_read); |
880 // TODO(mbelshe): support arbitrarily large frames! | 880 } |
881 | 881 |
882 read_pending_ = false; | 882 void SpdySession::StartRead() { |
| 883 DCHECK_NE(state_, STATE_DO_READ_COMPLETE); |
| 884 DoLoop(OK); |
| 885 } |
883 | 886 |
884 if (bytes_read <= 0) { | 887 int SpdySession::DoLoop(int result) { |
885 // Session is tearing down. | 888 bytes_read_ = 0; |
886 net::Error error = static_cast<net::Error>(bytes_read); | |
887 if (bytes_read == 0) | |
888 error = ERR_CONNECTION_CLOSED; | |
889 CloseSessionOnError(error, true, "bytes_read is <= 0."); | |
890 return; | |
891 } | |
892 | |
893 bytes_received_ += bytes_read; | |
894 | |
895 last_activity_time_ = base::TimeTicks::Now(); | |
896 | 889 |
897 // The SpdyFramer will use callbacks onto |this| as it parses frames. | 890 // The SpdyFramer will use callbacks onto |this| as it parses frames. |
898 // When errors occur, those callbacks can lead to teardown of all references | 891 // When errors occur, those callbacks can lead to teardown of all references |
899 // to |this|, so maintain a reference to self during this call for safe | 892 // to |this|, so maintain a reference to self during this call for safe |
900 // cleanup. | 893 // cleanup. |
901 scoped_refptr<SpdySession> self(this); | 894 scoped_refptr<SpdySession> self(this); |
902 | 895 |
| 896 do { |
| 897 switch (state_) { |
| 898 case STATE_DO_READ: |
| 899 DCHECK_EQ(result, OK); |
| 900 result = DoRead(); |
| 901 break; |
| 902 case STATE_DO_READ_COMPLETE: |
| 903 result = DoReadComplete(result); |
| 904 break; |
| 905 case STATE_CLOSED: |
| 906 result = ERR_CONNECTION_CLOSED; |
| 907 break; |
| 908 default: |
| 909 NOTREACHED() << "state_: " << state_; |
| 910 break; |
| 911 } |
| 912 } while (result != ERR_IO_PENDING && result != ERR_CONNECTION_CLOSED); |
| 913 |
| 914 return result; |
| 915 } |
| 916 |
| 917 int SpdySession::DoRead() { |
| 918 if (bytes_read_ > kMaxReadBytes) { |
| 919 state_ = STATE_DO_READ; |
| 920 MessageLoop::current()->PostTask( |
| 921 FROM_HERE, |
| 922 base::Bind(&SpdySession::StartRead, |
| 923 weak_factory_.GetWeakPtr())); |
| 924 return ERR_IO_PENDING; |
| 925 } |
| 926 |
| 927 CHECK(connection_.get()); |
| 928 CHECK(connection_->socket()); |
| 929 state_ = STATE_DO_READ_COMPLETE; |
| 930 return connection_->socket()->Read( |
| 931 read_buffer_.get(), |
| 932 kReadBufferSize, |
| 933 base::Bind(&SpdySession::OnReadComplete, weak_factory_.GetWeakPtr())); |
| 934 } |
| 935 |
| 936 int SpdySession::DoReadComplete(int result) { |
| 937 // Parse a frame. For now this code requires that the frame fit into our |
| 938 // buffer (32KB). |
| 939 // TODO(mbelshe): support arbitrarily large frames! |
| 940 |
| 941 if (result <= 0) { |
| 942 // Session is tearing down. |
| 943 net::Error error = static_cast<net::Error>(result); |
| 944 if (result == 0) |
| 945 error = ERR_CONNECTION_CLOSED; |
| 946 CloseSessionOnError(error, true, "result is <= 0."); |
| 947 return ERR_CONNECTION_CLOSED; |
| 948 } |
| 949 |
| 950 total_bytes_received_ += result; |
| 951 bytes_read_ += result; |
| 952 |
| 953 last_activity_time_ = base::TimeTicks::Now(); |
| 954 |
903 DCHECK(buffered_spdy_framer_.get()); | 955 DCHECK(buffered_spdy_framer_.get()); |
904 char* data = read_buffer_->data(); | 956 char* data = read_buffer_->data(); |
905 while (bytes_read && | 957 while (result && |
906 buffered_spdy_framer_->error_code() == | 958 buffered_spdy_framer_->error_code() == |
907 SpdyFramer::SPDY_NO_ERROR) { | 959 SpdyFramer::SPDY_NO_ERROR) { |
908 uint32 bytes_processed = | 960 uint32 bytes_processed = |
909 buffered_spdy_framer_->ProcessInput(data, bytes_read); | 961 buffered_spdy_framer_->ProcessInput(data, result); |
910 bytes_read -= bytes_processed; | 962 result -= bytes_processed; |
911 data += bytes_processed; | 963 data += bytes_processed; |
912 } | 964 } |
913 | 965 |
914 if (state_ != CLOSED) | 966 if (IsConnected()) |
915 ReadSocket(); | 967 state_ = STATE_DO_READ; |
| 968 return OK; |
916 } | 969 } |
917 | 970 |
918 void SpdySession::OnWriteComplete(int result) { | 971 void SpdySession::OnWriteComplete(int result) { |
919 DCHECK(write_pending_); | 972 DCHECK(write_pending_); |
920 DCHECK(in_flight_write_.size()); | 973 DCHECK(in_flight_write_.size()); |
921 | 974 |
922 last_activity_time_ = base::TimeTicks::Now(); | 975 last_activity_time_ = base::TimeTicks::Now(); |
923 write_pending_ = false; | 976 write_pending_ = false; |
924 | 977 |
925 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); | 978 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 WriteSocketLater(); | 1015 WriteSocketLater(); |
963 } else { | 1016 } else { |
964 in_flight_write_.release(); | 1017 in_flight_write_.release(); |
965 | 1018 |
966 // The stream is now errored. Close it down. | 1019 // The stream is now errored. Close it down. |
967 CloseSessionOnError( | 1020 CloseSessionOnError( |
968 static_cast<net::Error>(result), true, "The stream has errored."); | 1021 static_cast<net::Error>(result), true, "The stream has errored."); |
969 } | 1022 } |
970 } | 1023 } |
971 | 1024 |
972 net::Error SpdySession::ReadSocket() { | |
973 if (read_pending_) | |
974 return OK; | |
975 | |
976 if (state_ == CLOSED) { | |
977 NOTREACHED(); | |
978 return ERR_UNEXPECTED; | |
979 } | |
980 | |
981 CHECK(connection_.get()); | |
982 CHECK(connection_->socket()); | |
983 int bytes_read = connection_->socket()->Read( | |
984 read_buffer_.get(), | |
985 kReadBufferSize, | |
986 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this))); | |
987 switch (bytes_read) { | |
988 case 0: | |
989 // Socket is closed! | |
990 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0."); | |
991 return ERR_CONNECTION_CLOSED; | |
992 case net::ERR_IO_PENDING: | |
993 // Waiting for data. Nothing to do now. | |
994 read_pending_ = true; | |
995 return ERR_IO_PENDING; | |
996 default: | |
997 // Data was read, process it. | |
998 // Schedule the work through the message loop to avoid recursive | |
999 // callbacks. | |
1000 read_pending_ = true; | |
1001 MessageLoop::current()->PostTask( | |
1002 FROM_HERE, | |
1003 base::Bind(&SpdySession::OnReadComplete, | |
1004 weak_factory_.GetWeakPtr(), bytes_read)); | |
1005 break; | |
1006 } | |
1007 return OK; | |
1008 } | |
1009 | |
1010 void SpdySession::WriteSocketLater() { | 1025 void SpdySession::WriteSocketLater() { |
1011 if (delayed_write_pending_) | 1026 if (delayed_write_pending_) |
1012 return; | 1027 return; |
1013 | 1028 |
1014 if (state_ < CONNECTED) | 1029 if (!IsConnected()) |
1015 return; | 1030 return; |
1016 | 1031 |
1017 delayed_write_pending_ = true; | 1032 delayed_write_pending_ = true; |
1018 MessageLoop::current()->PostTask( | 1033 MessageLoop::current()->PostTask( |
1019 FROM_HERE, | 1034 FROM_HERE, |
1020 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr())); | 1035 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr())); |
1021 } | 1036 } |
1022 | 1037 |
1023 void SpdySession::WriteSocket() { | 1038 void SpdySession::WriteSocket() { |
1024 // This function should only be called via WriteSocketLater. | 1039 // This function should only be called via WriteSocketLater. |
1025 DCHECK(delayed_write_pending_); | 1040 DCHECK(delayed_write_pending_); |
1026 delayed_write_pending_ = false; | 1041 delayed_write_pending_ = false; |
1027 | 1042 |
1028 // If the socket isn't connected yet, just wait; we'll get called | 1043 // If the socket isn't connected yet, just wait; we'll get called |
1029 // again when the socket connection completes. If the socket is | 1044 // again when the socket connection completes. If the socket is |
1030 // closed, just return. | 1045 // closed, just return. |
1031 if (state_ < CONNECTED || state_ == CLOSED) | 1046 if (!IsConnected()) |
1032 return; | 1047 return; |
1033 | 1048 |
1034 if (write_pending_) // Another write is in progress still. | 1049 if (write_pending_) // Another write is in progress still. |
1035 return; | 1050 return; |
1036 | 1051 |
1037 // Loop sending frames until we've sent everything or until the write | 1052 // Loop sending frames until we've sent everything or until the write |
1038 // returns error (or ERR_IO_PENDING). | 1053 // returns error (or ERR_IO_PENDING). |
1039 DCHECK(buffered_spdy_framer_.get()); | 1054 DCHECK(buffered_spdy_framer_.get()); |
1040 while (in_flight_write_.buffer() || !write_queue_.empty()) { | 1055 while (in_flight_write_.buffer() || !write_queue_.empty()) { |
1041 if (!in_flight_write_.buffer()) { | 1056 if (!in_flight_write_.buffer()) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 scoped_refptr<SpdySession> self(this); | 1159 scoped_refptr<SpdySession> self(this); |
1145 | 1160 |
1146 DCHECK_LT(err, OK); | 1161 DCHECK_LT(err, OK); |
1147 net_log_.AddEvent( | 1162 net_log_.AddEvent( |
1148 NetLog::TYPE_SPDY_SESSION_CLOSE, | 1163 NetLog::TYPE_SPDY_SESSION_CLOSE, |
1149 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); | 1164 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); |
1150 | 1165 |
1151 // Don't close twice. This can occur because we can have both | 1166 // Don't close twice. This can occur because we can have both |
1152 // a read and a write outstanding, and each can complete with | 1167 // a read and a write outstanding, and each can complete with |
1153 // an error. | 1168 // an error. |
1154 if (state_ != CLOSED) { | 1169 if (!IsClosed()) { |
1155 state_ = CLOSED; | 1170 state_ = STATE_CLOSED; |
1156 error_ = err; | 1171 error_ = err; |
1157 if (remove_from_pool) | 1172 if (remove_from_pool) |
1158 RemoveFromPool(); | 1173 RemoveFromPool(); |
1159 CloseAllStreams(err); | 1174 CloseAllStreams(err); |
1160 } | 1175 } |
1161 } | 1176 } |
1162 | 1177 |
1163 base::Value* SpdySession::GetInfoAsValue() const { | 1178 base::Value* SpdySession::GetInfoAsValue() const { |
1164 base::DictionaryValue* dict = new base::DictionaryValue(); | 1179 base::DictionaryValue* dict = new base::DictionaryValue(); |
1165 | 1180 |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2102 SettingsMap::const_iterator it; | 2117 SettingsMap::const_iterator it; |
2103 for (it = settings_map.begin(); it != settings_map.end(); ++it) { | 2118 for (it = settings_map.begin(); it != settings_map.end(); ++it) { |
2104 const SpdySettingsIds id = it->first; | 2119 const SpdySettingsIds id = it->first; |
2105 const uint32 val = it->second.second; | 2120 const uint32 val = it->second.second; |
2106 switch (id) { | 2121 switch (id) { |
2107 case SETTINGS_CURRENT_CWND: | 2122 case SETTINGS_CURRENT_CWND: |
2108 // Record several different histograms to see if cwnd converges | 2123 // Record several different histograms to see if cwnd converges |
2109 // for larger volumes of data being sent. | 2124 // for larger volumes of data being sent. |
2110 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", | 2125 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", |
2111 val, 1, 200, 100); | 2126 val, 1, 200, 100); |
2112 if (bytes_received_ > 10 * 1024) { | 2127 if (total_bytes_received_ > 10 * 1024) { |
2113 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", | 2128 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", |
2114 val, 1, 200, 100); | 2129 val, 1, 200, 100); |
2115 if (bytes_received_ > 25 * 1024) { | 2130 if (total_bytes_received_ > 25 * 1024) { |
2116 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K", | 2131 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K", |
2117 val, 1, 200, 100); | 2132 val, 1, 200, 100); |
2118 if (bytes_received_ > 50 * 1024) { | 2133 if (total_bytes_received_ > 50 * 1024) { |
2119 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K", | 2134 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K", |
2120 val, 1, 200, 100); | 2135 val, 1, 200, 100); |
2121 if (bytes_received_ > 100 * 1024) { | 2136 if (total_bytes_received_ > 100 * 1024) { |
2122 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K", | 2137 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K", |
2123 val, 1, 200, 100); | 2138 val, 1, 200, 100); |
2124 } | 2139 } |
2125 } | 2140 } |
2126 } | 2141 } |
2127 } | 2142 } |
2128 break; | 2143 break; |
2129 case SETTINGS_ROUND_TRIP_TIME: | 2144 case SETTINGS_ROUND_TRIP_TIME: |
2130 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", | 2145 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", |
2131 val, 1, 1200, 100); | 2146 val, 1, 1200, 100); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2290 } | 2305 } |
2291 | 2306 |
2292 session_recv_window_size_ -= delta_window_size; | 2307 session_recv_window_size_ -= delta_window_size; |
2293 net_log_.AddEvent( | 2308 net_log_.AddEvent( |
2294 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, | 2309 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, |
2295 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2310 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
2296 -delta_window_size, session_recv_window_size_)); | 2311 -delta_window_size, session_recv_window_size_)); |
2297 } | 2312 } |
2298 | 2313 |
2299 } // namespace net | 2314 } // namespace net |
OLD | NEW |