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

Unified Diff: net/http/http_stream_parser.cc

Issue 1074263003: Add histograms for a number of hacks in the HTTP header parsing logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fetcher4
Patch Set: Fix search Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: net/http/http_stream_parser.cc
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index fc04a7d9a50ed444b94c3636c48343fb0e73be65..5aeafa154727ac326814bfb0bd4b15bd1c50f95c 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_util.h"
#include "base/values.h"
@@ -25,6 +26,20 @@ namespace net {
namespace {
+enum HttpHeaderParserEvent {
+ HEADER_PARSER_INVOKED = 0,
+ HEADER_HTTP_09_RESPONSE = 1,
+ HEADER_ALLOWED_TRUNCATED_HEADERS = 2,
+ HEADER_SKIPPED_WS_PREFIX = 3,
+ HEADER_SKIPPED_NON_WS_PREFIX = 4,
+ NUM_HEADER_EVENTS
+};
+
+void RecordHeaderParserEvent(HttpHeaderParserEvent header_event) {
+ UMA_HISTOGRAM_ENUMERATION("Net.HttpHeaderParserEvent", header_event,
+ NUM_HEADER_EVENTS);
+}
+
const uint64 kMaxMergedHeaderAndBodySize = 1400;
const size_t kRequestBodyBufferSize = 1 << 14; // 16KB
@@ -828,13 +843,16 @@ int HttpStreamParser::HandleReadHeaderResult(int result) {
// Parse things as well as we can and let the caller decide what to do.
int end_offset;
if (response_header_start_offset_ >= 0) {
+ // The response looks to be a truncated set of HTTP headers.
io_state_ = STATE_READ_BODY_COMPLETE;
end_offset = read_buf_->offset();
+ RecordHeaderParserEvent(HEADER_ALLOWED_TRUNCATED_HEADERS);
} else {
- // Now waiting for the body to be read.
+ // The response is apparently using HTTP/0.9. Treat the entire response
+ // the body.
end_offset = 0;
}
- int rv = DoParseResponseHeaders(end_offset);
+ int rv = ParseResponseHeaders(end_offset);
if (rv < 0)
return rv;
return result;
@@ -844,7 +862,7 @@ int HttpStreamParser::HandleReadHeaderResult(int result) {
DCHECK_LE(read_buf_->offset(), read_buf_->capacity());
DCHECK_GE(result, 0);
- int end_of_header_offset = ParseResponseHeaders();
+ int end_of_header_offset = FindAndParseResponseHeaders();
// Note: -1 is special, it indicates we haven't found the end of headers.
// Anything less than -1 is a net::Error, so we bail out.
@@ -895,7 +913,7 @@ int HttpStreamParser::HandleReadHeaderResult(int result) {
return result;
}
-int HttpStreamParser::ParseResponseHeaders() {
+int HttpStreamParser::FindAndParseResponseHeaders() {
int end_offset = -1;
DCHECK_EQ(0, read_buf_unused_offset_);
@@ -918,16 +936,33 @@ int HttpStreamParser::ParseResponseHeaders() {
if (end_offset == -1)
return -1;
- int rv = DoParseResponseHeaders(end_offset);
+ int rv = ParseResponseHeaders(end_offset);
if (rv < 0)
return rv;
return end_offset;
}
-int HttpStreamParser::DoParseResponseHeaders(int end_offset) {
+int HttpStreamParser::ParseResponseHeaders(int end_offset) {
scoped_refptr<HttpResponseHeaders> headers;
DCHECK_EQ(0, read_buf_unused_offset_);
+ RecordHeaderParserEvent(HEADER_PARSER_INVOKED);
+
+ if (response_header_start_offset_ > 0) {
+ bool has_non_whitespace_in_prefix = false;
+ for (int i = 0; i < response_header_start_offset_; ++i) {
+ if (!strchr(" \t\r\n", read_buf_->StartOfBuffer()[i])) {
+ has_non_whitespace_in_prefix = true;
+ break;
+ }
+ }
+ if (has_non_whitespace_in_prefix) {
+ RecordHeaderParserEvent(HEADER_SKIPPED_NON_WS_PREFIX);
+ } else {
+ RecordHeaderParserEvent(HEADER_SKIPPED_WS_PREFIX);
+ }
+ }
+
if (response_header_start_offset_ >= 0) {
received_bytes_ += end_offset;
headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
@@ -935,6 +970,7 @@ int HttpStreamParser::DoParseResponseHeaders(int end_offset) {
} else {
// Enough data was read -- there is no status line.
headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
+ RecordHeaderParserEvent(HEADER_HTTP_09_RESPONSE);
}
// Check for multiple Content-Length headers with no Transfer-Encoding header.

Powered by Google App Engine
This is Rietveld 408576698