// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/tools/balsa/balsa_frame.h"

// Visual C++ defines _M_IX86_FP as 2 if the /arch:SSE2 compiler option is
// specified.
#if !defined(__SSE2__) && _M_IX86_FP == 2
#define __SSE2__ 1
#endif

#include <assert.h>
#if __SSE2__
#include <emmintrin.h>
#endif  // __SSE2__

#include <limits>
#include <string>
#include <utility>
#include <vector>

#include "base/logging.h"
#include "base/port.h"
#include "base/strings/string_piece.h"
#include "net/tools/balsa/balsa_enums.h"
#include "net/tools/balsa/balsa_headers.h"
#include "net/tools/balsa/balsa_visitor_interface.h"
#include "net/tools/balsa/buffer_interface.h"
#include "net/tools/balsa/simple_buffer.h"
#include "net/tools/balsa/split.h"
#include "net/tools/balsa/string_piece_utils.h"

#if defined(COMPILER_MSVC)
#include <intrin.h>
#include <string.h>

#pragma intrinsic(_BitScanForward)

static int ffs(int i) {
  unsigned long index;
  return _BitScanForward(&index, i) ? index + 1 : 0;
}

#define strncasecmp _strnicmp
#else
#include <strings.h>
#endif

namespace net {

// Constants holding some header names for headers which can affect the way the
// HTTP message is framed, and so must be processed specially:
static const char kContentLength[] = "content-length";
static const size_t kContentLengthSize = sizeof(kContentLength) - 1;
static const char kTransferEncoding[] = "transfer-encoding";
static const size_t kTransferEncodingSize = sizeof(kTransferEncoding) - 1;

BalsaFrame::BalsaFrame()
    : last_char_was_slash_r_(false),
      saw_non_newline_char_(false),
      start_was_space_(true),
      chunk_length_character_extracted_(false),
      is_request_(true),
      request_was_head_(false),
      max_header_length_(16 * 1024),
      max_request_uri_length_(2048),
      visitor_(&do_nothing_visitor_),
      chunk_length_remaining_(0),
      content_length_remaining_(0),
      last_slash_n_loc_(NULL),
      last_recorded_slash_n_loc_(NULL),
      last_slash_n_idx_(0),
      term_chars_(0),
      parse_state_(BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE),
      last_error_(BalsaFrameEnums::NO_ERROR),
      headers_(NULL) {
}

BalsaFrame::~BalsaFrame() {}

void BalsaFrame::Reset() {
  last_char_was_slash_r_ = false;
  saw_non_newline_char_ = false;
  start_was_space_ = true;
  chunk_length_character_extracted_ = false;
  // is_request_ = true;               // not reset between messages.
  // request_was_head_ = false;        // not reset between messages.
  // max_header_length_ = 4096;        // not reset between messages.
  // max_request_uri_length_ = 2048;   // not reset between messages.
  // visitor_ = &do_nothing_visitor_;  // not reset between messages.
  chunk_length_remaining_ = 0;
  content_length_remaining_ = 0;
  last_slash_n_loc_ = NULL;
  last_recorded_slash_n_loc_ = NULL;
  last_slash_n_idx_ = 0;
  term_chars_ = 0;
  parse_state_ = BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE;
  last_error_ = BalsaFrameEnums::NO_ERROR;
  lines_.clear();
  if (headers_ != NULL) {
    headers_->Clear();
  }
}

const char* BalsaFrameEnums::ParseStateToString(
    BalsaFrameEnums::ParseState error_code) {
  switch (error_code) {
    case PARSE_ERROR:
      return "PARSE_ERROR";
    case READING_HEADER_AND_FIRSTLINE:
      return "READING_HEADER_AND_FIRSTLINE";
    case READING_CHUNK_LENGTH:
      return "READING_CHUNK_LENGTH";
    case READING_CHUNK_EXTENSION:
      return "READING_CHUNK_EXTENSION";
    case READING_CHUNK_DATA:
      return "READING_CHUNK_DATA";
    case READING_CHUNK_TERM:
      return "READING_CHUNK_TERM";
    case READING_LAST_CHUNK_TERM:
      return "READING_LAST_CHUNK_TERM";
    case READING_TRAILER:
      return "READING_TRAILER";
    case READING_UNTIL_CLOSE:
      return "READING_UNTIL_CLOSE";
    case READING_CONTENT:
      return "READING_CONTENT";
    case MESSAGE_FULLY_READ:
      return "MESSAGE_FULLY_READ";
    case NUM_STATES:
      return "UNKNOWN_STATE";
  }
  return "UNKNOWN_STATE";
}

const char* BalsaFrameEnums::ErrorCodeToString(
    BalsaFrameEnums::ErrorCode error_code) {
  switch (error_code) {
    case NO_ERROR:
      return "NO_ERROR";
    case NO_STATUS_LINE_IN_RESPONSE:
      return "NO_STATUS_LINE_IN_RESPONSE";
    case NO_REQUEST_LINE_IN_REQUEST:
      return "NO_REQUEST_LINE_IN_REQUEST";
    case FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION:
      return "FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION";
    case FAILED_TO_FIND_WS_AFTER_REQUEST_METHOD:
      return "FAILED_TO_FIND_WS_AFTER_REQUEST_METHOD";
    case FAILED_TO_FIND_WS_AFTER_RESPONSE_STATUSCODE:
      return "FAILED_TO_FIND_WS_AFTER_RESPONSE_STATUSCODE";
    case FAILED_TO_FIND_WS_AFTER_REQUEST_REQUEST_URI:
      return "FAILED_TO_FIND_WS_AFTER_REQUEST_REQUEST_URI";
    case FAILED_TO_FIND_NL_AFTER_RESPONSE_REASON_PHRASE:
      return "FAILED_TO_FIND_NL_AFTER_RESPONSE_REASON_PHRASE";
    case FAILED_TO_FIND_NL_AFTER_REQUEST_HTTP_VERSION:
      return "FAILED_TO_FIND_NL_AFTER_REQUEST_HTTP_VERSION";
    case FAILED_CONVERTING_STATUS_CODE_TO_INT:
      return "FAILED_CONVERTING_STATUS_CODE_TO_INT";
    case REQUEST_URI_TOO_LONG:
      return "REQUEST_URI_TOO_LONG";
    case HEADERS_TOO_LONG:
      return "HEADERS_TOO_LONG";
    case UNPARSABLE_CONTENT_LENGTH:
      return "UNPARSABLE_CONTENT_LENGTH";
    case MAYBE_BODY_BUT_NO_CONTENT_LENGTH:
      return "MAYBE_BODY_BUT_NO_CONTENT_LENGTH";
    case REQUIRED_BODY_BUT_NO_CONTENT_LENGTH:
      return "REQUIRED_BODY_BUT_NO_CONTENT_LENGTH";
    case HEADER_MISSING_COLON:
      return "HEADER_MISSING_COLON";
    case INVALID_CHUNK_LENGTH:
      return "INVALID_CHUNK_LENGTH";
    case CHUNK_LENGTH_OVERFLOW:
      return "CHUNK_LENGTH_OVERFLOW";
    case CALLED_BYTES_SPLICED_WHEN_UNSAFE_TO_DO_SO:
      return "CALLED_BYTES_SPLICED_WHEN_UNSAFE_TO_DO_SO";
    case CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT:
      return "CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT";
    case MULTIPLE_CONTENT_LENGTH_KEYS:
      return "MULTIPLE_CONTENT_LENGTH_KEYS";
    case MULTIPLE_TRANSFER_ENCODING_KEYS:
      return "MULTIPLE_TRANSFER_ENCODING_KEYS";
    case UNKNOWN_TRANSFER_ENCODING:
      return "UNKNOWN_TRANSFER_ENCODING";
    case INVALID_HEADER_FORMAT:
      return "INVALID_HEADER_FORMAT";
    case INTERNAL_LOGIC_ERROR:
      return "INTERNAL_LOGIC_ERROR";
    case NUM_ERROR_CODES:
      return "UNKNOWN_ERROR";
  }
  return "UNKNOWN_ERROR";
}

// Summary:
//     Parses the first line of either a request or response.
//     Note that in the case of a detected warning, error_code will be set
//   but the function will not return false.
//     Exactly zero or one warning or error (but not both) may be detected
//   by this function.
//     Note that this function will not write the data of the first-line
//   into the header's buffer (that should already have been done elsewhere).
//
// Pre-conditions:
//     begin != end
//     *begin should be a character which is > ' '. This implies that there
//   is at least one non-whitespace characters between [begin, end).
//   headers is a valid pointer to a BalsaHeaders class.
//     error_code is a valid pointer to a BalsaFrameEnums::ErrorCode value.
//     Entire first line must exist between [begin, end)
//     Exactly zero or one newlines -may- exist between [begin, end)
//     [begin, end) should exist in the header's buffer.
//
// Side-effects:
//   headers will be modified
//   error_code may be modified if either a warning or error is detected
//
// Returns:
//   True if no error (as opposed to warning) is detected.
//   False if an error (as opposed to warning) is detected.

//
// If there is indeed non-whitespace in the line, then the following
// will take care of this for you:
//  while (*begin <= ' ') ++begin;
//  ProcessFirstLine(begin, end, is_request, &headers, &error_code);
//
bool ParseHTTPFirstLine(const char* begin,
                        const char* end,
                        bool is_request,
                        size_t max_request_uri_length,
                        BalsaHeaders* headers,
                        BalsaFrameEnums::ErrorCode* error_code) {
  const char* current = begin;
  // HTTP firstlines all have the following structure:
  //  LWS         NONWS  LWS    NONWS   LWS    NONWS   NOTCRLF  CRLF
  //  [\t \r\n]+ [^\t ]+ [\t ]+ [^\t ]+ [\t ]+ [^\t ]+ [^\r\n]+ "\r\n"
  //  ws1        nws1    ws2    nws2    ws3    nws3             ws4
  //  |          [-------)      [-------)      [----------------)
  //    REQ:     method         request_uri    version
  //   RESP:     version        statuscode     reason
  //
  //   The first NONWS->LWS component we'll call firstline_a.
  //   The second firstline_b, and the third firstline_c.
  //
  //   firstline_a goes from nws1 to (but not including) ws2
  //   firstline_b goes from nws2 to (but not including) ws3
  //   firstline_c goes from nws3 to (but not including) ws4
  //
  // In the code:
  //    ws1 == whitespace_1_idx_
  //   nws1 == non_whitespace_1_idx_
  //    ws2 == whitespace_2_idx_
  //   nws2 == non_whitespace_2_idx_
  //    ws3 == whitespace_3_idx_
  //   nws3 == non_whitespace_3_idx_
  //    ws4 == whitespace_4_idx_

  // Kill all whitespace (including '\r\n') at the end of the line.
  --end;
  if (*end != '\n') {
    *error_code = BalsaFrameEnums::INTERNAL_LOGIC_ERROR;
    LOG(DFATAL) << "INTERNAL_LOGIC_ERROR Headers: \n"
                << headers->OriginalHeadersForDebugging();
    return false;
  }
  while (begin < end && *end <= ' ') {
    --end;
  }
  DCHECK(*end != '\n');
  if (*end == '\n') {
    *error_code = BalsaFrameEnums::INTERNAL_LOGIC_ERROR;
    LOG(DFATAL) << "INTERNAL_LOGIC_ERROR Headers: \n"
                << headers->OriginalHeadersForDebugging();
    return false;
  }
  ++end;

  // The two following statements should not be possible.
  if (end == begin) {
    *error_code = BalsaFrameEnums::INTERNAL_LOGIC_ERROR;
    LOG(DFATAL) << "INTERNAL_LOGIC_ERROR Headers: \n"
                << headers->OriginalHeadersForDebugging();
    return false;
  }

  // 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).
#if 0
  while (*current <= ' ') {
    ++current;
  }
#endif
  // non_whitespace_1_idx_
  headers->non_whitespace_1_idx_ = current - begin;
  do {
    // The first time through, we're guaranteed that the current character
    // won't be a whitespace (else the loop above wouldn't have terminated).
    // That implies that we're guaranteed to get at least one non-whitespace
    // character if we get into this loop at all.
    ++current;
    if (current == end) {
      headers->whitespace_2_idx_ = current - begin;
      headers->non_whitespace_2_idx_ = current - begin;
      headers->whitespace_3_idx_ = current - begin;
      headers->non_whitespace_3_idx_ = current - 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);
      if (!is_request) {  // FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION
        return false;
      }
      goto output_exhausted;
    }
  } while (*current > ' ');
  // whitespace_2_idx_
  headers->whitespace_2_idx_ = current - begin;
  do {
    ++current;
    // Note that due to the loop which consumes all of the whitespace
    // at the end of the line, current can never == end while in this function.
  } while (*current <= ' ');
  // non_whitespace_2_idx_
  headers->non_whitespace_2_idx_ = current - begin;
  do {
    ++current;
    if (current == end) {
      headers->whitespace_3_idx_ = current - begin;
      headers->non_whitespace_3_idx_ = current - 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);
      goto output_exhausted;
    }
  } while (*current > ' ');
  // whitespace_3_idx_
  headers->whitespace_3_idx_ = current - begin;
  do {
    ++current;
    // Note that due to the loop which consumes all of the whitespace
    // at the end of the line, current can never == end while in this function.
  } while (*current <= ' ');
  // non_whitespace_3_idx_
  headers->non_whitespace_3_idx_ = current - begin;
  headers->whitespace_4_idx_ = end - begin;

 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:
  //   GET\r\n
  // or
  //   GET /\r\n
  // should be parsed without issue (though the visitor should know that
  // parsing the entire line was not exactly as it should be).
  //
  // Eventually, these errors may be removed alltogether, as the visitor can
  // detect them on its own by examining the size of the various fields.
  // headers->set_first_line(non_whitespace_1_idx_, current);

  if (is_request) {
    if ((headers->whitespace_3_idx_ - headers->non_whitespace_2_idx_) >
        max_request_uri_length) {
      // For requests, we need at least the method.  We could assume that a
      // blank URI means "/".  If version isn't stated, it should be assumed
      // to be HTTP/0.9 by the visitor.
      *error_code = BalsaFrameEnums::REQUEST_URI_TOO_LONG;
      return false;
    }
  } else {
    headers->parsed_response_code_ = 0;
    {
      const char* parsed_response_code_current =
        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;

      // Convert a string of [0-9]* into an int.
      // Note that this allows for the conversion of response codes which
      // are outside the bounds of normal HTTP response codes (no checking
      // is done to ensure that these are valid-- they're merely parsed)!
      while (parsed_response_code_current < parsed_response_code_end) {
        if (*parsed_response_code_current < '0' ||
            *parsed_response_code_current > '9') {
          *error_code = BalsaFrameEnums::FAILED_CONVERTING_STATUS_CODE_TO_INT;
          return false;
        }
        size_t status_code_x_10 = headers->parsed_response_code_ * 10;
        uint8 c = *parsed_response_code_current - '0';
        if ((headers->parsed_response_code_ > kMaxDiv10) ||
            (std::numeric_limits<size_t>::max() - status_code_x_10) < c) {
          // overflow.
          *error_code = BalsaFrameEnums::FAILED_CONVERTING_STATUS_CODE_TO_INT;
          return false;
        }
        headers->parsed_response_code_ = status_code_x_10 + c;
        ++parsed_response_code_current;
      }
    }
  }
  return true;
}

