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 |