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