// begin - beginning of the firstline
// end - end of the firstline
//
// A precondition for this function is that there is non-whitespace between
// [begin, end). If this precondition is not met, the function will not perform
// as expected (and bad things may happen, and it will eat your first, second,
// and third unborn children!).
//
// Another precondition for this function is that [begin, end) includes
// at most one newline, which must be at the end of the line.
void BalsaFrame::ProcessFirstLine(const char* begin, const char* end) {
  BalsaFrameEnums::ErrorCode previous_error = last_error_;
  if (!ParseHTTPFirstLine(begin,
                          end,
                          is_request_,
                          max_request_uri_length_,
                          headers_,
                          &last_error_)) {
    parse_state_ = BalsaFrameEnums::PARSE_ERROR;
    visitor_->HandleHeaderError(this);
    return;
  }
  if (previous_error != last_error_) {
    visitor_->HandleHeaderWarning(this);
  }

  if (is_request_) {
    size_t version_length =
        headers_->whitespace_4_idx_ - headers_->non_whitespace_3_idx_;
    visitor_->ProcessRequestFirstLine(
        begin + headers_->non_whitespace_1_idx_,
        headers_->whitespace_4_idx_ - headers_->non_whitespace_1_idx_,
        begin + headers_->non_whitespace_1_idx_,
        headers_->whitespace_2_idx_ - headers_->non_whitespace_1_idx_,
        begin + headers_->non_whitespace_2_idx_,
        headers_->whitespace_3_idx_ - headers_->non_whitespace_2_idx_,
        begin + headers_->non_whitespace_3_idx_,
        version_length);
    if (version_length == 0)
      parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
  } else {
    visitor_->ProcessResponseFirstLine(
        begin + headers_->non_whitespace_1_idx_,
        headers_->whitespace_4_idx_ - headers_->non_whitespace_1_idx_,
        begin + headers_->non_whitespace_1_idx_,
        headers_->whitespace_2_idx_ - headers_->non_whitespace_1_idx_,
        begin + headers_->non_whitespace_2_idx_,
        headers_->whitespace_3_idx_ - headers_->non_whitespace_2_idx_,
        begin + headers_->non_whitespace_3_idx_,
        headers_->whitespace_4_idx_ - headers_->non_whitespace_3_idx_);
  }
}

