| Index: net/tools/balsa/balsa_frame.cc
|
| diff --git a/net/tools/balsa/balsa_frame.cc b/net/tools/balsa/balsa_frame.cc
|
| index 96e91935597b734b39088d26bd10a8f6614dba25..da04b14a56d475b7fe9932aa6223b72a119409bf 100644
|
| --- a/net/tools/balsa/balsa_frame.cc
|
| +++ b/net/tools/balsa/balsa_frame.cc
|
| @@ -56,7 +56,8 @@ BalsaFrame::BalsaFrame()
|
| headers_(NULL) {
|
| }
|
|
|
| -BalsaFrame::~BalsaFrame() {}
|
| +BalsaFrame::~BalsaFrame() {
|
| +}
|
|
|
| void BalsaFrame::Reset() {
|
| last_char_was_slash_r_ = false;
|
| @@ -266,16 +267,16 @@ bool ParseHTTPFirstLine(const char* begin,
|
|
|
| // whitespace_1_idx_
|
| headers->whitespace_1_idx_ = current - begin;
|
| - // This loop is commented out as it is never used in current code. This is
|
| - // true only because we don't begin parsing the headers at all until we've
|
| - // encountered a non whitespace character at the beginning of the stream, at
|
| - // which point we begin our demarcation of header-start. If we did -not- do
|
| - // this (for instance, only looked for [\r\n] instead of (< ' ')), this loop
|
| - // would be necessary for the proper functioning of this parsing.
|
| - // This is left here as this function may (in the future) be refactored out
|
| - // of the BalsaFrame class so that it may be shared between code in
|
| - // BalsaFrame and BalsaHeaders (where it would be used in some variant of the
|
| - // set_first_line() function (at which point it would be necessary).
|
| +// This loop is commented out as it is never used in current code. This is
|
| +// true only because we don't begin parsing the headers at all until we've
|
| +// encountered a non whitespace character at the beginning of the stream, at
|
| +// which point we begin our demarcation of header-start. If we did -not- do
|
| +// this (for instance, only looked for [\r\n] instead of (< ' ')), this loop
|
| +// would be necessary for the proper functioning of this parsing.
|
| +// This is left here as this function may (in the future) be refactored out
|
| +// of the BalsaFrame class so that it may be shared between code in
|
| +// BalsaFrame and BalsaHeaders (where it would be used in some variant of the
|
| +// set_first_line() function (at which point it would be necessary).
|
| #if 0
|
| while (*current <= ' ') {
|
| ++current;
|
| @@ -297,10 +298,9 @@ bool ParseHTTPFirstLine(const char* begin,
|
| headers->whitespace_4_idx_ = current - begin;
|
| // FAILED_TO_FIND_WS_AFTER_REQUEST_METHOD for request
|
| // FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION for response
|
| - *error_code =
|
| - static_cast<BalsaFrameEnums::ErrorCode>(
|
| - BalsaFrameEnums::FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION +
|
| - is_request);
|
| + *error_code = static_cast<BalsaFrameEnums::ErrorCode>(
|
| + BalsaFrameEnums::FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION +
|
| + is_request);
|
| if (!is_request) { // FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION
|
| return false;
|
| }
|
| @@ -324,10 +324,9 @@ bool ParseHTTPFirstLine(const char* begin,
|
| headers->whitespace_4_idx_ = current - begin;
|
| // FAILED_TO_FIND_START_OF_REQUEST_REQUEST_URI for request
|
| // FAILED_TO_FIND_START_OF_RESPONSE_STATUSCODE for response
|
| - *error_code =
|
| - static_cast<BalsaFrameEnums::ErrorCode>(
|
| - BalsaFrameEnums::FAILED_TO_FIND_WS_AFTER_RESPONSE_STATUSCODE
|
| - + is_request);
|
| + *error_code = static_cast<BalsaFrameEnums::ErrorCode>(
|
| + BalsaFrameEnums::FAILED_TO_FIND_WS_AFTER_RESPONSE_STATUSCODE +
|
| + is_request);
|
| goto output_exhausted;
|
| }
|
| } while (*current > ' ');
|
| @@ -342,7 +341,7 @@ bool ParseHTTPFirstLine(const char* begin,
|
| headers->non_whitespace_3_idx_ = current - begin;
|
| headers->whitespace_4_idx_ = end - begin;
|
|
|
| - output_exhausted:
|
| +output_exhausted:
|
| // Note that we don't fail the parse immediately when parsing of the
|
| // firstline fails. Depending on the protocol type, we may want to accept
|
| // a firstline with only one or two elements, e.g., for HTTP/0.9:
|
| @@ -369,7 +368,7 @@ bool ParseHTTPFirstLine(const char* begin,
|
| headers->parsed_response_code_ = 0;
|
| {
|
| const char* parsed_response_code_current =
|
| - begin + headers->non_whitespace_2_idx_;
|
| + begin + headers->non_whitespace_2_idx_;
|
| const char* parsed_response_code_end = begin + headers->whitespace_3_idx_;
|
| const size_t kMaxDiv10 = std::numeric_limits<size_t>::max() / 10;
|
|
|
| @@ -467,20 +466,22 @@ void BalsaFrame::CleanUpKeyValueWhitespace(
|
| DCHECK_LT(colon_loc, line_end);
|
| DCHECK_EQ(':', *colon_loc);
|
| DCHECK_EQ(':', *current);
|
| - DCHECK_GE(' ', *line_end)
|
| - << "\"" << std::string(line_begin, line_end) << "\"";
|
| + DCHECK_GE(' ', *line_end) << "\"" << std::string(line_begin, line_end)
|
| + << "\"";
|
|
|
| // TODO(fenix): Investigate whether or not the bounds tests in the
|
| // while loops here are redundant, and if so, remove them.
|
| --current;
|
| - while (current > line_begin && *current <= ' ') --current;
|
| + while (current > line_begin && *current <= ' ')
|
| + --current;
|
| current += (current != colon_loc);
|
| current_header_line->key_end_idx = current - stream_begin;
|
|
|
| current = colon_loc;
|
| DCHECK_EQ(':', *current);
|
| ++current;
|
| - while (current < line_end && *current <= ' ') ++current;
|
| + while (current < line_end && *current <= ' ')
|
| + ++current;
|
| current_header_line->value_begin_idx = current - stream_begin;
|
|
|
| DCHECK_GE(current_header_line->key_end_idx,
|
| @@ -497,8 +498,8 @@ inline void BalsaFrame::FindColonsAndParseIntoKeyValue() {
|
| // The last line is always just a newline (and is uninteresting).
|
| const Lines::size_type lines_size_m1 = lines_.size() - 1;
|
| #if __SSE2__
|
| - const __v16qi colons = { ':', ':', ':', ':', ':', ':', ':', ':',
|
| - ':', ':', ':', ':', ':', ':', ':', ':'};
|
| + const __v16qi colons = {':', ':', ':', ':', ':', ':', ':', ':',
|
| + ':', ':', ':', ':', ':', ':', ':', ':'};
|
| const char* header_lines_end_m16 = headers_->OriginalHeaderStreamEnd() - 16;
|
| #endif // __SSE2__
|
| const char* current = stream_begin + lines_[1].first;
|
| @@ -534,8 +535,8 @@ inline void BalsaFrame::FindColonsAndParseIntoKeyValue() {
|
| //
|
| // We're guaranteed to have *line_end > ' ' while line_end >= line_begin.
|
| --line_end;
|
| - DCHECK_EQ('\n', *line_end)
|
| - << "\"" << std::string(line_begin, line_end) << "\"";
|
| + DCHECK_EQ('\n', *line_end) << "\"" << std::string(line_begin, line_end)
|
| + << "\"";
|
| while (*line_end <= ' ' && line_end > line_begin) {
|
| --line_end;
|
| }
|
| @@ -568,9 +569,9 @@ inline void BalsaFrame::FindColonsAndParseIntoKeyValue() {
|
| #if __SSE2__
|
| while (current < header_lines_end_m16) {
|
| __m128i header_bytes =
|
| - _mm_loadu_si128(reinterpret_cast<const __m128i *>(current));
|
| + _mm_loadu_si128(reinterpret_cast<const __m128i*>(current));
|
| __m128i colon_cmp =
|
| - _mm_cmpeq_epi8(header_bytes, reinterpret_cast<__m128i>(colons));
|
| + _mm_cmpeq_epi8(header_bytes, reinterpret_cast<__m128i>(colons));
|
| int colon_msk = _mm_movemask_epi8(colon_cmp);
|
| if (colon_msk == 0) {
|
| current += 16;
|
| @@ -598,7 +599,7 @@ inline void BalsaFrame::FindColonsAndParseIntoKeyValue() {
|
| last_error_ = BalsaFrameEnums::HEADER_MISSING_COLON;
|
| visitor_->HandleHeaderWarning(this);
|
| continue;
|
| - found_colon:
|
| + found_colon:
|
| DCHECK_EQ(*current, ':');
|
| DCHECK_LE(current - stream_begin, line_end - stream_begin);
|
| DCHECK_LE(stream_begin - stream_begin, current - stream_begin);
|
| @@ -609,11 +610,8 @@ inline void BalsaFrame::FindColonsAndParseIntoKeyValue() {
|
| if (current < line_end) {
|
| ++current_header_line.key_end_idx;
|
|
|
| - CleanUpKeyValueWhitespace(stream_begin,
|
| - line_begin,
|
| - current,
|
| - line_end,
|
| - ¤t_header_line);
|
| + CleanUpKeyValueWhitespace(
|
| + stream_begin, line_begin, current, line_end, ¤t_header_line);
|
| }
|
| }
|
| }
|
| @@ -628,9 +626,9 @@ void BalsaFrame::ProcessContentLengthLine(
|
| const char* value_begin = (stream_begin + header_line.value_begin_idx);
|
|
|
| if (value_begin >= line_end) {
|
| - // There is no non-whitespace value data.
|
| +// There is no non-whitespace value data.
|
| #if DEBUGFRAMER
|
| - LOG(INFO) << "invalid content-length -- no non-whitespace value data";
|
| + LOG(INFO) << "invalid content-length -- no non-whitespace value data";
|
| #endif
|
| *status = BalsaHeadersEnums::INVALID_CONTENT_LENGTH;
|
| return;
|
| @@ -673,11 +671,9 @@ void BalsaFrame::ProcessTransferEncodingLine(HeaderLines::size_type line_idx) {
|
| const char* value_begin = stream_begin + header_line.value_begin_idx;
|
| size_t value_length = line_end - value_begin;
|
|
|
| - if ((value_length == 7) &&
|
| - !strncasecmp(value_begin, "chunked", 7)) {
|
| + if ((value_length == 7) && !strncasecmp(value_begin, "chunked", 7)) {
|
| headers_->transfer_encoding_is_chunked_ = true;
|
| - } else if ((value_length == 8) &&
|
| - !strncasecmp(value_begin, "identity", 8)) {
|
| + } else if ((value_length == 8) && !strncasecmp(value_begin, "identity", 8)) {
|
| headers_->transfer_encoding_is_chunked_ = false;
|
| } else {
|
| last_error_ = BalsaFrameEnums::UNKNOWN_TRANSFER_ENCODING;
|
| @@ -688,8 +684,10 @@ void BalsaFrame::ProcessTransferEncodingLine(HeaderLines::size_type line_idx) {
|
| }
|
|
|
| namespace {
|
| -bool SplitStringPiece(base::StringPiece original, char delim,
|
| - base::StringPiece* before, base::StringPiece* after) {
|
| +bool SplitStringPiece(base::StringPiece original,
|
| + char delim,
|
| + base::StringPiece* before,
|
| + base::StringPiece* after) {
|
| const char* p = original.data();
|
| const char* end = p + original.size();
|
|
|
| @@ -747,7 +745,8 @@ void ProcessChunkExtensionsManual(base::StringPiece all_extensions,
|
|
|
| } // anonymous namespace
|
|
|
| -void BalsaFrame::ProcessChunkExtensions(const char* input, size_t size,
|
| +void BalsaFrame::ProcessChunkExtensions(const char* input,
|
| + size_t size,
|
| BalsaHeaders* extensions) {
|
| ProcessChunkExtensionsManual(base::StringPiece(input, size), extensions);
|
| }
|
| @@ -775,13 +774,13 @@ void BalsaFrame::ProcessHeaderLines() {
|
| FindColonsAndParseIntoKeyValue();
|
| // At this point, we've parsed all of the headers. Time to look for those
|
| // headers which we require for framing.
|
| - const HeaderLines::size_type
|
| - header_lines_size = headers_->header_lines_.size();
|
| + const HeaderLines::size_type header_lines_size =
|
| + headers_->header_lines_.size();
|
| for (HeaderLines::size_type i = 0; i < header_lines_size; ++i) {
|
| const HeaderLineDescription& current_header_line =
|
| - headers_->header_lines_[i];
|
| + headers_->header_lines_[i];
|
| const char* key_begin =
|
| - (stream_begin + current_header_line.first_char_idx);
|
| + (stream_begin + current_header_line.first_char_idx);
|
| const char* key_end = (stream_begin + current_header_line.key_end_idx);
|
| const size_t key_len = key_end - key_begin;
|
| const char c = *key_begin;
|
| @@ -795,12 +794,11 @@ void BalsaFrame::ProcessHeaderLines() {
|
| // that the message is framed, and so the framer is required to search
|
| // for them.
|
|
|
| -
|
| if (c == 'c' || c == 'C') {
|
| if ((key_len == kContentLengthSize) &&
|
| 0 == strncasecmp(key_begin, kContentLength, kContentLengthSize)) {
|
| BalsaHeadersEnums::ContentLengthStatus content_length_status =
|
| - BalsaHeadersEnums::NO_CONTENT_LENGTH;
|
| + BalsaHeadersEnums::NO_CONTENT_LENGTH;
|
| size_t length = 0;
|
| ProcessContentLengthLine(i, &content_length_status, &length);
|
| if (content_length_idx != 0) { // then we've already seen one!
|
| @@ -820,12 +818,11 @@ void BalsaFrame::ProcessHeaderLines() {
|
| headers_->content_length_ = length;
|
| content_length_remaining_ = length;
|
| }
|
| -
|
| }
|
| } else if (c == 't' || c == 'T') {
|
| if ((key_len == kTransferEncodingSize) &&
|
| - 0 == strncasecmp(key_begin, kTransferEncoding,
|
| - kTransferEncodingSize)) {
|
| + 0 == strncasecmp(
|
| + key_begin, kTransferEncoding, kTransferEncodingSize)) {
|
| if (transfer_encoding_idx != 0) {
|
| last_error_ = BalsaFrameEnums::MULTIPLE_TRANSFER_ENCODING_KEYS;
|
| parse_state_ = BalsaFrameEnums::PARSE_ERROR;
|
| @@ -857,9 +854,8 @@ void BalsaFrame::AssignParseStateAfterHeadersHaveBeenParsed() {
|
| // one of these response-codes. rfc2616 section 4.3
|
| parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
|
| if (is_request_ ||
|
| - !(request_was_head_ ||
|
| - (headers_->parsed_response_code_ >= 100 &&
|
| - headers_->parsed_response_code_ < 200) ||
|
| + !(request_was_head_ || (headers_->parsed_response_code_ >= 100 &&
|
| + headers_->parsed_response_code_ < 200) ||
|
| (headers_->parsed_response_code_ == 204) ||
|
| (headers_->parsed_response_code_ == 304))) {
|
| // Then we can have a body.
|
| @@ -894,12 +890,12 @@ void BalsaFrame::AssignParseStateAfterHeadersHaveBeenParsed() {
|
| last_error_ = BalsaFrameEnums::UNPARSABLE_CONTENT_LENGTH;
|
| visitor_->HandleHeaderError(this);
|
| break;
|
| - // We can have: no transfer-encoding, no content length, and no
|
| - // connection: close...
|
| - // Unfortunately, this case doesn't seem to be covered in the spec.
|
| - // We'll assume that the safest thing to do here is what the google
|
| - // binaries before 2008 already do, which is to assume that
|
| - // everything until the connection is closed is body.
|
| + // We can have: no transfer-encoding, no content length, and no
|
| + // connection: close...
|
| + // Unfortunately, this case doesn't seem to be covered in the spec.
|
| + // We'll assume that the safest thing to do here is what the google
|
| + // binaries before 2008 already do, which is to assume that
|
| + // everything until the connection is closed is body.
|
| case BalsaHeadersEnums::NO_CONTENT_LENGTH:
|
| if (is_request_) {
|
| base::StringPiece method = headers_->request_method();
|
| @@ -907,8 +903,7 @@ void BalsaFrame::AssignParseStateAfterHeadersHaveBeenParsed() {
|
| // do not we consider it an error.
|
| if ((method.size() == 4 &&
|
| strncmp(method.data(), "POST", 4) == 0) ||
|
| - (method.size() == 3 &&
|
| - strncmp(method.data(), "PUT", 3) == 0)) {
|
| + (method.size() == 3 && strncmp(method.data(), "PUT", 3) == 0)) {
|
| parse_state_ = BalsaFrameEnums::PARSE_ERROR;
|
| last_error_ =
|
| BalsaFrameEnums::REQUIRED_BODY_BUT_NO_CONTENT_LENGTH;
|
| @@ -922,13 +917,14 @@ void BalsaFrame::AssignParseStateAfterHeadersHaveBeenParsed() {
|
| visitor_->HandleHeaderWarning(this);
|
| }
|
| break;
|
| - // The COV_NF_... statements here provide hints to the apparatus
|
| - // which computes coverage reports/ratios that this code is never
|
| - // intended to be executed, and should technically be impossible.
|
| - // COV_NF_START
|
| + // The COV_NF_... statements here provide hints to the apparatus
|
| + // which computes coverage reports/ratios that this code is never
|
| + // intended to be executed, and should technically be impossible.
|
| + // COV_NF_START
|
| default:
|
| LOG(FATAL) << "Saw a content_length_status: "
|
| - << headers_->content_length_status_ << " which is unknown.";
|
| + << headers_->content_length_status_
|
| + << " which is unknown.";
|
| // COV_NF_END
|
| }
|
| }
|
| @@ -971,74 +967,73 @@ size_t BalsaFrame::ProcessHeaders(const char* message_start,
|
| } while (message_current < message_end);
|
| goto bottom; // this is necessary to skip 'last_char_was_slash_r' checks
|
| } else {
|
| - read_real_message:
|
| - // Note that SSE2 can be enabled on certain piii platforms.
|
| + read_real_message :
|
| +// Note that SSE2 can be enabled on certain piii platforms.
|
| #if __SSE2__
|
| - {
|
| - const char* const message_end_m16 = message_end - 16;
|
| - __v16qi newlines = { '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
|
| - '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n' };
|
| - while (message_current < message_end_m16) {
|
| - // What this does (using compiler intrinsics):
|
| - //
|
| - // Load 16 '\n's into an xmm register
|
| - // Load 16 bytes of currennt message into an xmm register
|
| - // Do byte-wise equals on those two xmm registers
|
| - // Take the first bit of each byte, and put that into the first
|
| - // 16 bits of a mask
|
| - // If the mask is zero, no '\n' found. increment by 16 and try again
|
| - // Else scan forward to find the first set bit.
|
| - // Increment current by the index of the first set bit
|
| - // (ffs returns index of first set bit + 1)
|
| - __m128i msg_bytes =
|
| - _mm_loadu_si128(const_cast<__m128i *>(
|
| - reinterpret_cast<const __m128i *>(message_current)));
|
| - __m128i newline_cmp =
|
| + {
|
| + const char* const message_end_m16 = message_end - 16;
|
| + __v16qi newlines = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
|
| + '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
|
| + while (message_current < message_end_m16) {
|
| + // What this does (using compiler intrinsics):
|
| + //
|
| + // Load 16 '\n's into an xmm register
|
| + // Load 16 bytes of currennt message into an xmm register
|
| + // Do byte-wise equals on those two xmm registers
|
| + // Take the first bit of each byte, and put that into the first
|
| + // 16 bits of a mask
|
| + // If the mask is zero, no '\n' found. increment by 16 and try again
|
| + // Else scan forward to find the first set bit.
|
| + // Increment current by the index of the first set bit
|
| + // (ffs returns index of first set bit + 1)
|
| + __m128i msg_bytes = _mm_loadu_si128(const_cast<__m128i*>(
|
| + reinterpret_cast<const __m128i*>(message_current)));
|
| + __m128i newline_cmp =
|
| _mm_cmpeq_epi8(msg_bytes, reinterpret_cast<__m128i>(newlines));
|
| - int newline_msk = _mm_movemask_epi8(newline_cmp);
|
| - if (newline_msk == 0) {
|
| - message_current += 16;
|
| - continue;
|
| - }
|
| - message_current += (ffs(newline_msk) - 1);
|
| - const size_t relative_idx = message_current - message_start;
|
| - const size_t message_current_idx = 1 + base_idx + relative_idx;
|
| - lines_.push_back(std::make_pair(last_slash_n_idx_,
|
| - message_current_idx));
|
| - if (lines_.size() == 1) {
|
| - headers_->WriteFromFramer(checkpoint,
|
| - 1 + message_current - checkpoint);
|
| - checkpoint = message_current + 1;
|
| - const char* begin = headers_->OriginalHeaderStreamBegin();
|
| + int newline_msk = _mm_movemask_epi8(newline_cmp);
|
| + if (newline_msk == 0) {
|
| + message_current += 16;
|
| + continue;
|
| + }
|
| + message_current += (ffs(newline_msk) - 1);
|
| + const size_t relative_idx = message_current - message_start;
|
| + const size_t message_current_idx = 1 + base_idx + relative_idx;
|
| + lines_.push_back(
|
| + std::make_pair(last_slash_n_idx_, message_current_idx));
|
| + if (lines_.size() == 1) {
|
| + headers_->WriteFromFramer(checkpoint,
|
| + 1 + message_current - checkpoint);
|
| + checkpoint = message_current + 1;
|
| + const char* begin = headers_->OriginalHeaderStreamBegin();
|
| #if DEBUGFRAMER
|
| LOG(INFO) << "First line " << std::string(begin, lines_[0].second);
|
| LOG(INFO) << "is_request_: " << is_request_;
|
| #endif
|
| - ProcessFirstLine(begin, begin + lines_[0].second);
|
| - if (parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ)
|
| - goto process_lines;
|
| - else if (parse_state_ == BalsaFrameEnums::PARSE_ERROR)
|
| - goto bottom;
|
| - }
|
| - const size_t chars_since_last_slash_n = (message_current_idx -
|
| - last_slash_n_idx_);
|
| - last_slash_n_idx_ = message_current_idx;
|
| - if (chars_since_last_slash_n > 2) {
|
| - // We have a slash-n, but the last slash n was
|
| - // more than 2 characters away from this. Thus, we know
|
| - // that this cannot be an end-of-header.
|
| - ++message_current;
|
| - continue;
|
| - }
|
| - if ((chars_since_last_slash_n == 1) ||
|
| - (((message_current > message_start) &&
|
| - (*(message_current - 1) == '\r')) ||
|
| - (last_char_was_slash_r_))) {
|
| + ProcessFirstLine(begin, begin + lines_[0].second);
|
| + if (parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ)
|
| goto process_lines;
|
| - }
|
| + else if (parse_state_ == BalsaFrameEnums::PARSE_ERROR)
|
| + goto bottom;
|
| + }
|
| + const size_t chars_since_last_slash_n =
|
| + (message_current_idx - last_slash_n_idx_);
|
| + last_slash_n_idx_ = message_current_idx;
|
| + if (chars_since_last_slash_n > 2) {
|
| + // We have a slash-n, but the last slash n was
|
| + // more than 2 characters away from this. Thus, we know
|
| + // that this cannot be an end-of-header.
|
| ++message_current;
|
| + continue;
|
| + }
|
| + if ((chars_since_last_slash_n == 1) ||
|
| + (((message_current > message_start) &&
|
| + (*(message_current - 1) == '\r')) ||
|
| + (last_char_was_slash_r_))) {
|
| + goto process_lines;
|
| }
|
| + ++message_current;
|
| }
|
| + }
|
| #endif // __SSE2__
|
| while (message_current < message_end) {
|
| if (*message_current != '\n') {
|
| @@ -1047,8 +1042,8 @@ size_t BalsaFrame::ProcessHeaders(const char* message_start,
|
| }
|
| const size_t relative_idx = message_current - message_start;
|
| const size_t message_current_idx = 1 + base_idx + relative_idx;
|
| - lines_.push_back(std::make_pair(last_slash_n_idx_,
|
| - message_current_idx));
|
| + lines_.push_back(
|
| + std::make_pair(last_slash_n_idx_, message_current_idx));
|
| if (lines_.size() == 1) {
|
| headers_->WriteFromFramer(checkpoint,
|
| 1 + message_current - checkpoint);
|
| @@ -1064,8 +1059,8 @@ size_t BalsaFrame::ProcessHeaders(const char* message_start,
|
| else if (parse_state_ == BalsaFrameEnums::PARSE_ERROR)
|
| goto bottom;
|
| }
|
| - const size_t chars_since_last_slash_n = (message_current_idx -
|
| - last_slash_n_idx_);
|
| + const size_t chars_since_last_slash_n =
|
| + (message_current_idx - last_slash_n_idx_);
|
| last_slash_n_idx_ = message_current_idx;
|
| if (chars_since_last_slash_n > 2) {
|
| // false positive.
|
| @@ -1082,7 +1077,7 @@ size_t BalsaFrame::ProcessHeaders(const char* message_start,
|
| }
|
| }
|
| continue;
|
| - process_lines:
|
| + process_lines:
|
| ++message_current;
|
| DCHECK(message_current >= message_start);
|
| if (message_current > message_start) {
|
| @@ -1139,11 +1134,10 @@ size_t BalsaFrame::ProcessHeaders(const char* message_start,
|
| if (message_current > message_start) {
|
| headers_->WriteFromFramer(checkpoint, message_current - checkpoint);
|
| }
|
| - bottom:
|
| +bottom:
|
| return message_current - original_message_start;
|
| }
|
|
|
| -
|
| size_t BalsaFrame::BytesSafeToSplice() const {
|
| switch (parse_state_) {
|
| case BalsaFrameEnums::READING_CHUNK_DATA:
|
| @@ -1167,8 +1161,8 @@ void BalsaFrame::BytesSpliced(size_t bytes_spliced) {
|
| }
|
| return;
|
| } else {
|
| - last_error_ =
|
| - BalsaFrameEnums::CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT;
|
| + last_error_ = BalsaFrameEnums::
|
| + CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT;
|
| goto error_exit;
|
| }
|
|
|
| @@ -1184,8 +1178,8 @@ void BalsaFrame::BytesSpliced(size_t bytes_spliced) {
|
| }
|
| return;
|
| } else {
|
| - last_error_ =
|
| - BalsaFrameEnums::CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT;
|
| + last_error_ = BalsaFrameEnums::
|
| + CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT;
|
| goto error_exit;
|
| }
|
|
|
| @@ -1194,7 +1188,7 @@ void BalsaFrame::BytesSpliced(size_t bytes_spliced) {
|
| goto error_exit;
|
| }
|
|
|
| - error_exit:
|
| +error_exit:
|
| parse_state_ = BalsaFrameEnums::PARSE_ERROR;
|
| visitor_->HandleBodyError(this);
|
| };
|
| @@ -1219,13 +1213,13 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| const char* on_entry = current;
|
| const char* end = current + size;
|
| #if DEBUGFRAMER
|
| - LOG(INFO) << "\n=============="
|
| - << BalsaFrameEnums::ParseStateToString(parse_state_)
|
| - << "===============\n";
|
| + LOG(INFO) << "\n==============" << BalsaFrameEnums::ParseStateToString(
|
| + parse_state_) << "===============\n";
|
| #endif // DEBUGFRAMER
|
|
|
| DCHECK(headers_ != NULL);
|
| - if (headers_ == NULL) return 0;
|
| + if (headers_ == NULL)
|
| + return 0;
|
|
|
| if (parse_state_ == BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE) {
|
| const size_t header_length = headers_->GetReadableBytesFromHeaderStream();
|
| @@ -1270,7 +1264,7 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
|
|
| while (current < end) {
|
| switch (parse_state_) {
|
| - label_reading_chunk_length:
|
| + label_reading_chunk_length:
|
| case BalsaFrameEnums::READING_CHUNK_LENGTH:
|
| // In this state we read the chunk length.
|
| // Note that once we hit a character which is not in:
|
| @@ -1281,22 +1275,22 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| // This is more annoying than simply doing the conversion
|
| // here. This code accounts for overflow.
|
| static const signed char buf[] = {
|
| - // %0 %1 %2 %3 %4 %5 %6 %7 %8 \t \n %b %c \r %e %f
|
| - -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1,
|
| - // %10 %11 %12 %13 %14 %15 %16 %17 %18 %19 %1a %1b %1c %1d %1e %1f
|
| - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| - // ' ' %21 %22 %23 %24 %25 %26 %27 %28 %29 %2a %2b %2c %2d %2e %2f
|
| - -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| - // %30 %31 %32 %33 %34 %35 %36 %37 %38 %39 %3a ';' %3c %3d %3e %3f
|
| - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -2, -1, -1, -1, -1,
|
| - // %40 'A' 'B' 'C' 'D' 'E' 'F' %47 %48 %49 %4a %4b %4c %4d %4e %4f
|
| - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| - // %50 %51 %52 %53 %54 %55 %56 %57 %58 %59 %5a %5b %5c %5d %5e %5f
|
| - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| - // %60 'a' 'b' 'c' 'd' 'e' 'f' %67 %68 %69 %6a %6b %6c %6d %6e %6f
|
| - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| - // %70 %71 %72 %73 %74 %75 %76 %77 %78 %79 %7a %7b %7c %7d %7e %7f
|
| - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| + // %0 %1 %2 %3 %4 %5 %6 %7 %8 \t \n %b %c \r %e %f
|
| + -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1,
|
| + // %10 %11 %12 %13 %14 %15 %16 %17 %18 %19 %1a %1b %1c %1d %1e %1f
|
| + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| + // ' ' %21 %22 %23 %24 %25 %26 %27 %28 %29 %2a %2b %2c %2d %2e %2f
|
| + -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| + // %30 %31 %32 %33 %34 %35 %36 %37 %38 %39 %3a ';' %3c %3d %3e %3f
|
| + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -2, -1, -1, -1, -1,
|
| + // %40 'A' 'B' 'C' 'D' 'E' 'F' %47 %48 %49 %4a %4b %4c %4d %4e %4f
|
| + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| + // %50 %51 %52 %53 %54 %55 %56 %57 %58 %59 %5a %5b %5c %5d %5e %5f
|
| + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| + // %60 'a' 'b' 'c' 'd' 'e' 'f' %67 %68 %69 %6a %6b %6c %6d %6e %6f
|
| + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| + // %70 %71 %72 %73 %74 %75 %76 %77 %78 %79 %7a %7b %7c %7d %7e %7f
|
| + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
| };
|
| // valid cases:
|
| // "09123\n" // -> 09123
|
| @@ -1356,44 +1350,41 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| visitor_->ProcessBodyInput(on_entry, current - on_entry);
|
| goto bottom; // case BalsaFrameEnums::READING_CHUNK_LENGTH
|
|
|
| - label_reading_chunk_extension:
|
| - case BalsaFrameEnums::READING_CHUNK_EXTENSION:
|
| - {
|
| - // TODO(phython): Convert this scanning to be 16 bytes at a time if
|
| - // there is data to be read.
|
| - const char* extensions_start = current;
|
| - size_t extensions_length = 0;
|
| - while (current < end) {
|
| - const char c = *current;
|
| - if (c == '\r' || c == '\n') {
|
| - extensions_length =
|
| - (extensions_start == current) ?
|
| - 0 :
|
| - current - extensions_start - 1;
|
| - }
|
| + label_reading_chunk_extension:
|
| + case BalsaFrameEnums::READING_CHUNK_EXTENSION: {
|
| + // TODO(phython): Convert this scanning to be 16 bytes at a time if
|
| + // there is data to be read.
|
| + const char* extensions_start = current;
|
| + size_t extensions_length = 0;
|
| + while (current < end) {
|
| + const char c = *current;
|
| + if (c == '\r' || c == '\n') {
|
| + extensions_length = (extensions_start == current)
|
| + ? 0
|
| + : current - extensions_start - 1;
|
| + }
|
|
|
| - ++current;
|
| - if (c == '\n') {
|
| - chunk_length_character_extracted_ = false;
|
| - visitor_->ProcessChunkExtensions(
|
| - extensions_start, extensions_length);
|
| - if (chunk_length_remaining_ != 0) {
|
| - parse_state_ = BalsaFrameEnums::READING_CHUNK_DATA;
|
| - goto label_reading_chunk_data;
|
| - }
|
| - HeaderFramingFound('\n');
|
| - parse_state_ = BalsaFrameEnums::READING_LAST_CHUNK_TERM;
|
| - goto label_reading_last_chunk_term;
|
| + ++current;
|
| + if (c == '\n') {
|
| + chunk_length_character_extracted_ = false;
|
| + visitor_->ProcessChunkExtensions(extensions_start,
|
| + extensions_length);
|
| + if (chunk_length_remaining_ != 0) {
|
| + parse_state_ = BalsaFrameEnums::READING_CHUNK_DATA;
|
| + goto label_reading_chunk_data;
|
| }
|
| + HeaderFramingFound('\n');
|
| + parse_state_ = BalsaFrameEnums::READING_LAST_CHUNK_TERM;
|
| + goto label_reading_last_chunk_term;
|
| }
|
| - visitor_->ProcessChunkExtensions(
|
| - extensions_start, extensions_length);
|
| }
|
| + visitor_->ProcessChunkExtensions(extensions_start, extensions_length);
|
| + }
|
|
|
| visitor_->ProcessBodyInput(on_entry, current - on_entry);
|
| goto bottom; // case BalsaFrameEnums::READING_CHUNK_EXTENSION
|
|
|
| - label_reading_chunk_data:
|
| + label_reading_chunk_data:
|
| case BalsaFrameEnums::READING_CHUNK_DATA:
|
| while (current < end) {
|
| if (chunk_length_remaining_ == 0) {
|
| @@ -1401,8 +1392,9 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| }
|
| // read in the chunk
|
| size_t bytes_remaining = end - current;
|
| - size_t consumed_bytes = (chunk_length_remaining_ < bytes_remaining) ?
|
| - chunk_length_remaining_ : bytes_remaining;
|
| + size_t consumed_bytes = (chunk_length_remaining_ < bytes_remaining)
|
| + ? chunk_length_remaining_
|
| + : bytes_remaining;
|
| const char* tmp_current = current + consumed_bytes;
|
| visitor_->ProcessBodyInput(on_entry, tmp_current - on_entry);
|
| visitor_->ProcessBodyData(current, consumed_bytes);
|
| @@ -1416,7 +1408,7 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| visitor_->ProcessBodyInput(on_entry, current - on_entry);
|
| goto bottom; // case BalsaFrameEnums::READING_CHUNK_DATA
|
|
|
| - label_reading_chunk_term:
|
| + label_reading_chunk_term:
|
| case BalsaFrameEnums::READING_CHUNK_TERM:
|
| while (current < end) {
|
| const char c = *current;
|
| @@ -1430,7 +1422,7 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| visitor_->ProcessBodyInput(on_entry, current - on_entry);
|
| goto bottom; // case BalsaFrameEnums::READING_CHUNK_TERM
|
|
|
| - label_reading_last_chunk_term:
|
| + label_reading_last_chunk_term:
|
| case BalsaFrameEnums::READING_LAST_CHUNK_TERM:
|
| while (current < end) {
|
| const char c = *current;
|
| @@ -1472,7 +1464,7 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| visitor_->ProcessBodyInput(on_entry, current - on_entry);
|
| goto bottom; // case BalsaFrameEnums::READING_LAST_CHUNK_TERM
|
|
|
| - label_reading_trailer:
|
| + label_reading_trailer:
|
| case BalsaFrameEnums::READING_TRAILER:
|
| while (current < end) {
|
| const char c = *current;
|
| @@ -1495,23 +1487,22 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| visitor_->ProcessTrailerInput(on_entry, current - on_entry);
|
| break; // case BalsaFrameEnums::READING_TRAILER
|
|
|
| - // Note that there is no label:
|
| - // 'label_reading_until_close'
|
| - // here. This is because the state-machine exists immediately after
|
| - // reading the headers instead of transitioning here (as it would
|
| - // do if it was consuming all the data it could, all the time).
|
| - case BalsaFrameEnums::READING_UNTIL_CLOSE:
|
| - {
|
| - const size_t bytes_remaining = end - current;
|
| - if (bytes_remaining > 0) {
|
| - visitor_->ProcessBodyInput(current, bytes_remaining);
|
| - visitor_->ProcessBodyData(current, bytes_remaining);
|
| - current += bytes_remaining;
|
| - }
|
| + // Note that there is no label:
|
| + // 'label_reading_until_close'
|
| + // here. This is because the state-machine exists immediately after
|
| + // reading the headers instead of transitioning here (as it would
|
| + // do if it was consuming all the data it could, all the time).
|
| + case BalsaFrameEnums::READING_UNTIL_CLOSE: {
|
| + const size_t bytes_remaining = end - current;
|
| + if (bytes_remaining > 0) {
|
| + visitor_->ProcessBodyInput(current, bytes_remaining);
|
| + visitor_->ProcessBodyData(current, bytes_remaining);
|
| + current += bytes_remaining;
|
| }
|
| + }
|
| goto bottom; // case BalsaFrameEnums::READING_UNTIL_CLOSE
|
|
|
| - // label_reading_content:
|
| + // label_reading_content:
|
| case BalsaFrameEnums::READING_CONTENT:
|
| #if DEBUGFRAMER
|
| LOG(INFO) << "ReadingContent: " << content_length_remaining_;
|
| @@ -1520,8 +1511,9 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| // read in the content
|
| const size_t bytes_remaining = end - current;
|
| const size_t consumed_bytes =
|
| - (content_length_remaining_ < bytes_remaining) ?
|
| - content_length_remaining_ : bytes_remaining;
|
| + (content_length_remaining_ < bytes_remaining)
|
| + ? content_length_remaining_
|
| + : bytes_remaining;
|
| visitor_->ProcessBodyInput(current, consumed_bytes);
|
| visitor_->ProcessBodyData(current, consumed_bytes);
|
| current += consumed_bytes;
|
| @@ -1538,17 +1530,16 @@ size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
|
| // above. This is a glaring logic error, and we should do something
|
| // drastic to ensure that this gets looked-at and fixed.
|
| LOG(FATAL) << "Unknown state: " << parse_state_ // COV_NF_LINE
|
| - << " memory corruption?!"; // COV_NF_LINE
|
| + << " memory corruption?!"; // COV_NF_LINE
|
| }
|
| }
|
| - bottom:
|
| +bottom:
|
| #if DEBUGFRAMER
|
| LOG(INFO) << "\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"
|
| - << std::string(input, current)
|
| - << "\n$$$$$$$$$$$$$$"
|
| - << BalsaFrameEnums::ParseStateToString(parse_state_)
|
| - << "$$$$$$$$$$$$$$$"
|
| - << " consumed: " << (current - input);
|
| + << std::string(input, current) << "\n$$$$$$$$$$$$$$"
|
| + << BalsaFrameEnums::ParseStateToString(parse_state_)
|
| + << "$$$$$$$$$$$$$$$"
|
| + << " consumed: " << (current - input);
|
| if (Error()) {
|
| LOG(INFO) << BalsaFrameEnums::ErrorCodeToString(ErrorCode());
|
| }
|
|
|