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

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: Correctly handle SpdyStatusCodes 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
« no previous file with comments | « net/spdy/spdy_session.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/compiler_specific.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/memory/linked_ptr.h" 12 #include "base/memory/linked_ptr.h"
12 #include "base/message_loop.h" 13 #include "base/message_loop.h"
13 #include "base/metrics/field_trial.h" 14 #include "base/metrics/field_trial.h"
14 #include "base/metrics/stats_counters.h" 15 #include "base/metrics/stats_counters.h"
15 #include "base/stl_util.h" 16 #include "base/stl_util.h"
16 #include "base/string_number_conversions.h" 17 #include "base/string_number_conversions.h"
17 #include "base/string_util.h" 18 #include "base/string_util.h"
18 #include "base/stringprintf.h" 19 #include "base/stringprintf.h"
19 #include "base/time.h" 20 #include "base/time.h"
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 scoped_refptr<SpdyStream>* stream, 480 scoped_refptr<SpdyStream>* stream,
480 const BoundNetLog& stream_net_log) { 481 const BoundNetLog& stream_net_log) {
481 CHECK_NE(state_, CLOSED); 482 CHECK_NE(state_, CLOSED);
482 483
483 *stream = NULL; 484 *stream = NULL;
484 485
485 // Don't allow access to secure push streams over an unauthenticated, but 486 // Don't allow access to secure push streams over an unauthenticated, but
486 // encrypted SSL socket. 487 // encrypted SSL socket.
487 if (is_secure_ && certificate_error_code_ != OK && 488 if (is_secure_ && certificate_error_code_ != OK &&
488 (url.SchemeIs("https") || url.SchemeIs("wss"))) { 489 (url.SchemeIs("https") || url.SchemeIs("wss"))) {
490 RecordProtocolErrorHistogram(
491 PROTOCOL_ERROR_REQUST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
489 CloseSessionOnError( 492 CloseSessionOnError(
490 static_cast<net::Error>(certificate_error_code_), 493 static_cast<net::Error>(certificate_error_code_),
491 true, 494 true,
492 "Tried to get SPDY stream for secure content over an unauthenticated " 495 "Tried to get SPDY stream for secure content over an unauthenticated "
493 "session."); 496 "session.");
494 return ERR_SPDY_PROTOCOL_ERROR; 497 return ERR_SPDY_PROTOCOL_ERROR;
495 } 498 }
496 499
497 *stream = GetActivePushStream(url.spec()); 500 *stream = GetActivePushStream(url.spec());
498 if (stream->get()) { 501 if (stream->get()) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 RequestPriority priority, 584 RequestPriority priority,
582 scoped_refptr<SpdyStream>* spdy_stream, 585 scoped_refptr<SpdyStream>* spdy_stream,
583 const BoundNetLog& stream_net_log) { 586 const BoundNetLog& stream_net_log) {
584 DCHECK_GE(priority, MINIMUM_PRIORITY); 587 DCHECK_GE(priority, MINIMUM_PRIORITY);
585 DCHECK_LT(priority, NUM_PRIORITIES); 588 DCHECK_LT(priority, NUM_PRIORITIES);
586 589
587 // Make sure that we don't try to send https/wss over an unauthenticated, but 590 // Make sure that we don't try to send https/wss over an unauthenticated, but
588 // encrypted SSL socket. 591 // encrypted SSL socket.
589 if (is_secure_ && certificate_error_code_ != OK && 592 if (is_secure_ && certificate_error_code_ != OK &&
590 (url.SchemeIs("https") || url.SchemeIs("wss"))) { 593 (url.SchemeIs("https") || url.SchemeIs("wss"))) {
594 RecordProtocolErrorHistogram(
595 PROTOCOL_ERROR_REQUST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
591 CloseSessionOnError( 596 CloseSessionOnError(
592 static_cast<net::Error>(certificate_error_code_), 597 static_cast<net::Error>(certificate_error_code_),
593 true, 598 true,
594 "Tried to create SPDY stream for secure content over an " 599 "Tried to create SPDY stream for secure content over an "
595 "unauthenticated session."); 600 "unauthenticated session.");
596 return ERR_SPDY_PROTOCOL_ERROR; 601 return ERR_SPDY_PROTOCOL_ERROR;
597 } 602 }
598 603
599 const std::string& path = url.PathForRequest(); 604 const std::string& path = url.PathForRequest();
600 605
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 scoped_ptr<SpdyRstStreamControlFrame> rst_frame( 831 scoped_ptr<SpdyRstStreamControlFrame> rst_frame(
827 buffered_spdy_framer_->CreateRstStream(stream_id, status)); 832 buffered_spdy_framer_->CreateRstStream(stream_id, status));
828 833
829 // Default to lowest priority unless we know otherwise. 834 // Default to lowest priority unless we know otherwise.
830 RequestPriority priority = net::IDLE; 835 RequestPriority priority = net::IDLE;
831 if(IsStreamActive(stream_id)) { 836 if(IsStreamActive(stream_id)) {
832 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 837 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
833 priority = stream->priority(); 838 priority = stream->priority();
834 } 839 }
835 QueueFrame(rst_frame.get(), priority, NULL); 840 QueueFrame(rst_frame.get(), priority, NULL);
841 RecordProtocolErrorHistogram(
842 static_cast<SpdyProtocolErrorDetails>(status + STATUS_CODE_INVALID));
836 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); 843 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR);
837 } 844 }
838 845
839 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { 846 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const {
840 return ContainsKey(active_streams_, stream_id); 847 return ContainsKey(active_streams_, stream_id);
841 } 848 }
842 849
843 LoadState SpdySession::GetLoadState() const { 850 LoadState SpdySession::GetLoadState() const {
844 // NOTE: The application only queries the LoadState via the 851 // NOTE: The application only queries the LoadState via the
845 // SpdyNetworkTransaction, and details are only needed when 852 // SpdyNetworkTransaction, and details are only needed when
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 // We've deferred compression until just before we write it to the socket, 1033 // We've deferred compression until just before we write it to the socket,
1027 // which is now. At this time, we don't compress our data frames. 1034 // which is now. At this time, we don't compress our data frames.
1028 SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false); 1035 SpdyFrame uncompressed_frame(next_buffer.buffer()->data(), false);
1029 size_t size; 1036 size_t size;
1030 if (buffered_spdy_framer_->IsCompressible(uncompressed_frame)) { 1037 if (buffered_spdy_framer_->IsCompressible(uncompressed_frame)) {
1031 DCHECK(uncompressed_frame.is_control_frame()); 1038 DCHECK(uncompressed_frame.is_control_frame());
1032 scoped_ptr<SpdyFrame> compressed_frame( 1039 scoped_ptr<SpdyFrame> compressed_frame(
1033 buffered_spdy_framer_->CompressControlFrame( 1040 buffered_spdy_framer_->CompressControlFrame(
1034 reinterpret_cast<const SpdyControlFrame&>(uncompressed_frame))); 1041 reinterpret_cast<const SpdyControlFrame&>(uncompressed_frame)));
1035 if (!compressed_frame.get()) { 1042 if (!compressed_frame.get()) {
1043 RecordProtocolErrorHistogram(
1044 PROTOCOL_ERROR_SPDY_COMPRESSION_FAILURE);
1036 CloseSessionOnError( 1045 CloseSessionOnError(
1037 net::ERR_SPDY_PROTOCOL_ERROR, true, "SPDY Compression failure."); 1046 net::ERR_SPDY_PROTOCOL_ERROR, true, "SPDY Compression failure.");
1038 return; 1047 return;
1039 } 1048 }
1040 1049
1041 size = compressed_frame->length() + SpdyFrame::kHeaderSize; 1050 size = compressed_frame->length() + SpdyFrame::kHeaderSize;
1042 1051
1043 DCHECK_GT(size, 0u); 1052 DCHECK_GT(size, 0u);
1044 1053
1045 // TODO(mbelshe): We have too much copying of data here. 1054 // TODO(mbelshe): We have too much copying of data here.
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 return GetSSLClientSocket()->GetServerBoundCertService(); 1316 return GetSSLClientSocket()->GetServerBoundCertService();
1308 } 1317 }
1309 1318
1310 SSLClientCertType SpdySession::GetDomainBoundCertType() const { 1319 SSLClientCertType SpdySession::GetDomainBoundCertType() const {
1311 if (!is_secure_) 1320 if (!is_secure_)
1312 return CLIENT_CERT_INVALID_TYPE; 1321 return CLIENT_CERT_INVALID_TYPE;
1313 return GetSSLClientSocket()->domain_bound_cert_type(); 1322 return GetSSLClientSocket()->domain_bound_cert_type();
1314 } 1323 }
1315 1324
1316 void SpdySession::OnError(SpdyFramer::SpdyError error_code) { 1325 void SpdySession::OnError(SpdyFramer::SpdyError error_code) {
1326 RecordProtocolErrorHistogram(
1327 static_cast<SpdyProtocolErrorDetails>(error_code));
1317 std::string description = base::StringPrintf( 1328 std::string description = base::StringPrintf(
1318 "SPDY_ERROR error_code: %d.", error_code); 1329 "SPDY_ERROR error_code: %d.", error_code);
1319 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true, description); 1330 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true, description);
1320 } 1331 }
1321 1332
1322 void SpdySession::OnStreamError(SpdyStreamId stream_id, 1333 void SpdySession::OnStreamError(SpdyStreamId stream_id,
1323 const std::string& description) { 1334 const std::string& description) {
1324 if (IsStreamActive(stream_id)) 1335 if (IsStreamActive(stream_id))
1325 ResetStream(stream_id, PROTOCOL_ERROR, description); 1336 ResetStream(stream_id, PROTOCOL_ERROR, description);
1326 } 1337 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 return; 1512 return;
1502 } 1513 }
1503 1514
1504 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 1515 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
1505 CHECK_EQ(stream->stream_id(), stream_id); 1516 CHECK_EQ(stream->stream_id(), stream_id);
1506 CHECK(!stream->cancelled()); 1517 CHECK(!stream->cancelled());
1507 1518
1508 if (stream->response_received()) { 1519 if (stream->response_received()) {
1509 stream->LogStreamError(ERR_SYN_REPLY_NOT_RECEIVED, 1520 stream->LogStreamError(ERR_SYN_REPLY_NOT_RECEIVED,
1510 "Received duplicate SYN_REPLY for stream."); 1521 "Received duplicate SYN_REPLY for stream.");
1522 RecordProtocolErrorHistogram(PROTOCOL_ERROR_SYN_REPLY_NOT_RECEIVED);
1511 CloseStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); 1523 CloseStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR);
1512 return; 1524 return;
1513 } 1525 }
1514 stream->set_response_received(); 1526 stream->set_response_received();
1515 1527
1516 Respond(*headers, stream); 1528 Respond(*headers, stream);
1517 } 1529 }
1518 1530
1519 void SpdySession::OnHeaders(const SpdyHeadersControlFrame& frame, 1531 void SpdySession::OnHeaders(const SpdyHeadersControlFrame& frame,
1520 const linked_ptr<SpdyHeaderBlock>& headers) { 1532 const linked_ptr<SpdyHeaderBlock>& headers) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 } 1575 }
1564 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; 1576 scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
1565 CHECK_EQ(stream->stream_id(), stream_id); 1577 CHECK_EQ(stream->stream_id(), stream_id);
1566 CHECK(!stream->cancelled()); 1578 CHECK(!stream->cancelled());
1567 1579
1568 if (frame.status() == 0) { 1580 if (frame.status() == 0) {
1569 stream->OnDataReceived(NULL, 0); 1581 stream->OnDataReceived(NULL, 0);
1570 } else if (frame.status() == REFUSED_STREAM) { 1582 } else if (frame.status() == REFUSED_STREAM) {
1571 DeleteStream(stream_id, ERR_SPDY_SERVER_REFUSED_STREAM); 1583 DeleteStream(stream_id, ERR_SPDY_SERVER_REFUSED_STREAM);
1572 } else { 1584 } else {
1585 RecordProtocolErrorHistogram(
1586 PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM);
1573 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, 1587 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR,
1574 base::StringPrintf("SPDY stream closed: %d", 1588 base::StringPrintf("SPDY stream closed: %d",
1575 frame.status())); 1589 frame.status()));
1576 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. 1590 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical.
1577 // For now, it doesn't matter much - it is a protocol error. 1591 // For now, it doesn't matter much - it is a protocol error.
1578 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); 1592 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR);
1579 } 1593 }
1580 } 1594 }
1581 1595
1582 void SpdySession::OnGoAway(const SpdyGoAwayControlFrame& frame) { 1596 void SpdySession::OnGoAway(const SpdyGoAwayControlFrame& frame) {
(...skipping 21 matching lines...) Expand all
1604 new NetLogSpdyPingParameter(frame.unique_id(), "received"))); 1618 new NetLogSpdyPingParameter(frame.unique_id(), "received")));
1605 1619
1606 // Send response to a PING from server. 1620 // Send response to a PING from server.
1607 if (frame.unique_id() % 2 == 0) { 1621 if (frame.unique_id() % 2 == 0) {
1608 WritePingFrame(frame.unique_id()); 1622 WritePingFrame(frame.unique_id());
1609 return; 1623 return;
1610 } 1624 }
1611 1625
1612 --pings_in_flight_; 1626 --pings_in_flight_;
1613 if (pings_in_flight_ < 0) { 1627 if (pings_in_flight_ < 0) {
1628 RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING);
1614 CloseSessionOnError( 1629 CloseSessionOnError(
1615 net::ERR_SPDY_PROTOCOL_ERROR, true, "pings_in_flight_ is < 0."); 1630 net::ERR_SPDY_PROTOCOL_ERROR, true, "pings_in_flight_ is < 0.");
1616 return; 1631 return;
1617 } 1632 }
1618 1633
1619 if (pings_in_flight_ > 0) 1634 if (pings_in_flight_ > 0)
1620 return; 1635 return;
1621 1636
1622 // We will record RTT in histogram when there are no more client sent 1637 // We will record RTT in histogram when there are no more client sent
1623 // pings_in_flight_. 1638 // pings_in_flight_.
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 FROM_HERE, 1880 FROM_HERE,
1866 base::Bind(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(), 1881 base::Bind(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(),
1867 now), 1882 now),
1868 delay); 1883 delay);
1869 } 1884 }
1870 1885
1871 void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) { 1886 void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) {
1872 UMA_HISTOGRAM_TIMES("Net.SpdyPing.RTT", duration); 1887 UMA_HISTOGRAM_TIMES("Net.SpdyPing.RTT", duration);
1873 } 1888 }
1874 1889
1890 void SpdySession::RecordProtocolErrorHistogram(
1891 SpdyProtocolErrorDetails details) {
1892 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails", details,
1893 NUM_SPDY_PROTOCOL_ERROR_DETAILS);
1894 if (EndsWith(host_port_pair().host(), "google.com", false)) {
1895 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails_Google", details,
1896 NUM_SPDY_PROTOCOL_ERROR_DETAILS);
1897 }
1898 }
1899
1875 void SpdySession::RecordHistograms() { 1900 void SpdySession::RecordHistograms() {
1876 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession", 1901 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession",
1877 streams_initiated_count_, 1902 streams_initiated_count_,
1878 0, 300, 50); 1903 0, 300, 50);
1879 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession", 1904 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession",
1880 streams_pushed_count_, 1905 streams_pushed_count_,
1881 0, 300, 50); 1906 0, 300, 50);
1882 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession", 1907 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession",
1883 streams_pushed_and_claimed_count_, 1908 streams_pushed_and_claimed_count_,
1884 0, 300, 50); 1909 0, 300, 50);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 SSLClientSocket* SpdySession::GetSSLClientSocket() const { 1984 SSLClientSocket* SpdySession::GetSSLClientSocket() const {
1960 if (!is_secure_) 1985 if (!is_secure_)
1961 return NULL; 1986 return NULL;
1962 SSLClientSocket* ssl_socket = 1987 SSLClientSocket* ssl_socket =
1963 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 1988 reinterpret_cast<SSLClientSocket*>(connection_->socket());
1964 DCHECK(ssl_socket); 1989 DCHECK(ssl_socket);
1965 return ssl_socket; 1990 return ssl_socket;
1966 } 1991 }
1967 1992
1968 } // namespace net 1993 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698