// 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. #ifndef NET_TOOLS_BALSA_BALSA_ENUMS_H_ #define NET_TOOLS_BALSA_BALSA_ENUMS_H_ namespace net { struct BalsaFrameEnums { enum ParseState { PARSE_ERROR, READING_HEADER_AND_FIRSTLINE, READING_CHUNK_LENGTH, READING_CHUNK_EXTENSION, READING_CHUNK_DATA, READING_CHUNK_TERM, READING_LAST_CHUNK_TERM, READING_TRAILER, READING_UNTIL_CLOSE, READING_CONTENT, MESSAGE_FULLY_READ, NUM_STATES, }; enum ErrorCode { #if defined(_WIN32) // On Windows, defines the NO_ERROR macro as 0L, which // breaks the compilation of the "NO_ERROR = 0" line. #undef NO_ERROR #endif NO_ERROR = 0, // A sentinel value for convenience, none of the callbacks // should ever see this error code. // Header parsing errors // Note that adding one to many of the REQUEST errors yields the // appropriate RESPONSE error. // Particularly, when parsing the first line of a request or response, // there are three sequences of non-whitespace regardless of whether or // not it is a request or response. These are listed below, in order. // // firstline_a firstline_b firstline_c // REQ: method request_uri version // RESP: version statuscode reason // // As you can see, the first token is the 'method' field for a request, // and 'version' field for a response. We call the first non whitespace // token firstline_a, the second firstline_b, and the third token // followed by [^\r\n]*) firstline_c. // // This organization is important, as it lets us determine the error code // to use without a branch based on is_response. Instead, we simply add // is_response to the response error code-- If is_response is true, then // we'll get the response error code, thanks to the fact that the error // code numbers are organized to ensure that response error codes always // precede request error codes. // | Triggered // | while processing // | this NONWS // | sequence... NO_STATUS_LINE_IN_RESPONSE, // | NO_REQUEST_LINE_IN_REQUEST, // | FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION, // | firstline_a FAILED_TO_FIND_WS_AFTER_REQUEST_METHOD, // | firstline_a FAILED_TO_FIND_WS_AFTER_RESPONSE_STATUSCODE, // | firstline_b FAILED_TO_FIND_WS_AFTER_REQUEST_REQUEST_URI, // | firstline_b FAILED_TO_FIND_NL_AFTER_RESPONSE_REASON_PHRASE, // | firstline_c FAILED_TO_FIND_NL_AFTER_REQUEST_HTTP_VERSION, // | firstline_c FAILED_CONVERTING_STATUS_CODE_TO_INT, REQUEST_URI_TOO_LONG, // Request URI greater than kMaxUrlLen. HEADERS_TOO_LONG, UNPARSABLE_CONTENT_LENGTH, // Warning: there may be a body but there was no content-length/chunked // encoding MAYBE_BODY_BUT_NO_CONTENT_LENGTH, // This is used if a body is required for a request. REQUIRED_BODY_BUT_NO_CONTENT_LENGTH, HEADER_MISSING_COLON, // Chunking errors INVALID_CHUNK_LENGTH, CHUNK_LENGTH_OVERFLOW, // Other errors. CALLED_BYTES_SPLICED_WHEN_UNSAFE_TO_DO_SO, CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT, MULTIPLE_CONTENT_LENGTH_KEYS, MULTIPLE_TRANSFER_ENCODING_KEYS, UNKNOWN_TRANSFER_ENCODING, INVALID_HEADER_FORMAT, // A detected internal inconsistency was found. INTERNAL_LOGIC_ERROR, NUM_ERROR_CODES }; static const char* ParseStateToString(ParseState error_code); static const char* ErrorCodeToString(ErrorCode error_code); }; struct BalsaHeadersEnums { enum ContentLengthStatus { INVALID_CONTENT_LENGTH, CONTENT_LENGTH_OVERFLOW, NO_CONTENT_LENGTH, VALID_CONTENT_LENGTH, }; }; } // namespace net #endif // NET_TOOLS_BALSA_BALSA_ENUMS_H_