Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: net/spdy/spdy_session.cc

Issue 10233016: Add a new UMA histogram for tracking SpdySessionErrorDetails (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/logging.h" 10 #include "base/logging.h"
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 CHECK_NE(state_, CLOSED); 490 CHECK_NE(state_, CLOSED);
491 491
492 *stream = NULL; 492 *stream = NULL;
493 493
494 // Don't allow access to secure push streams over an unauthenticated, but 494 // Don't allow access to secure push streams over an unauthenticated, but
495 // encrypted SSL socket. 495 // encrypted SSL socket.
496 if (is_secure_ && certificate_error_code_ != OK && 496 if (is_secure_ && certificate_error_code_ != OK &&
497 (url.SchemeIs("https") || url.SchemeIs("wss"))) { 497 (url.SchemeIs("https") || url.SchemeIs("wss"))) {
498 CloseSessionOnError( 498 CloseSessionOnError(
499 static_cast<net::Error>(certificate_error_code_), 499 static_cast<net::Error>(certificate_error_code_),
500 REQUST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION,
500 true, 501 true,
501 "Tried to get SPDY stream for secure content over an unauthenticated " 502 "Tried to get SPDY stream for secure content over an unauthenticated "
502 "session."); 503 "session.");
503 return ERR_SPDY_PROTOCOL_ERROR; 504 return ERR_SPDY_PROTOCOL_ERROR;
504 } 505 }
505 506
506 *stream = GetActivePushStream(url.spec()); 507 *stream = GetActivePushStream(url.spec());
507 if (stream->get()) { 508 if (stream->get()) {
508 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); 509 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_);
509 streams_pushed_and_claimed_count_++; 510 streams_pushed_and_claimed_count_++;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 const BoundNetLog& stream_net_log) { 593 const BoundNetLog& stream_net_log) {
593 DCHECK_GE(priority, MINIMUM_PRIORITY); 594 DCHECK_GE(priority, MINIMUM_PRIORITY);
594 DCHECK_LT(priority, NUM_PRIORITIES); 595 DCHECK_LT(priority, NUM_PRIORITIES);
595 596
596 // Make sure that we don't try to send https/wss over an unauthenticated, but 597 // Make sure that we don't try to send https/wss over an unauthenticated, but
597 // encrypted SSL socket. 598 // encrypted SSL socket.
598 if (is_secure_ && certificate_error_code_ != OK && 599 if (is_secure_ && certificate_error_code_ != OK &&
599 (url.SchemeIs("https") || url.SchemeIs("wss"))) { 600 (url.SchemeIs("https") || url.SchemeIs("wss"))) {
600 CloseSessionOnError( 601 CloseSessionOnError(
601 static_cast<net::Error>(certificate_error_code_), 602 static_cast<net::Error>(certificate_error_code_),
603 REQUST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION,
602 true, 604 true,
603 "Tried to create SPDY stream for secure content over an " 605 "Tried to create SPDY stream for secure content over an "
604 "unauthenticated session."); 606 "unauthenticated session.");
605 return ERR_SPDY_PROTOCOL_ERROR; 607 return ERR_SPDY_PROTOCOL_ERROR;
606 } 608 }
607 609
608 const std::string& path = url.PathForRequest(); 610 const std::string& path = url.PathForRequest();
609 611
610 const SpdyStreamId stream_id = GetNewStreamId(); 612 const SpdyStreamId stream_id = GetNewStreamId();
611 613
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 // buffer (32KB). 871 // buffer (32KB).
870 // TODO(mbelshe): support arbitrarily large frames! 872 // TODO(mbelshe): support arbitrarily large frames!
871 873
872 read_pending_ = false; 874 read_pending_ = false;
873 875
874 if (bytes_read <= 0) { 876 if (bytes_read <= 0) {
875 // Session is tearing down. 877 // Session is tearing down.
876 net::Error error = static_cast<net::Error>(bytes_read); 878 net::Error error = static_cast<net::Error>(bytes_read);
877 if (bytes_read == 0) 879 if (bytes_read == 0)
878 error = ERR_CONNECTION_CLOSED; 880 error = ERR_CONNECTION_CLOSED;
879 CloseSessionOnError(error, true, "bytes_read is <= 0."); 881 CloseSessionOnError(error, READ_FAILED, true,
882 "bytes_read is <= 0.");
880 return; 883 return;
881 } 884 }
882 885
883 bytes_received_ += bytes_read; 886 bytes_received_ += bytes_read;
884 887
885 received_data_time_ = base::TimeTicks::Now(); 888 received_data_time_ = base::TimeTicks::Now();
886 889
887 // The SpdyFramer will use callbacks onto |this| as it parses frames. 890 // The SpdyFramer will use callbacks onto |this| as it parses frames.
888 // 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
889 // 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
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 950
948 // Write more data. We're already in a continuation, so we can 951 // Write more data. We're already in a continuation, so we can
949 // go ahead and write it immediately (without going back to the 952 // go ahead and write it immediately (without going back to the
950 // message loop). 953 // message loop).
951 WriteSocketLater(); 954 WriteSocketLater();
952 } else { 955 } else {
953 in_flight_write_.release(); 956 in_flight_write_.release();
954 957
955 // The stream is now errored. Close it down. 958 // The stream is now errored. Close it down.
956 CloseSessionOnError( 959 CloseSessionOnError(
957 static_cast<net::Error>(result), true, "The stream has errored."); 960 static_cast<net::Error>(result), WRITE_FAILED, true,
961 "The stream has errored.");
958 } 962 }
959 } 963 }
960 964
961 net::Error SpdySession::ReadSocket() { 965 net::Error SpdySession::ReadSocket() {
962 if (read_pending_) 966 if (read_pending_)
963 return OK; 967 return OK;
964 968
965 if (state_ == CLOSED) { 969 if (state_ == CLOSED) {
966 NOTREACHED(); 970 NOTREACHED();
967 return ERR_UNEXPECTED; 971 return ERR_UNEXPECTED;
968 } 972 }
969 973
970 CHECK(connection_.get()); 974 CHECK(connection_.get());
971 CHECK(connection_->socket()); 975 CHECK(connection_->socket());
972 int bytes_read = connection_->socket()->Read( 976 int bytes_read = connection_->socket()->Read(
973 read_buffer_.get(), 977 read_buffer_.get(),
974 kReadBufferSize, 978 kReadBufferSize,
975 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this))); 979 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this)));
976 switch (bytes_read) { 980 switch (bytes_read) {
977 case 0: 981 case 0:
978 // Socket is closed! 982 // Socket is closed!
979 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0."); 983 CloseSessionOnError(ERR_CONNECTION_CLOSED, READ_FAILED, true,
984 "bytes_read is 0.");
980 return ERR_CONNECTION_CLOSED; 985 return ERR_CONNECTION_CLOSED;
981 case net::ERR_IO_PENDING: 986 case net::ERR_IO_PENDING:
982 // Waiting for data. Nothing to do now. 987 // Waiting for data. Nothing to do now.
983 read_pending_ = true; 988 read_pending_ = true;
984 return ERR_IO_PENDING; 989 return ERR_IO_PENDING;
985 default: 990 default:
986 // Data was read, process it. 991 // Data was read, process it.
987 // Schedule the work through the message loop to avoid recursive 992 // Schedule the work through the message loop to avoid recursive
988 // callbacks. 993 // callbacks.
989 read_pending_ = true; 994 read_pending_ = true;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 // which is now. At this time, we don't compress our data frames. 1041 // which is now. At this time, we don't compress our data frames.
1037 SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false); 1042 SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false);
1038 size_t size; 1043 size_t size;
1039 if (buffered_spdy_framer_->IsCompressible(uncompressed_frame)) { 1044 if (buffered_spdy_framer_->IsCompressible(uncompressed_frame)) {
1040 DCHECK(uncompressed_frame.is_control_frame()); 1045 DCHECK(uncompressed_frame.is_control_frame());
1041 scoped_ptr<SpdyFrame> compressed_frame( 1046 scoped_ptr<SpdyFrame> compressed_frame(
1042 buffered_spdy_framer_->CompressControlFrame( 1047 buffered_spdy_framer_->CompressControlFrame(
1043 reinterpret_cast<const SpdyControlFrame&>(uncompressed_frame))); 1048 reinterpret_cast<const SpdyControlFrame&>(uncompressed_frame)));
1044 if (!compressed_frame.get()) { 1049 if (!compressed_frame.get()) {
1045 CloseSessionOnError( 1050 CloseSessionOnError(
1046 net::ERR_SPDY_PROTOCOL_ERROR, true, "SPDY Compression failure."); 1051 net::ERR_SPDY_PROTOCOL_ERROR, SPDY_COMPRESSION_FAILURE, true,
1052 "SPDY Compression failure.");
1047 return; 1053 return;
1048 } 1054 }
1049 1055
1050 size = compressed_frame->length() + SpdyFrame::kHeaderSize; 1056 size = compressed_frame->length() + SpdyFrame::kHeaderSize;
1051 1057
1052 DCHECK_GT(size, 0u); 1058 DCHECK_GT(size, 0u);
1053 1059
1054 // TODO(mbelshe): We have too much copying of data here. 1060 // TODO(mbelshe): We have too much copying of data here.
1055 IOBufferWithSize* buffer = new IOBufferWithSize(size); 1061 IOBufferWithSize* buffer = new IOBufferWithSize(size);
1056 memcpy(buffer->data(), compressed_frame->data(), size); 1062 memcpy(buffer->data(), compressed_frame->data(), size);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 SpdyStream* stream) { 1139 SpdyStream* stream) {
1134 int length = SpdyFrame::kHeaderSize + frame->length(); 1140 int length = SpdyFrame::kHeaderSize + frame->length();
1135 IOBuffer* buffer = new IOBuffer(length); 1141 IOBuffer* buffer = new IOBuffer(length);
1136 memcpy(buffer->data(), frame->data(), length); 1142 memcpy(buffer->data(), frame->data(), length);
1137 queue_.push(SpdyIOBuffer(buffer, length, priority, stream)); 1143 queue_.push(SpdyIOBuffer(buffer, length, priority, stream));
1138 1144
1139 WriteSocketLater(); 1145 WriteSocketLater();
1140 } 1146 }
1141 1147
1142 void SpdySession::CloseSessionOnError(net::Error err, 1148 void SpdySession::CloseSessionOnError(net::Error err,
1149 SpdySessionErrorDetails details,
1143 bool remove_from_pool, 1150 bool remove_from_pool,
1144 const std::string& description) { 1151 const std::string& description) {
1152 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails", details,
1153 NUM_SPDY_SESSION_ERROR_DETAILS);
1154 if (EndsWith(host_port_pair().host(), "google.com", false)) {
1155 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails_Google", details,
1156 NUM_SPDY_SESSION_ERROR_DETAILS);
1157 }
1145 // Closing all streams can have a side-effect of dropping the last reference 1158 // Closing all streams can have a side-effect of dropping the last reference
1146 // to |this|. Hold a reference through this function. 1159 // to |this|. Hold a reference through this function.
1147 scoped_refptr<SpdySession> self(this); 1160 scoped_refptr<SpdySession> self(this);
1148 1161
1149 DCHECK_LT(err, OK); 1162 DCHECK_LT(err, OK);
1150 net_log_.AddEvent( 1163 net_log_.AddEvent(
1151 NetLog::TYPE_SPDY_SESSION_CLOSE, 1164 NetLog::TYPE_SPDY_SESSION_CLOSE,
1152 make_scoped_refptr( 1165 make_scoped_refptr(
1153 new NetLogSpdySessionCloseParameter(err, description))); 1166 new NetLogSpdySessionCloseParameter(err, description)));
1154 1167
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 return NULL; 1328 return NULL;
1316 return GetSSLClientSocket()->GetServerBoundCertService(); 1329 return GetSSLClientSocket()->GetServerBoundCertService();
1317 } 1330 }
1318 1331
1319 SSLClientCertType SpdySession::GetDomainBoundCertType() const { 1332 SSLClientCertType SpdySession::GetDomainBoundCertType() const {
1320 if (!is_secure_) 1333 if (!is_secure_)
1321 return CLIENT_CERT_INVALID_TYPE; 1334 return CLIENT_CERT_INVALID_TYPE;
1322 return GetSSLClientSocket()->domain_bound_cert_type(); 1335 return GetSSLClientSocket()->domain_bound_cert_type();
1323 } 1336 }
1324 1337
1325 void SpdySession::OnError(int error_code) { 1338 void SpdySession::OnError(SpdyFramer::SpdyError error_code) {
1326 std::string description = base::StringPrintf( 1339 std::string description = base::StringPrintf(
1327 "SPDY_ERROR error_code: %d.", error_code); 1340 "SPDY_ERROR error_code: %d.", error_code);
1328 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true, description); 1341 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR,
1342 static_cast<SpdySessionErrorDetails>(error_code),
1343 true, description);
1329 } 1344 }
1330 1345
1331 void SpdySession::OnStreamError(SpdyStreamId stream_id, 1346 void SpdySession::OnStreamError(SpdyStreamId stream_id,
1332 const std::string& description) { 1347 const std::string& description) {
1333 if (IsStreamActive(stream_id)) 1348 if (IsStreamActive(stream_id))
1334 ResetStream(stream_id, PROTOCOL_ERROR, description); 1349 ResetStream(stream_id, PROTOCOL_ERROR, description);
1335 } 1350 }
1336 1351
1337 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, 1352 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
1338 const char* data, 1353 const char* data,
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 1629
1615 // Send response to a PING from server. 1630 // Send response to a PING from server.
1616 if (frame.unique_id() % 2 == 0) { 1631 if (frame.unique_id() % 2 == 0) {
1617 WritePingFrame(frame.unique_id()); 1632 WritePingFrame(frame.unique_id());
1618 return; 1633 return;
1619 } 1634 }
1620 1635
1621 --pings_in_flight_; 1636 --pings_in_flight_;
1622 if (pings_in_flight_ < 0) { 1637 if (pings_in_flight_ < 0) {
1623 CloseSessionOnError( 1638 CloseSessionOnError(
1624 net::ERR_SPDY_PROTOCOL_ERROR, true, "pings_in_flight_ is < 0."); 1639 net::ERR_SPDY_PROTOCOL_ERROR, UNEXPECTED_PING, true,
1640 "pings_in_flight_ is < 0.");
1625 return; 1641 return;
1626 } 1642 }
1627 1643
1628 if (pings_in_flight_ > 0) 1644 if (pings_in_flight_ > 0)
1629 return; 1645 return;
1630 1646
1631 // We will record RTT in histogram when there are no more client sent 1647 // We will record RTT in histogram when there are no more client sent
1632 // pings_in_flight_. 1648 // pings_in_flight_.
1633 RecordPingRTTHistogram(base::TimeTicks::Now() - last_ping_sent_time_); 1649 RecordPingRTTHistogram(base::TimeTicks::Now() - last_ping_sent_time_);
1634 1650
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 check_ping_status_pending_ = false; 1870 check_ping_status_pending_ = false;
1855 return; 1871 return;
1856 } 1872 }
1857 1873
1858 DCHECK(check_ping_status_pending_); 1874 DCHECK(check_ping_status_pending_);
1859 1875
1860 base::TimeTicks now = base::TimeTicks::Now(); 1876 base::TimeTicks now = base::TimeTicks::Now();
1861 base::TimeDelta delay = hung_interval_ - (now - received_data_time_); 1877 base::TimeDelta delay = hung_interval_ - (now - received_data_time_);
1862 1878
1863 if (delay.InMilliseconds() < 0 || received_data_time_ < last_check_time) { 1879 if (delay.InMilliseconds() < 0 || received_data_time_ < last_check_time) {
1864 CloseSessionOnError(net::ERR_SPDY_PING_FAILED, true, "Failed ping."); 1880 CloseSessionOnError(net::ERR_SPDY_PING_FAILED, PING_FAILED, true,
1881 "Failed ping.");
1865 // Track all failed PING messages in a separate bucket. 1882 // Track all failed PING messages in a separate bucket.
1866 const base::TimeDelta kFailedPing = 1883 const base::TimeDelta kFailedPing =
1867 base::TimeDelta::FromInternalValue(INT_MAX); 1884 base::TimeDelta::FromInternalValue(INT_MAX);
1868 RecordPingRTTHistogram(kFailedPing); 1885 RecordPingRTTHistogram(kFailedPing);
1869 return; 1886 return;
1870 } 1887 }
1871 1888
1872 // Check the status of connection after a delay. 1889 // Check the status of connection after a delay.
1873 MessageLoop::current()->PostDelayedTask( 1890 MessageLoop::current()->PostDelayedTask(
1874 FROM_HERE, 1891 FROM_HERE,
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1968 SSLClientSocket* SpdySession::GetSSLClientSocket() const { 1985 SSLClientSocket* SpdySession::GetSSLClientSocket() const {
1969 if (!is_secure_) 1986 if (!is_secure_)
1970 return NULL; 1987 return NULL;
1971 SSLClientSocket* ssl_socket = 1988 SSLClientSocket* ssl_socket =
1972 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 1989 reinterpret_cast<SSLClientSocket*>(connection_->socket());
1973 DCHECK(ssl_socket); 1990 DCHECK(ssl_socket);
1974 return ssl_socket; 1991 return ssl_socket;
1975 } 1992 }
1976 1993
1977 } // namespace net 1994 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698