1 // Copyright 2021 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_BALSA_BALSA_ENUMS_H_ 6 #define QUICHE_BALSA_BALSA_ENUMS_H_ 7 8 #include "quiche/common/platform/api/quiche_export.h" 9 10 namespace quiche { 11 12 struct QUICHE_EXPORT BalsaFrameEnums { 13 enum ParseState : int { 14 ERROR, 15 READING_HEADER_AND_FIRSTLINE, 16 READING_CHUNK_LENGTH, 17 READING_CHUNK_EXTENSION, 18 READING_CHUNK_DATA, 19 READING_CHUNK_TERM, 20 READING_LAST_CHUNK_TERM, 21 READING_TRAILER, 22 READING_UNTIL_CLOSE, 23 READING_CONTENT, 24 MESSAGE_FULLY_READ, 25 NUM_STATES, 26 }; 27 28 enum ErrorCode : int { 29 // A sentinel value for convenience, none of the callbacks should ever see 30 // this error code. 31 BALSA_NO_ERROR = 0, 32 33 // Header parsing errors 34 // Note that adding one to many of the REQUEST errors yields the 35 // appropriate RESPONSE error. 36 // Particularly, when parsing the first line of a request or response, 37 // there are three sequences of non-whitespace regardless of whether or 38 // not it is a request or response. These are listed below, in order. 39 // 40 // firstline_a firstline_b firstline_c 41 // REQ: method request_uri version 42 // RESP: version statuscode reason 43 // 44 // As you can see, the first token is the 'method' field for a request, 45 // and 'version' field for a response. We call the first non whitespace 46 // token firstline_a, the second firstline_b, and the third token 47 // followed by [^\r\n]*) firstline_c. 48 // 49 // This organization is important, as it lets us determine the error code 50 // to use without a branch based on is_response. Instead, we simply add 51 // is_response to the response error code-- If is_response is true, then 52 // we'll get the response error code, thanks to the fact that the error 53 // code numbers are organized to ensure that response error codes always 54 // precede request error codes. 55 // | Triggered 56 // | while processing 57 // | this NONWS 58 // | sequence... 59 NO_STATUS_LINE_IN_RESPONSE, // | 60 NO_REQUEST_LINE_IN_REQUEST, // | 61 FAILED_TO_FIND_WS_AFTER_RESPONSE_VERSION, // | firstline_a 62 FAILED_TO_FIND_WS_AFTER_REQUEST_METHOD, // | firstline_a 63 FAILED_TO_FIND_WS_AFTER_RESPONSE_STATUSCODE, // | firstline_b 64 FAILED_TO_FIND_WS_AFTER_REQUEST_REQUEST_URI, // | firstline_b 65 FAILED_TO_FIND_NL_AFTER_RESPONSE_REASON_PHRASE, // | firstline_c 66 FAILED_TO_FIND_NL_AFTER_REQUEST_HTTP_VERSION, // | firstline_c 67 68 FAILED_CONVERTING_STATUS_CODE_TO_INT, 69 70 HEADERS_TOO_LONG, 71 UNPARSABLE_CONTENT_LENGTH, 72 // Warning: there may be a body but there was no content-length/chunked 73 // encoding 74 MAYBE_BODY_BUT_NO_CONTENT_LENGTH, 75 76 // This is used if a body is required for a request. 77 REQUIRED_BODY_BUT_NO_CONTENT_LENGTH, 78 79 HEADER_MISSING_COLON, 80 81 // Chunking errors 82 INVALID_CHUNK_LENGTH, 83 CHUNK_LENGTH_OVERFLOW, 84 INVALID_CHUNK_EXTENSION, 85 86 // Other errors. 87 CALLED_BYTES_SPLICED_WHEN_UNSAFE_TO_DO_SO, 88 CALLED_BYTES_SPLICED_AND_EXCEEDED_SAFE_SPLICE_AMOUNT, 89 MULTIPLE_CONTENT_LENGTH_KEYS, 90 MULTIPLE_TRANSFER_ENCODING_KEYS, 91 UNKNOWN_TRANSFER_ENCODING, 92 BOTH_TRANSFER_ENCODING_AND_CONTENT_LENGTH, 93 INVALID_HEADER_FORMAT, 94 HTTP2_INVALID_HEADER_FORMAT, 95 HTTP2_CONTENT_LENGTH_ERROR, 96 97 // Trailer errors. 98 INVALID_TRAILER_FORMAT, 99 TRAILER_TOO_LONG, 100 TRAILER_MISSING_COLON, 101 102 // A detected internal inconsistency was found. 103 INTERNAL_LOGIC_ERROR, 104 105 // A control character was found in a header key or value 106 INVALID_HEADER_CHARACTER, 107 INVALID_HEADER_NAME_CHARACTER, 108 INVALID_TRAILER_NAME_CHARACTER, 109 110 // The client request included 'Expect: 100-continue' header on a protocol 111 // that doesn't support it. 112 UNSUPPORTED_100_CONTINUE, 113 114 NUM_ERROR_CODES 115 }; 116 static const char* ParseStateToString(ParseState error_code); 117 static const char* ErrorCodeToString(ErrorCode error_code); 118 }; 119 120 struct QUICHE_EXPORT BalsaHeadersEnums { 121 enum ContentLengthStatus : int { 122 INVALID_CONTENT_LENGTH, 123 CONTENT_LENGTH_OVERFLOW, 124 NO_CONTENT_LENGTH, 125 VALID_CONTENT_LENGTH, 126 }; 127 }; 128 129 } // namespace quiche 130 131 #endif // QUICHE_BALSA_BALSA_ENUMS_H_ 132