// 'stream_begin' points to the first character of the headers buffer.
// 'line_begin' points to the first character of the line.
// 'current' points to a char which is ':'.
// 'line_end' points to the position of '\n' + 1.
// 'line_begin' points to the position of first character of line.
void BalsaFrame::CleanUpKeyValueWhitespace(
    const char* stream_begin,
    const char* line_begin,
    const char* current,
    const char* line_end,
    HeaderLineDescription* current_header_line) {
  const char* colon_loc = current;
  DCHECK_LT(colon_loc, line_end);
  DCHECK_EQ(':', *colon_loc);
  DCHECK_EQ(':', *current);
  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;
  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;
  current_header_line->value_begin_idx = current - stream_begin;

  DCHECK_GE(current_header_line->key_end_idx,
            current_header_line->first_char_idx);
  DCHECK_GE(current_header_line->value_begin_idx,
            current_header_line->key_end_idx);
  DCHECK_GE(current_header_line->last_char_idx,
            current_header_line->value_begin_idx);
}

inline void BalsaFrame::FindColonsAndParseIntoKeyValue() {
  DCHECK(!lines_.empty());
  const char* stream_begin = headers_->OriginalHeaderStreamBegin();
  // The last line is always just a newline (and is uninteresting).
  const Lines::size_type lines_size_m1 = lines_.size() - 1;
#if __SSE2__
  const __m128i colons = _mm_set1_epi8(':');
  const char* header_lines_end_m16 = headers_->OriginalHeaderStreamEnd() - 16;
#endif  // __SSE2__
  const char* current = stream_begin + lines_[1].first;
  // This code is a bit more subtle than it may appear at first glance.
  // This code looks for a colon in the current line... but it also looks
  // beyond the current line. If there is no colon in the current line, then
  // for each subsequent line (until the colon which -has- been found is
  // associated with a line), no searching for a colon will be performed. In
  // this way, we minimize the amount of bytes we have scanned for a colon.
  for (Lines::size_type i = 1; i < lines_size_m1;) {
    const char* line_begin = stream_begin + lines_[i].first;

    // Here we handle possible continuations.  Note that we do not replace
    // the '\n' in the line before a continuation (at least, as of now),
    // which implies that any code which looks for a value must deal with
    // "\r\n", etc -within- the line (and not just at the end of it).
    for (++i; i < lines_size_m1; ++i) {
      const char c = *(stream_begin + lines_[i].first);
      if (c > ' ') {
        // Not a continuation, so stop.  Note that if the 'original' i = 1,
        // and the next line is not a continuation, we'll end up with i = 2
        // when we break. This handles the incrementing of i for the outer
        // loop.
        break;
      }
    }
    const char* line_end = stream_begin + lines_[i - 1].second;
    DCHECK_LT(line_begin - stream_begin, line_end - stream_begin);

    // We cleanup the whitespace at the end of the line before doing anything
    // else of interest as it allows us to do nothing when irregularly formatted
    // headers are parsed (e.g. those with only keys, only values, or no colon).
    //
    // 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) << "\"";
    while (*line_end <= ' ' && line_end > line_begin) {
      --line_end;
    }
    ++line_end;
    DCHECK_GE(' ', *line_end);
    DCHECK_LT(line_begin, line_end);

    // We use '0' for the block idx, because we're always writing to the first
    // block from the framer (we do this because the framer requires that the
    // entire header sequence be in a contiguous buffer).
    headers_->header_lines_.push_back(
        HeaderLineDescription(line_begin - stream_begin,
                              line_end - stream_begin,
                              line_end - stream_begin,
                              line_end - stream_begin,
                              0));
    if (current >= line_end) {
      last_error_ = BalsaFrameEnums::HEADER_MISSING_COLON;
      visitor_->HandleHeaderWarning(this);
      // Then the next colon will not be found within this header line-- time
      // to try again with another header-line.
      continue;
    } else if (current < line_begin) {
      // When this condition is true, the last detected colon was part of a
      // previous line.  We reset to the beginning of the line as we don't care
      // about the presence of any colon before the beginning of the current
      // line.
      current = line_begin;
    }
#if __SSE2__
    while (current < header_lines_end_m16) {
      __m128i header_bytes =
        _mm_loadu_si128(reinterpret_cast<const __m128i *>(current));
      __m128i colon_cmp = _mm_cmpeq_epi8(header_bytes, colons);
      int colon_msk = _mm_movemask_epi8(colon_cmp);
      if (colon_msk == 0) {
        current += 16;
        continue;
      }
      current += (ffs(colon_msk) - 1);
      if (current > line_end) {
        break;
      }
      goto found_colon;
    }
#endif  // __SSE2__
    for (; current < line_end; ++current) {
      if (*current != ':') {
        continue;
      }
      goto found_colon;
    }
    // If we've gotten to here, then there was no colon
    // in the line. The arguments we passed into the construction
    // for the HeaderLineDescription object should be OK-- it assumes
    // that the entire content is 'key' by default (which is true, as
    // there was no colon, there can be no value). Note that this is a
    // construct which is technically not allowed by the spec.
    last_error_ = BalsaFrameEnums::HEADER_MISSING_COLON;
    visitor_->HandleHeaderWarning(this);
    continue;
 found_colon:
    DCHECK_EQ(*current, ':');
    DCHECK_LE(current - stream_begin, line_end - stream_begin);
    DCHECK_LE(stream_begin - stream_begin, current - stream_begin);

    HeaderLineDescription& current_header_line = headers_->header_lines_.back();
    current_header_line.key_end_idx = current - stream_begin;
    current_header_line.value_begin_idx = current_header_line.key_end_idx;
    if (current < line_end) {
      ++current_header_line.key_end_idx;

      CleanUpKeyValueWhitespace(stream_begin,
                                line_begin,
                                current,
                                line_end,
                                &current_header_line);
    }
  }
}

