| 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 <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 size_t max_concurrent_streams_limit, | 226 size_t max_concurrent_streams_limit, |
| 227 TimeFunc time_func, | 227 TimeFunc time_func, |
| 228 const HostPortPair& trusted_spdy_proxy, | 228 const HostPortPair& trusted_spdy_proxy, |
| 229 NetLog* net_log) | 229 NetLog* net_log) |
| 230 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 230 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 231 host_port_proxy_pair_(host_port_proxy_pair), | 231 host_port_proxy_pair_(host_port_proxy_pair), |
| 232 spdy_session_pool_(spdy_session_pool), | 232 spdy_session_pool_(spdy_session_pool), |
| 233 http_server_properties_(http_server_properties), | 233 http_server_properties_(http_server_properties), |
| 234 connection_(new ClientSocketHandle), | 234 connection_(new ClientSocketHandle), |
| 235 read_buffer_(new IOBuffer(kReadBufferSize)), | 235 read_buffer_(new IOBuffer(kReadBufferSize)), |
| 236 read_pending_(false), | |
| 237 stream_hi_water_mark_(kFirstStreamId), | 236 stream_hi_water_mark_(kFirstStreamId), |
| 238 write_pending_(false), | 237 write_pending_(false), |
| 239 delayed_write_pending_(false), | 238 delayed_write_pending_(false), |
| 240 is_secure_(false), | 239 is_secure_(false), |
| 241 certificate_error_code_(OK), | 240 certificate_error_code_(OK), |
| 242 error_(OK), | 241 error_(OK), |
| 243 state_(IDLE), | 242 state_(STATE_IDLE), |
| 244 max_concurrent_streams_(initial_max_concurrent_streams == 0 ? | 243 max_concurrent_streams_(initial_max_concurrent_streams == 0 ? |
| 245 kInitialMaxConcurrentStreams : | 244 kInitialMaxConcurrentStreams : |
| 246 initial_max_concurrent_streams), | 245 initial_max_concurrent_streams), |
| 247 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ? | 246 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ? |
| 248 kMaxConcurrentStreamLimit : | 247 kMaxConcurrentStreamLimit : |
| 249 max_concurrent_streams_limit), | 248 max_concurrent_streams_limit), |
| 250 streams_initiated_count_(0), | 249 streams_initiated_count_(0), |
| 251 streams_pushed_count_(0), | 250 streams_pushed_count_(0), |
| 252 streams_pushed_and_claimed_count_(0), | 251 streams_pushed_and_claimed_count_(0), |
| 253 streams_abandoned_count_(0), | 252 streams_abandoned_count_(0), |
| 254 bytes_received_(0), | 253 total_bytes_received_(0), |
| 254 bytes_read_(0), |
| 255 sent_settings_(false), | 255 sent_settings_(false), |
| 256 received_settings_(false), | 256 received_settings_(false), |
| 257 stalled_streams_(0), | 257 stalled_streams_(0), |
| 258 pings_in_flight_(0), | 258 pings_in_flight_(0), |
| 259 next_ping_id_(1), | 259 next_ping_id_(1), |
| 260 last_activity_time_(base::TimeTicks::Now()), | 260 last_activity_time_(base::TimeTicks::Now()), |
| 261 check_ping_status_pending_(false), | 261 check_ping_status_pending_(false), |
| 262 flow_control_(false), | 262 flow_control_(false), |
| 263 initial_send_window_size_(kSpdyStreamInitialWindowSize), | 263 initial_send_window_size_(kSpdyStreamInitialWindowSize), |
| 264 initial_recv_window_size_(initial_recv_window_size == 0 ? | 264 initial_recv_window_size_(initial_recv_window_size == 0 ? |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 | 304 |
| 305 SpdySession::CallbackResultPair::CallbackResultPair( | 305 SpdySession::CallbackResultPair::CallbackResultPair( |
| 306 const CompletionCallback& callback_in, int result_in) | 306 const CompletionCallback& callback_in, int result_in) |
| 307 : callback(callback_in), | 307 : callback(callback_in), |
| 308 result(result_in) { | 308 result(result_in) { |
| 309 } | 309 } |
| 310 | 310 |
| 311 SpdySession::CallbackResultPair::~CallbackResultPair() {} | 311 SpdySession::CallbackResultPair::~CallbackResultPair() {} |
| 312 | 312 |
| 313 SpdySession::~SpdySession() { | 313 SpdySession::~SpdySession() { |
| 314 if (state_ != CLOSED) { | 314 if (state_ != STATE_CLOSED) { |
| 315 state_ = CLOSED; | 315 state_ = STATE_CLOSED; |
| 316 | 316 |
| 317 // Cleanup all the streams. | 317 // Cleanup all the streams. |
| 318 CloseAllStreams(net::ERR_ABORTED); | 318 CloseAllStreams(net::ERR_ABORTED); |
| 319 } | 319 } |
| 320 | 320 |
| 321 if (connection_->is_initialized()) { | 321 if (connection_->is_initialized()) { |
| 322 // With SPDY we can't recycle sockets. | 322 // With SPDY we can't recycle sockets. |
| 323 connection_->socket()->Disconnect(); | 323 connection_->socket()->Disconnect(); |
| 324 } | 324 } |
| 325 | 325 |
| 326 // Streams should all be gone now. | 326 // Streams should all be gone now. |
| 327 DCHECK_EQ(0u, num_active_streams()); | 327 DCHECK_EQ(0u, num_active_streams()); |
| 328 DCHECK_EQ(0u, num_unclaimed_pushed_streams()); | 328 DCHECK_EQ(0u, num_unclaimed_pushed_streams()); |
| 329 | 329 |
| 330 DCHECK(pending_callback_map_.empty()); | 330 DCHECK(pending_callback_map_.empty()); |
| 331 | 331 |
| 332 RecordHistograms(); | 332 RecordHistograms(); |
| 333 | 333 |
| 334 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); | 334 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); |
| 335 } | 335 } |
| 336 | 336 |
| 337 net::Error SpdySession::InitializeWithSocket( | 337 net::Error SpdySession::InitializeWithSocket( |
| 338 ClientSocketHandle* connection, | 338 ClientSocketHandle* connection, |
| 339 bool is_secure, | 339 bool is_secure, |
| 340 int certificate_error_code) { | 340 int certificate_error_code) { |
| 341 base::StatsCounter spdy_sessions("spdy.sessions"); | 341 base::StatsCounter spdy_sessions("spdy.sessions"); |
| 342 spdy_sessions.Increment(); | 342 spdy_sessions.Increment(); |
| 343 | 343 |
| 344 state_ = CONNECTED; | 344 state_ = STATE_DO_READ; |
| 345 connection_.reset(connection); | 345 connection_.reset(connection); |
| 346 is_secure_ = is_secure; | 346 is_secure_ = is_secure; |
| 347 certificate_error_code_ = certificate_error_code; | 347 certificate_error_code_ = certificate_error_code; |
| 348 | 348 |
| 349 NextProto protocol = default_protocol_; | 349 NextProto protocol = default_protocol_; |
| 350 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol(); | 350 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol(); |
| 351 if (protocol_negotiated != kProtoUnknown) { | 351 if (protocol_negotiated != kProtoUnknown) { |
| 352 protocol = protocol_negotiated; | 352 protocol = protocol_negotiated; |
| 353 } | 353 } |
| 354 | 354 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 366 flow_control_ = (protocol >= kProtoSPDY3); | 366 flow_control_ = (protocol >= kProtoSPDY3); |
| 367 | 367 |
| 368 buffered_spdy_framer_.reset(new BufferedSpdyFramer(version, | 368 buffered_spdy_framer_.reset(new BufferedSpdyFramer(version, |
| 369 enable_compression_)); | 369 enable_compression_)); |
| 370 buffered_spdy_framer_->set_visitor(this); | 370 buffered_spdy_framer_->set_visitor(this); |
| 371 SendInitialSettings(); | 371 SendInitialSettings(); |
| 372 UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol, kProtoMaximumVersion); | 372 UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol, kProtoMaximumVersion); |
| 373 | 373 |
| 374 // Write out any data that we might have to send, such as the settings frame. | 374 // Write out any data that we might have to send, such as the settings frame. |
| 375 WriteSocketLater(); | 375 WriteSocketLater(); |
| 376 net::Error error = ReadSocket(); | 376 int error = DoLoop(OK); |
| 377 if (error == ERR_IO_PENDING) | 377 if (error == ERR_IO_PENDING) |
| 378 return OK; | 378 return OK; |
| 379 return error; | 379 return static_cast<net::Error>(error); |
| 380 } | 380 } |
| 381 | 381 |
| 382 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) { | 382 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) { |
| 383 if (!verify_domain_authentication_) | 383 if (!verify_domain_authentication_) |
| 384 return true; | 384 return true; |
| 385 | 385 |
| 386 if (state_ != CONNECTED) | 386 if (!IsConnected()) |
| 387 return false; | 387 return false; |
| 388 | 388 |
| 389 SSLInfo ssl_info; | 389 SSLInfo ssl_info; |
| 390 bool was_npn_negotiated; | 390 bool was_npn_negotiated; |
| 391 NextProto protocol_negotiated = kProtoUnknown; | 391 NextProto protocol_negotiated = kProtoUnknown; |
| 392 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) | 392 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) |
| 393 return true; // This is not a secure session, so all domains are okay. | 393 return true; // This is not a secure session, so all domains are okay. |
| 394 | 394 |
| 395 return !ssl_info.client_cert_sent && | 395 return !ssl_info.client_cert_sent && |
| 396 (enable_credential_frames_ || !ssl_info.channel_id_sent || | 396 (enable_credential_frames_ || !ssl_info.channel_id_sent || |
| 397 ServerBoundCertService::GetDomainForHost(domain) == | 397 ServerBoundCertService::GetDomainForHost(domain) == |
| 398 ServerBoundCertService::GetDomainForHost( | 398 ServerBoundCertService::GetDomainForHost( |
| 399 host_port_proxy_pair_.first.host())) && | 399 host_port_proxy_pair_.first.host())) && |
| 400 ssl_info.cert->VerifyNameMatch(domain); | 400 ssl_info.cert->VerifyNameMatch(domain); |
| 401 } | 401 } |
| 402 | 402 |
| 403 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream, | 403 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream, |
| 404 SpdyIOBufferProducer* producer) { | 404 SpdyIOBufferProducer* producer) { |
| 405 write_queue_.push(producer); | 405 write_queue_.push(producer); |
| 406 stream_producers_[producer] = stream; | 406 stream_producers_[producer] = stream; |
| 407 WriteSocketLater(); | 407 WriteSocketLater(); |
| 408 } | 408 } |
| 409 | 409 |
| 410 int SpdySession::GetPushStream( | 410 int SpdySession::GetPushStream( |
| 411 const GURL& url, | 411 const GURL& url, |
| 412 scoped_refptr<SpdyStream>* stream, | 412 scoped_refptr<SpdyStream>* stream, |
| 413 const BoundNetLog& stream_net_log) { | 413 const BoundNetLog& stream_net_log) { |
| 414 CHECK_NE(state_, CLOSED); | 414 CHECK_NE(state_, STATE_CLOSED); |
| 415 | 415 |
| 416 *stream = NULL; | 416 *stream = NULL; |
| 417 | 417 |
| 418 // Don't allow access to secure push streams over an unauthenticated, but | 418 // Don't allow access to secure push streams over an unauthenticated, but |
| 419 // encrypted SSL socket. | 419 // encrypted SSL socket. |
| 420 if (is_secure_ && certificate_error_code_ != OK && | 420 if (is_secure_ && certificate_error_code_ != OK && |
| 421 (url.SchemeIs("https") || url.SchemeIs("wss"))) { | 421 (url.SchemeIs("https") || url.SchemeIs("wss"))) { |
| 422 RecordProtocolErrorHistogram( | 422 RecordProtocolErrorHistogram( |
| 423 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION); | 423 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION); |
| 424 CloseSessionOnError( | 424 CloseSessionOnError( |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 return ContainsKey(active_streams_, stream_id); | 764 return ContainsKey(active_streams_, stream_id); |
| 765 } | 765 } |
| 766 | 766 |
| 767 LoadState SpdySession::GetLoadState() const { | 767 LoadState SpdySession::GetLoadState() const { |
| 768 // NOTE: The application only queries the LoadState via the | 768 // NOTE: The application only queries the LoadState via the |
| 769 // SpdyNetworkTransaction, and details are only needed when | 769 // SpdyNetworkTransaction, and details are only needed when |
| 770 // we're in the process of connecting. | 770 // we're in the process of connecting. |
| 771 | 771 |
| 772 // If we're connecting, defer to the connection to give us the actual | 772 // If we're connecting, defer to the connection to give us the actual |
| 773 // LoadState. | 773 // LoadState. |
| 774 if (state_ == CONNECTING) | 774 if (state_ == STATE_CONNECTING) |
| 775 return connection_->GetLoadState(); | 775 return connection_->GetLoadState(); |
| 776 | 776 |
| 777 // Just report that we're idle since the session could be doing | 777 // Just report that we're idle since the session could be doing |
| 778 // many things concurrently. | 778 // many things concurrently. |
| 779 return LOAD_STATE_IDLE; | 779 return LOAD_STATE_IDLE; |
| 780 } | 780 } |
| 781 | 781 |
| 782 void SpdySession::OnReadComplete(int bytes_read) { | 782 void SpdySession::OnReadComplete(int bytes_read) { |
| 783 DCHECK_NE(state_, STATE_DO_READ); |
| 784 DoLoop(bytes_read); |
| 785 } |
| 786 |
| 787 void SpdySession::StartRead() { |
| 788 DCHECK_NE(state_, STATE_DO_READ_COMPLETE); |
| 789 DoLoop(OK); |
| 790 } |
| 791 |
| 792 int SpdySession::DoLoop(int result) { |
| 793 bytes_read_ = 0; |
| 794 do { |
| 795 switch (state_) { |
| 796 case STATE_DO_READ: |
| 797 DCHECK_EQ(result, OK); |
| 798 result = DoRead(); |
| 799 break; |
| 800 case STATE_DO_READ_COMPLETE: |
| 801 result = DoReadComplete(result); |
| 802 break; |
| 803 case STATE_CLOSED: |
| 804 result = ERR_CONNECTION_CLOSED; |
| 805 break; |
| 806 default: |
| 807 NOTREACHED() << "state_: " << state_; |
| 808 break; |
| 809 } |
| 810 } while (result != ERR_IO_PENDING && result != ERR_CONNECTION_CLOSED); |
| 811 |
| 812 return result; |
| 813 } |
| 814 |
| 815 int SpdySession::DoRead() { |
| 816 if (bytes_read_ > kMaxReadBytes) { |
| 817 state_ = STATE_DO_READ; |
| 818 MessageLoop::current()->PostTask( |
| 819 FROM_HERE, |
| 820 base::Bind(&SpdySession::StartRead, |
| 821 weak_factory_.GetWeakPtr())); |
| 822 return ERR_IO_PENDING; |
| 823 } |
| 824 |
| 825 CHECK(connection_.get()); |
| 826 CHECK(connection_->socket()); |
| 827 state_ = STATE_DO_READ_COMPLETE; |
| 828 return connection_->socket()->Read( |
| 829 read_buffer_.get(), |
| 830 kReadBufferSize, |
| 831 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this))); |
| 832 } |
| 833 |
| 834 int SpdySession::DoReadComplete(int result) { |
| 783 // Parse a frame. For now this code requires that the frame fit into our | 835 // Parse a frame. For now this code requires that the frame fit into our |
| 784 // buffer (32KB). | 836 // buffer (32KB). |
| 785 // TODO(mbelshe): support arbitrarily large frames! | 837 // TODO(mbelshe): support arbitrarily large frames! |
| 786 | 838 |
| 787 read_pending_ = false; | 839 if (result <= 0) { |
| 788 | |
| 789 if (bytes_read <= 0) { | |
| 790 // Session is tearing down. | 840 // Session is tearing down. |
| 791 net::Error error = static_cast<net::Error>(bytes_read); | 841 net::Error error = static_cast<net::Error>(result); |
| 792 if (bytes_read == 0) | 842 if (result == 0) |
| 793 error = ERR_CONNECTION_CLOSED; | 843 error = ERR_CONNECTION_CLOSED; |
| 794 CloseSessionOnError(error, true, "bytes_read is <= 0."); | 844 CloseSessionOnError(error, true, "result is <= 0."); |
| 795 return; | 845 return ERR_CONNECTION_CLOSED; |
| 796 } | 846 } |
| 797 | 847 |
| 798 bytes_received_ += bytes_read; | 848 total_bytes_received_ += result; |
| 849 bytes_read_ += result; |
| 799 | 850 |
| 800 last_activity_time_ = base::TimeTicks::Now(); | 851 last_activity_time_ = base::TimeTicks::Now(); |
| 801 | 852 |
| 802 // The SpdyFramer will use callbacks onto |this| as it parses frames. | 853 // The SpdyFramer will use callbacks onto |this| as it parses frames. |
| 803 // When errors occur, those callbacks can lead to teardown of all references | 854 // When errors occur, those callbacks can lead to teardown of all references |
| 804 // to |this|, so maintain a reference to self during this call for safe | 855 // to |this|, so maintain a reference to self during this call for safe |
| 805 // cleanup. | 856 // cleanup. |
| 806 scoped_refptr<SpdySession> self(this); | 857 scoped_refptr<SpdySession> self(this); |
| 807 | 858 |
| 808 DCHECK(buffered_spdy_framer_.get()); | 859 DCHECK(buffered_spdy_framer_.get()); |
| 809 char *data = read_buffer_->data(); | 860 char *data = read_buffer_->data(); |
| 810 while (bytes_read && | 861 while (result && |
| 811 buffered_spdy_framer_->error_code() == | 862 buffered_spdy_framer_->error_code() == |
| 812 SpdyFramer::SPDY_NO_ERROR) { | 863 SpdyFramer::SPDY_NO_ERROR) { |
| 813 uint32 bytes_processed = | 864 uint32 bytes_processed = |
| 814 buffered_spdy_framer_->ProcessInput(data, bytes_read); | 865 buffered_spdy_framer_->ProcessInput(data, result); |
| 815 bytes_read -= bytes_processed; | 866 result -= bytes_processed; |
| 816 data += bytes_processed; | 867 data += bytes_processed; |
| 817 if (buffered_spdy_framer_->state() == SpdyFramer::SPDY_DONE) | 868 if (buffered_spdy_framer_->state() == SpdyFramer::SPDY_DONE) |
| 818 buffered_spdy_framer_->Reset(); | 869 buffered_spdy_framer_->Reset(); |
| 819 } | 870 } |
| 820 | 871 |
| 821 if (state_ != CLOSED) | 872 if (IsConnected()) |
| 822 ReadSocket(); | 873 state_ = STATE_DO_READ; |
| 874 return OK; |
| 823 } | 875 } |
| 824 | 876 |
| 825 void SpdySession::OnWriteComplete(int result) { | 877 void SpdySession::OnWriteComplete(int result) { |
| 826 DCHECK(write_pending_); | 878 DCHECK(write_pending_); |
| 827 DCHECK(in_flight_write_.size()); | 879 DCHECK(in_flight_write_.size()); |
| 828 | 880 |
| 829 last_activity_time_ = base::TimeTicks::Now(); | 881 last_activity_time_ = base::TimeTicks::Now(); |
| 830 write_pending_ = false; | 882 write_pending_ = false; |
| 831 | 883 |
| 832 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); | 884 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 WriteSocketLater(); | 919 WriteSocketLater(); |
| 868 } else { | 920 } else { |
| 869 in_flight_write_.release(); | 921 in_flight_write_.release(); |
| 870 | 922 |
| 871 // The stream is now errored. Close it down. | 923 // The stream is now errored. Close it down. |
| 872 CloseSessionOnError( | 924 CloseSessionOnError( |
| 873 static_cast<net::Error>(result), true, "The stream has errored."); | 925 static_cast<net::Error>(result), true, "The stream has errored."); |
| 874 } | 926 } |
| 875 } | 927 } |
| 876 | 928 |
| 877 net::Error SpdySession::ReadSocket() { | |
| 878 if (read_pending_) | |
| 879 return OK; | |
| 880 | |
| 881 if (state_ == CLOSED) { | |
| 882 NOTREACHED(); | |
| 883 return ERR_UNEXPECTED; | |
| 884 } | |
| 885 | |
| 886 CHECK(connection_.get()); | |
| 887 CHECK(connection_->socket()); | |
| 888 int bytes_read = connection_->socket()->Read( | |
| 889 read_buffer_.get(), | |
| 890 kReadBufferSize, | |
| 891 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this))); | |
| 892 switch (bytes_read) { | |
| 893 case 0: | |
| 894 // Socket is closed! | |
| 895 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0."); | |
| 896 return ERR_CONNECTION_CLOSED; | |
| 897 case net::ERR_IO_PENDING: | |
| 898 // Waiting for data. Nothing to do now. | |
| 899 read_pending_ = true; | |
| 900 return ERR_IO_PENDING; | |
| 901 default: | |
| 902 // Data was read, process it. | |
| 903 // Schedule the work through the message loop to avoid recursive | |
| 904 // callbacks. | |
| 905 read_pending_ = true; | |
| 906 MessageLoop::current()->PostTask( | |
| 907 FROM_HERE, | |
| 908 base::Bind(&SpdySession::OnReadComplete, | |
| 909 weak_factory_.GetWeakPtr(), bytes_read)); | |
| 910 break; | |
| 911 } | |
| 912 return OK; | |
| 913 } | |
| 914 | |
| 915 void SpdySession::WriteSocketLater() { | 929 void SpdySession::WriteSocketLater() { |
| 916 if (delayed_write_pending_) | 930 if (delayed_write_pending_) |
| 917 return; | 931 return; |
| 918 | 932 |
| 919 if (state_ < CONNECTED) | 933 if (!IsConnected()) |
| 920 return; | 934 return; |
| 921 | 935 |
| 922 delayed_write_pending_ = true; | 936 delayed_write_pending_ = true; |
| 923 MessageLoop::current()->PostTask( | 937 MessageLoop::current()->PostTask( |
| 924 FROM_HERE, | 938 FROM_HERE, |
| 925 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr())); | 939 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr())); |
| 926 } | 940 } |
| 927 | 941 |
| 928 void SpdySession::WriteSocket() { | 942 void SpdySession::WriteSocket() { |
| 929 // This function should only be called via WriteSocketLater. | 943 // This function should only be called via WriteSocketLater. |
| 930 DCHECK(delayed_write_pending_); | 944 DCHECK(delayed_write_pending_); |
| 931 delayed_write_pending_ = false; | 945 delayed_write_pending_ = false; |
| 932 | 946 |
| 933 // If the socket isn't connected yet, just wait; we'll get called | 947 // If the socket isn't connected yet, just wait; we'll get called |
| 934 // again when the socket connection completes. If the socket is | 948 // again when the socket connection completes. If the socket is |
| 935 // closed, just return. | 949 // closed, just return. |
| 936 if (state_ < CONNECTED || state_ == CLOSED) | 950 if (!IsConnected()) |
| 937 return; | 951 return; |
| 938 | 952 |
| 939 if (write_pending_) // Another write is in progress still. | 953 if (write_pending_) // Another write is in progress still. |
| 940 return; | 954 return; |
| 941 | 955 |
| 942 // Loop sending frames until we've sent everything or until the write | 956 // Loop sending frames until we've sent everything or until the write |
| 943 // returns error (or ERR_IO_PENDING). | 957 // returns error (or ERR_IO_PENDING). |
| 944 DCHECK(buffered_spdy_framer_.get()); | 958 DCHECK(buffered_spdy_framer_.get()); |
| 945 while (in_flight_write_.buffer() || !write_queue_.empty()) { | 959 while (in_flight_write_.buffer() || !write_queue_.empty()) { |
| 946 if (!in_flight_write_.buffer()) { | 960 if (!in_flight_write_.buffer()) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 scoped_refptr<SpdySession> self(this); | 1063 scoped_refptr<SpdySession> self(this); |
| 1050 | 1064 |
| 1051 DCHECK_LT(err, OK); | 1065 DCHECK_LT(err, OK); |
| 1052 net_log_.AddEvent( | 1066 net_log_.AddEvent( |
| 1053 NetLog::TYPE_SPDY_SESSION_CLOSE, | 1067 NetLog::TYPE_SPDY_SESSION_CLOSE, |
| 1054 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); | 1068 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); |
| 1055 | 1069 |
| 1056 // Don't close twice. This can occur because we can have both | 1070 // Don't close twice. This can occur because we can have both |
| 1057 // a read and a write outstanding, and each can complete with | 1071 // a read and a write outstanding, and each can complete with |
| 1058 // an error. | 1072 // an error. |
| 1059 if (state_ != CLOSED) { | 1073 if (!IsClosed()) { |
| 1060 state_ = CLOSED; | 1074 state_ = STATE_CLOSED; |
| 1061 error_ = err; | 1075 error_ = err; |
| 1062 if (remove_from_pool) | 1076 if (remove_from_pool) |
| 1063 RemoveFromPool(); | 1077 RemoveFromPool(); |
| 1064 CloseAllStreams(err); | 1078 CloseAllStreams(err); |
| 1065 } | 1079 } |
| 1066 } | 1080 } |
| 1067 | 1081 |
| 1068 Value* SpdySession::GetInfoAsValue() const { | 1082 Value* SpdySession::GetInfoAsValue() const { |
| 1069 DictionaryValue* dict = new DictionaryValue(); | 1083 DictionaryValue* dict = new DictionaryValue(); |
| 1070 | 1084 |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 SettingsMap::const_iterator it; | 1928 SettingsMap::const_iterator it; |
| 1915 for (it = settings_map.begin(); it != settings_map.end(); ++it) { | 1929 for (it = settings_map.begin(); it != settings_map.end(); ++it) { |
| 1916 const SpdySettingsIds id = it->first; | 1930 const SpdySettingsIds id = it->first; |
| 1917 const uint32 val = it->second.second; | 1931 const uint32 val = it->second.second; |
| 1918 switch (id) { | 1932 switch (id) { |
| 1919 case SETTINGS_CURRENT_CWND: | 1933 case SETTINGS_CURRENT_CWND: |
| 1920 // Record several different histograms to see if cwnd converges | 1934 // Record several different histograms to see if cwnd converges |
| 1921 // for larger volumes of data being sent. | 1935 // for larger volumes of data being sent. |
| 1922 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", | 1936 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", |
| 1923 val, 1, 200, 100); | 1937 val, 1, 200, 100); |
| 1924 if (bytes_received_ > 10 * 1024) { | 1938 if (total_bytes_received_ > 10 * 1024) { |
| 1925 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", | 1939 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", |
| 1926 val, 1, 200, 100); | 1940 val, 1, 200, 100); |
| 1927 if (bytes_received_ > 25 * 1024) { | 1941 if (total_bytes_received_ > 25 * 1024) { |
| 1928 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K", | 1942 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K", |
| 1929 val, 1, 200, 100); | 1943 val, 1, 200, 100); |
| 1930 if (bytes_received_ > 50 * 1024) { | 1944 if (total_bytes_received_ > 50 * 1024) { |
| 1931 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K", | 1945 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K", |
| 1932 val, 1, 200, 100); | 1946 val, 1, 200, 100); |
| 1933 if (bytes_received_ > 100 * 1024) { | 1947 if (total_bytes_received_ > 100 * 1024) { |
| 1934 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K", | 1948 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K", |
| 1935 val, 1, 200, 100); | 1949 val, 1, 200, 100); |
| 1936 } | 1950 } |
| 1937 } | 1951 } |
| 1938 } | 1952 } |
| 1939 } | 1953 } |
| 1940 break; | 1954 break; |
| 1941 case SETTINGS_ROUND_TRIP_TIME: | 1955 case SETTINGS_ROUND_TRIP_TIME: |
| 1942 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", | 1956 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", |
| 1943 val, 1, 1200, 100); | 1957 val, 1, 1200, 100); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1970 SSLClientSocket* SpdySession::GetSSLClientSocket() const { | 1984 SSLClientSocket* SpdySession::GetSSLClientSocket() const { |
| 1971 if (!is_secure_) | 1985 if (!is_secure_) |
| 1972 return NULL; | 1986 return NULL; |
| 1973 SSLClientSocket* ssl_socket = | 1987 SSLClientSocket* ssl_socket = |
| 1974 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | 1988 reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
| 1975 DCHECK(ssl_socket); | 1989 DCHECK(ssl_socket); |
| 1976 return ssl_socket; | 1990 return ssl_socket; |
| 1977 } | 1991 } |
| 1978 | 1992 |
| 1979 } // namespace net | 1993 } // namespace net |
| OLD | NEW |