| 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.
|
|
|