void BalsaFrame::ProcessContentLengthLine(
    HeaderLines::size_type line_idx,
    BalsaHeadersEnums::ContentLengthStatus* status,
    size_t* length) {
  const HeaderLineDescription& header_line = headers_->header_lines_[line_idx];
  const char* stream_begin = headers_->OriginalHeaderStreamBegin();
  const char* line_end = stream_begin + header_line.last_char_idx;
  const char* value_begin = (stream_begin + header_line.value_begin_idx);

  if (value_begin >= line_end) {
    // There is no non-whitespace value data.
#if DEBUGFRAMER
      LOG(INFO) << "invalid content-length -- no non-whitespace value data";
#endif
    *status = BalsaHeadersEnums::INVALID_CONTENT_LENGTH;
    return;
  }

  *length = 0;
  while (value_begin < line_end) {
    if (*value_begin < '0' || *value_begin > '9') {
      // bad! content-length found, and couldn't parse all of it!
      *status = BalsaHeadersEnums::INVALID_CONTENT_LENGTH;
#if DEBUGFRAMER
      LOG(INFO) << "invalid content-length - non numeric character detected";
#endif  // DEBUGFRAMER
      return;
    }
    const size_t kMaxDiv10 = std::numeric_limits<size_t>::max() / 10;
    size_t length_x_10 = *length * 10;
    const unsigned char c = *value_begin - '0';
    if (*length > kMaxDiv10 ||
        (std::numeric_limits<size_t>::max() - length_x_10) < c) {
      *status = BalsaHeadersEnums::CONTENT_LENGTH_OVERFLOW;
#if DEBUGFRAMER
      LOG(INFO) << "content-length overflow";
#endif  // DEBUGFRAMER
      return;
    }
    *length = length_x_10 + c;
    ++value_begin;
  }
#if DEBUGFRAMER
  LOG(INFO) << "content_length parsed: " << *length;
#endif  // DEBUGFRAMER
  *status = BalsaHeadersEnums::VALID_CONTENT_LENGTH;
}

void BalsaFrame::ProcessTransferEncodingLine(HeaderLines::size_type line_idx) {
  const HeaderLineDescription& header_line = headers_->header_lines_[line_idx];
  const char* stream_begin = headers_->OriginalHeaderStreamBegin();
  const char* line_end = stream_begin + header_line.last_char_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)) {
    headers_->transfer_encoding_is_chunked_ = true;
  } else if ((value_length == 8) &&
      !strncasecmp(value_begin, "identity", 8)) {
    headers_->transfer_encoding_is_chunked_ = false;
  } else {
    last_error_ = BalsaFrameEnums::UNKNOWN_TRANSFER_ENCODING;
    parse_state_ = BalsaFrameEnums::PARSE_ERROR;
    visitor_->HandleHeaderError(this);
    return;
  }
}

namespace {
bool SplitStringPiece(base::StringPiece original, char delim,
                      base::StringPiece* before, base::StringPiece* after) {
  const char* p = original.data();
  const char* end = p + original.size();

  while (p != end) {
    if (*p == delim) {
      ++p;
    } else {
      const char* start = p;
      while (++p != end && *p != delim) {
        // Skip to the next occurence of the delimiter.
      }
      *before = base::StringPiece(start, p - start);
      if (p != end)
        *after = base::StringPiece(p + 1, end - (p + 1));
      else
        *after = base::StringPiece("");
      StringPieceUtils::RemoveWhitespaceContext(before);
      StringPieceUtils::RemoveWhitespaceContext(after);
      return true;
    }
  }

  *before = original;
  *after = "";
  return false;
}

// TODO(phython): Fix this function to properly deal with quoted values.
// E.g. ";;foo", "\";;\"", or \"aa;
// The last example, the semi-colon is a separator between extensions.
void ProcessChunkExtensionsManual(base::StringPiece all_extensions,
                                  BalsaHeaders* extensions) {
  base::StringPiece extension;
  base::StringPiece remaining;
  StringPieceUtils::RemoveWhitespaceContext(&all_extensions);
  SplitStringPiece(all_extensions, ';', &extension, &remaining);
  while (!extension.empty()) {
    base::StringPiece key;
    base::StringPiece value;
    SplitStringPiece(extension, '=', &key, &value);
    if (!value.empty()) {
      // Strip quotation marks if they exist.
      if (!value.empty() && value[0] == '"')
        value.remove_prefix(1);
      if (!value.empty() && value[value.length() - 1] == '"')
        value.remove_suffix(1);
    }

    extensions->AppendHeader(key, value);

    StringPieceUtils::RemoveWhitespaceContext(&remaining);
    SplitStringPiece(remaining, ';', &extension, &remaining);
  }
}

}  // anonymous namespace

void BalsaFrame::ProcessChunkExtensions(const char* input, size_t size,
                                        BalsaHeaders* extensions) {
  ProcessChunkExtensionsManual(base::StringPiece(input, size), extensions);
}

void BalsaFrame::ProcessHeaderLines() {
  HeaderLines::size_type content_length_idx = 0;
  HeaderLines::size_type transfer_encoding_idx = 0;

  DCHECK(!lines_.empty());
#if DEBUGFRAMER
  LOG(INFO) << "******@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**********\n";
#endif  // DEBUGFRAMER

  // There is no need to attempt to process headers if no header lines exist.
  // There are at least two lines in the message which are not header lines.
  // These two non-header lines are the first line of the message, and the
  // last line of the message (which is an empty line).
  // Thus, we test to see if we have more than two lines total before attempting
  // to parse any header lines.
  if (lines_.size() > 2) {
    const char* stream_begin = headers_->OriginalHeaderStreamBegin();

    // Then, for the rest of the header data, we parse these into key-value
    // pairs.
    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();
    for (HeaderLines::size_type i = 0; i < header_lines_size; ++i) {
      const HeaderLineDescription& current_header_line =
        headers_->header_lines_[i];
      const char* key_begin =
        (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;
#if DEBUGFRAMER
      LOG(INFO) << "[" << i << "]: " << std::string(key_begin, key_len)
                << " c: '" << c << "' key_len: " << key_len;
#endif  // DEBUGFRAMER
      // If a header begins with either lowercase or uppercase 'c' or 't', then
      // the header may be one of content-length, connection, content-encoding
      // or transfer-encoding. These headers are special, as they change the way
      // 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;
          size_t length = 0;
          ProcessContentLengthLine(i, &content_length_status, &length);
          if (content_length_idx != 0) {  // then we've already seen one!
            if ((headers_->content_length_status_ != content_length_status) ||
                ((headers_->content_length_status_ ==
                  BalsaHeadersEnums::VALID_CONTENT_LENGTH) &&
                 length != headers_->content_length_)) {
              last_error_ = BalsaFrameEnums::MULTIPLE_CONTENT_LENGTH_KEYS;
              parse_state_ = BalsaFrameEnums::PARSE_ERROR;
              visitor_->HandleHeaderError(this);
              return;
            }
            continue;
          } else {
            content_length_idx = i + 1;
            headers_->content_length_status_ = content_length_status;
            headers_->content_length_ = length;
            content_length_remaining_ = length;
          }

        }
      } else if (c == 't' || c == 'T') {
        if ((key_len == kTransferEncodingSize) &&
            0 == strncasecmp(key_begin, kTransferEncoding,
                             kTransferEncodingSize)) {
          if (transfer_encoding_idx != 0) {
            last_error_ = BalsaFrameEnums::MULTIPLE_TRANSFER_ENCODING_KEYS;
            parse_state_ = BalsaFrameEnums::PARSE_ERROR;
            visitor_->HandleHeaderError(this);
            return;
          }
          transfer_encoding_idx = i + 1;
        }
      } else if (i == 0 && (key_len == 0 || c == ' ')) {
        last_error_ = BalsaFrameEnums::INVALID_HEADER_FORMAT;
        parse_state_ = BalsaFrameEnums::PARSE_ERROR;
        visitor_->HandleHeaderError(this);
        return;
      }
    }
    if (headers_->transfer_encoding_is_chunked_) {
      headers_->content_length_ = 0;
      headers_->content_length_status_ = BalsaHeadersEnums::NO_CONTENT_LENGTH;
      content_length_remaining_ = 0;
    }
    if (transfer_encoding_idx != 0) {
      ProcessTransferEncodingLine(transfer_encoding_idx - 1);
    }
  }
}

void BalsaFrame::AssignParseStateAfterHeadersHaveBeenParsed() {
  // For responses, can't have a body if the request was a HEAD, or if it is
  // 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) ||
        (headers_->parsed_response_code_ == 204) ||
        (headers_->parsed_response_code_ == 304))) {
    // Then we can have a body.
    if (headers_->transfer_encoding_is_chunked_) {
      // Note that
      // if ( Transfer-Encoding: chunked &&  Content-length: )
      // then Transfer-Encoding: chunked trumps.
      // This is as specified in the spec.
      // rfc2616 section 4.4.3
      parse_state_ = BalsaFrameEnums::READING_CHUNK_LENGTH;
    } else {
      // Errors parsing content-length definitely can cause
      // protocol errors/warnings
      switch (headers_->content_length_status_) {
        // If we have a content-length, and it is parsed
        // properly, there are two options.
        // 1) zero content, in which case the message is done, and
        // 2) nonzero content, in which case we have to
        //    consume the body.
        case BalsaHeadersEnums::VALID_CONTENT_LENGTH:
          if (headers_->content_length_ == 0) {
            parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
          } else {
            parse_state_ = BalsaFrameEnums::READING_CONTENT;
          }
          break;
        case BalsaHeadersEnums::CONTENT_LENGTH_OVERFLOW:
        case BalsaHeadersEnums::INVALID_CONTENT_LENGTH:
          // If there were characters left-over after parsing the
          // content length, we should flag an error and stop.
          parse_state_ = BalsaFrameEnums::PARSE_ERROR;
          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.
        case BalsaHeadersEnums::NO_CONTENT_LENGTH:
          if (is_request_) {
            base::StringPiece method = headers_->request_method();
            // POSTs and PUTs should have a detectable body length.  If they
            // 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)) {
              parse_state_ = BalsaFrameEnums::PARSE_ERROR;
              last_error_ =
                  BalsaFrameEnums::REQUIRED_BODY_BUT_NO_CONTENT_LENGTH;
              visitor_->HandleHeaderError(this);
              break;
            }
            parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
          } else {
            parse_state_ = BalsaFrameEnums::READING_UNTIL_CLOSE;
            last_error_ = BalsaFrameEnums::MAYBE_BODY_BUT_NO_CONTENT_LENGTH;
            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
        default:
          LOG(FATAL) << "Saw a content_length_status: "
           << headers_->content_length_status_ << " which is unknown.";
          // COV_NF_END
      }
    }
  }
}

size_t BalsaFrame::ProcessHeaders(const char* message_start,
                                  size_t message_length) {
  const char* const original_message_start = message_start;
  const char* const message_end = message_start + message_length;
  const char* message_current = message_start;
  const char* checkpoint = message_start;

  if (message_length == 0) {
    goto bottom;
  }

  while (message_current < message_end) {
    size_t base_idx = headers_->GetReadableBytesFromHeaderStream();

    // Yes, we could use strchr (assuming null termination), or
    // memchr, but as it turns out that is slower than this tight loop
    // for the input that we see.
    if (!saw_non_newline_char_) {
      do {
        const char c = *message_current;
        if (c != '\r' && c != '\n') {
          if (c <= ' ') {
            parse_state_ = BalsaFrameEnums::PARSE_ERROR;
            last_error_ = BalsaFrameEnums::NO_REQUEST_LINE_IN_REQUEST;
            visitor_->HandleHeaderError(this);
            goto bottom;
          } else {
            saw_non_newline_char_ = true;
            checkpoint = message_start = message_current;
            goto read_real_message;
          }
        }
        ++message_current;
      } 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.
#if __SSE2__
      {
        const char* const message_end_m16 = message_end - 16;
        __m128i newlines = _mm_set1_epi8('\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, 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();
#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_))) {
            goto process_lines;
          }
          ++message_current;
        }
      }
#endif  // __SSE2__
      while (message_current < message_end) {
        if (*message_current != '\n') {
          ++message_current;
          continue;
        }
        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) {
          // false positive.
          ++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;
      }
    }
    continue;
 process_lines:
    ++message_current;
    DCHECK(message_current >= message_start);
    if (message_current > message_start) {
      headers_->WriteFromFramer(checkpoint, message_current - checkpoint);
    }

    // Check if we have exceeded maximum headers length
    // Although we check for this limit before and after we call this function
    // we check it here as well to make sure that in case the visitor changed
    // the max_header_length_ (for example after processing the first line)
    // we handle it gracefully.
    if (headers_->GetReadableBytesFromHeaderStream() > max_header_length_) {
      parse_state_ = BalsaFrameEnums::PARSE_ERROR;
      last_error_ = BalsaFrameEnums::HEADERS_TOO_LONG;
      visitor_->HandleHeaderError(this);
      goto bottom;
    }

    // Since we know that we won't be writing any more bytes of the header,
    // we tell that to the headers object. The headers object may make
    // more efficient allocation decisions when this is signaled.
    headers_->DoneWritingFromFramer();
    {
      const char* readable_ptr = NULL;
      size_t readable_size = 0;
      headers_->GetReadablePtrFromHeaderStream(&readable_ptr, &readable_size);
      visitor_->ProcessHeaderInput(readable_ptr, readable_size);
    }

    // Ok, now that we've written everything into our header buffer, it is
    // time to process the header lines (extract proper values for headers
    // which are important for framing).
    ProcessHeaderLines();
    if (parse_state_ == BalsaFrameEnums::PARSE_ERROR) {
      goto bottom;
    }
    AssignParseStateAfterHeadersHaveBeenParsed();
    if (parse_state_ == BalsaFrameEnums::PARSE_ERROR) {
      goto bottom;
    }
    visitor_->ProcessHeaders(*headers_);
    visitor_->HeaderDone();
    if (parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ) {
      visitor_->MessageDone();
    }
    goto bottom;
  }
  // If we've gotten to here, it means that we've consumed all of the
  // available input. We need to record whether or not the last character we
  // saw was a '\r' so that a subsequent call to ProcessInput correctly finds
  // a header framing that is split across the two calls.
  last_char_was_slash_r_ = (*(message_end - 1) == '\r');
  DCHECK(message_current >= message_start);
  if (message_current > message_start) {
    headers_->WriteFromFramer(checkpoint, message_current - checkpoint);
  }
 bottom:
  return message_current - original_message_start;
}


size_t BalsaFrame::BytesSafeToSplice() const {
  switch (parse_state_) {
    case BalsaFrameEnums::READING_CHUNK_DATA:
      return chunk_length_remaining_;
    case BalsaFrameEnums::READING_UNTIL_CLOSE:
      return std::numeric_limits<size_t>::max();
    case BalsaFrameEnums::READING_CONTENT:
      return content_length_remaining_;
    default:
      return 0;
  }
}

void BalsaFrame::BytesSpliced(size_t bytes_spliced) {
  switch (parse_state_) {
    case BalsaFrameEnums::READING_CHUNK_DATA:
      if (chunk_length_remaining_ >= bytes_spliced) {
        chunk_length_remaining_ -= bytes_spliced;
        if (chunk_length_remaining_ == 0) {
          parse_state_ = BalsaFrameEnums::READING_CHUNK_TERM;
        }
        return;
      } else {
        last_error_ =
          BalsaFrameEnums::CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT;
        goto error_exit;
      }

    case BalsaFrameEnums::READING_UNTIL_CLOSE:
      return;

    case BalsaFrameEnums::READING_CONTENT:
      if (content_length_remaining_ >= bytes_spliced) {
        content_length_remaining_ -= bytes_spliced;
        if (content_length_remaining_ == 0) {
          parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
          visitor_->MessageDone();
        }
        return;
      } else {
        last_error_ =
          BalsaFrameEnums::CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT;
        goto error_exit;
      }

    default:
      last_error_ = BalsaFrameEnums::CALLED_BYTES_SPLICED_WHEN_UNSAFE_TO_DO_SO;
      goto error_exit;
  }

 error_exit:
  parse_state_ = BalsaFrameEnums::PARSE_ERROR;
  visitor_->HandleBodyError(this);
};

// You may note that the state-machine contained within this function has both
// switch and goto labels for nearly the same thing. For instance, the
// following two labels refer to the same code block:
//   label_reading_chunk_data:
//   case BalsaFrameEnums::READING_CHUNK_DATA:
// The 'case' statement is required for the switch statement which occurs when
// ProcessInput is invoked. The goto label is required as the state-machine
// does not use a computed goto in any subsequent operations.
//
// Since several states exit the state machine for various reasons, there is
// also one label at the bottom of the function. When it is appropriate to
// return from the function, that part of the state machine instead issues a
// goto bottom; This results in less code duplication, and makes debugging
// easier (as you can add a statement to a section of code which is guaranteed
// to be invoked when the function is exiting.
size_t BalsaFrame::ProcessInput(const char* input, size_t size) {
  const char* current = input;
  const char* on_entry = current;
  const char* end = current + size;
#if DEBUGFRAMER
  LOG(INFO) << "\n=============="
            << BalsaFrameEnums::ParseStateToString(parse_state_)
            << "===============\n";
#endif  // DEBUGFRAMER

  DCHECK(headers_ != NULL);
  if (headers_ == NULL) return 0;

  if (parse_state_ == BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE) {
    const size_t header_length = headers_->GetReadableBytesFromHeaderStream();
    // Yes, we still have to check this here as the user can change the
    // max_header_length amount!
    // Also it is possible that we have reached the maximum allowed header size,
    // and we have more to consume (remember we are still inside
    // READING_HEADER_AND_FIRSTLINE) in which case we directly declare an error.
    if (header_length > max_header_length_ ||
        (header_length == max_header_length_ && size > 0)) {
      parse_state_ = BalsaFrameEnums::PARSE_ERROR;
      last_error_ = BalsaFrameEnums::HEADERS_TOO_LONG;
      visitor_->HandleHeaderError(this);
      goto bottom;
    }
    size_t bytes_to_process = max_header_length_ - header_length;
    if (bytes_to_process > size) {
      bytes_to_process = size;
    }
    current += ProcessHeaders(input, bytes_to_process);
    // If we are still reading headers check if we have crossed the headers
    // limit. Note that we check for >= as opposed to >. This is because if
    // header_length_after equals max_header_length_ and we are still in the
    // parse_state_  BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE we know for
    // sure that the headers limit will be crossed later on
    if (parse_state_ == BalsaFrameEnums::READING_HEADER_AND_FIRSTLINE) {
      // Note that headers_ is valid only if we are still reading headers.
      const size_t header_length_after =
          headers_->GetReadableBytesFromHeaderStream();
      if (header_length_after >= max_header_length_) {
        parse_state_ = BalsaFrameEnums::PARSE_ERROR;
        last_error_ = BalsaFrameEnums::HEADERS_TOO_LONG;
        visitor_->HandleHeaderError(this);
      }
    }
    goto bottom;
  } else if (parse_state_ == BalsaFrameEnums::MESSAGE_FULLY_READ ||
             parse_state_ == BalsaFrameEnums::PARSE_ERROR) {
    // Can do nothing more 'till we're reset.
    goto bottom;
  }

  while (current < end) {
    switch (parse_state_) {
 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:
        // [0-9;A-Fa-f\n], we transition to a different state.
        //
        {
          // If we used strtol, etc, we'd have to buffer this line.
          // 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,
          };
          // valid cases:
          //  "09123\n"                      // -> 09123
          //  "09123\r\n"                    // -> 09123
          //  "09123  \n"                    // -> 09123
          //  "09123  \r\n"                  // -> 09123
          //  "09123  12312\n"               // -> 09123
          //  "09123  12312\r\n"             // -> 09123
          //  "09123; foo=bar\n"             // -> 09123
          //  "09123; foo=bar\r\n"           // -> 09123
          //  "FFFFFFFFFFFFFFFF\r\n"         // -> FFFFFFFFFFFFFFFF
          //  "FFFFFFFFFFFFFFFF 22\r\n"      // -> FFFFFFFFFFFFFFFF
          // invalid cases:
          // "[ \t]+[^\n]*\n"
          // "FFFFFFFFFFFFFFFFF\r\n"  (would overflow)
          // "\r\n"
          // "\n"
          while (current < end) {
            const char c = *current;
            ++current;
            const signed char addition = buf[static_cast<int>(c)];
            if (addition >= 0) {
              chunk_length_character_extracted_ = true;
              size_t length_x_16 = chunk_length_remaining_ * 16;
              const size_t kMaxDiv16 = std::numeric_limits<size_t>::max() / 16;
              if ((chunk_length_remaining_ > kMaxDiv16) ||
                  ((std::numeric_limits<size_t>::max() - length_x_16) <
                   static_cast<size_t>(addition))) {
                // overflow -- asked for a chunk-length greater than 2^64 - 1!!
                parse_state_ = BalsaFrameEnums::PARSE_ERROR;
                last_error_ = BalsaFrameEnums::CHUNK_LENGTH_OVERFLOW;
                visitor_->ProcessBodyInput(on_entry, current - on_entry);
                visitor_->HandleChunkingError(this);
                goto bottom;
              }
              chunk_length_remaining_ = length_x_16 + addition;
              continue;
            }

            if (!chunk_length_character_extracted_ || addition == -1) {
              // ^[0-9;A-Fa-f][ \t\n] -- was not matched, either because no
              // characters were converted, or an unexpected character was
              // seen.
              parse_state_ = BalsaFrameEnums::PARSE_ERROR;
              last_error_ = BalsaFrameEnums::INVALID_CHUNK_LENGTH;
              visitor_->ProcessBodyInput(on_entry, current - on_entry);
              visitor_->HandleChunkingError(this);
              goto bottom;
            }

            --current;
            parse_state_ = BalsaFrameEnums::READING_CHUNK_EXTENSION;
            visitor_->ProcessChunkLength(chunk_length_remaining_);
            goto label_reading_chunk_extension;
          }
        }
        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;
            }

            ++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_->ProcessBodyInput(on_entry, current - on_entry);
        goto bottom;  // case BalsaFrameEnums::READING_CHUNK_EXTENSION

 label_reading_chunk_data:
      case BalsaFrameEnums::READING_CHUNK_DATA:
        while (current < end) {
          if (chunk_length_remaining_ == 0) {
            break;
          }
          // read in the chunk
          size_t bytes_remaining = end - current;
          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);
          on_entry = current = tmp_current;
          chunk_length_remaining_ -= consumed_bytes;
        }
        if (chunk_length_remaining_ == 0) {
          parse_state_ = BalsaFrameEnums::READING_CHUNK_TERM;
          goto label_reading_chunk_term;
        }
        visitor_->ProcessBodyInput(on_entry, current - on_entry);
        goto bottom;  // case BalsaFrameEnums::READING_CHUNK_DATA

 label_reading_chunk_term:
      case BalsaFrameEnums::READING_CHUNK_TERM:
        while (current < end) {
          const char c = *current;
          ++current;

          if (c == '\n') {
            parse_state_ = BalsaFrameEnums::READING_CHUNK_LENGTH;
            goto label_reading_chunk_length;
          }
        }
        visitor_->ProcessBodyInput(on_entry, current - on_entry);
        goto bottom;  // case BalsaFrameEnums::READING_CHUNK_TERM

 label_reading_last_chunk_term:
      case BalsaFrameEnums::READING_LAST_CHUNK_TERM:
        while (current < end) {
          const char c = *current;

          if (!HeaderFramingFound(c)) {
            // If not, however, since the spec only suggests that the
            // client SHOULD indicate the presence of trailers, we get to
            // *test* that they did or didn't.
            // If all of the bytes we've seen since:
            //   OPTIONAL_WS 0 OPTIONAL_STUFF CRLF
            // are either '\r', or '\n', then we can assume that we don't yet
            // know if we need to parse headers, or if the next byte will make
            // the HeaderFramingFound condition (above) true.
            if (HeaderFramingMayBeFound()) {
              // If true, then we have seen only characters '\r' or '\n'.
              ++current;

              // Lets try again! There is no state change here.
              continue;
            } else {
              // If (!HeaderFramingMayBeFound()), then we know that we must be
              // reading the first non CRLF character of a trailer.
              parse_state_ = BalsaFrameEnums::READING_TRAILER;
              visitor_->ProcessBodyInput(on_entry, current - on_entry);
              on_entry = current;
              goto label_reading_trailer;
            }
          } else {
            // If we've found a "\r\n\r\n", then the message
            // is done.
            ++current;
            parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
            visitor_->ProcessBodyInput(on_entry, current - on_entry);
            visitor_->MessageDone();
            goto bottom;
          }
          break;  // from while loop
        }
        visitor_->ProcessBodyInput(on_entry, current - on_entry);
        goto bottom;  // case BalsaFrameEnums::READING_LAST_CHUNK_TERM

 label_reading_trailer:
      case BalsaFrameEnums::READING_TRAILER:
        while (current < end) {
          const char c = *current;
          ++current;
          // TODO(fenix): If we ever care about trailers as part of framing,
          // deal with them here (see below for part of the 'solution')
          // if (LineFramingFound(c)) {
          // trailer_lines_.push_back(make_pair(start_of_line_,
          //                                   trailer_length_ - 1));
          // start_of_line_ = trailer_length_;
          // }
          if (HeaderFramingFound(c)) {
            // ProcessTrailers(visitor_, &trailers_);
            parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
            visitor_->ProcessTrailerInput(on_entry, current - on_entry);
            visitor_->MessageDone();
            goto bottom;
          }
        }
        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;
          }
        }
        goto bottom;  // case BalsaFrameEnums::READING_UNTIL_CLOSE

        // label_reading_content:
      case BalsaFrameEnums::READING_CONTENT:
#if DEBUGFRAMER
        LOG(INFO) << "ReadingContent: " << content_length_remaining_;
#endif  // DEBUGFRAMER
        while (content_length_remaining_ && current < end) {
          // 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;
          visitor_->ProcessBodyInput(current, consumed_bytes);
          visitor_->ProcessBodyData(current, consumed_bytes);
          current += consumed_bytes;
          content_length_remaining_ -= consumed_bytes;
        }
        if (content_length_remaining_ == 0) {
          parse_state_ = BalsaFrameEnums::MESSAGE_FULLY_READ;
          visitor_->MessageDone();
        }
        goto bottom;  // case BalsaFrameEnums::READING_CONTENT

      default:
        // The state-machine should never be in a state that isn't handled
        // 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
    }
  }
 bottom:
#if DEBUGFRAMER
  LOG(INFO) << "\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"
    << std::string(input, current)
    << "\n$$$$$$$$$$$$$$"
    << BalsaFrameEnums::ParseStateToString(parse_state_)
    << "$$$$$$$$$$$$$$$"
    << " consumed: " << (current - input);
  if (Error()) {
    LOG(INFO) << BalsaFrameEnums::ErrorCodeToString(ErrorCode());
  }
#endif  // DEBUGFRAMER
  return current - input;
}

}  // namespace net
