diff options
Diffstat (limited to 'fhp.c')
-rw-r--r-- | fhp.c | 403 |
1 files changed, 1 insertions, 402 deletions
@@ -1,405 +1,4 @@ -#include <string.h> -#include "fhp/fhp.h" - -#define UNUSED(a) ((void) (a)) - -#define CASE_ALNUM_CHARS \ - case '0': \ - case '1': \ - case '2': \ - case '3': \ - case '4': \ - case '5': \ - case '6': \ - case '7': \ - case '8': \ - case '9': \ - case 'a': \ - case 'b': \ - case 'c': \ - case 'd': \ - case 'e': \ - case 'f': \ - case 'g': \ - case 'h': \ - case 'i': \ - case 'j': \ - case 'k': \ - case 'l': \ - case 'm': \ - case 'n': \ - case 'o': \ - case 'p': \ - case 'q': \ - case 'r': \ - case 's': \ - case 't': \ - case 'u': \ - case 'v': \ - case 'w': \ - case 'x': \ - case 'y': \ - case 'z': \ - case 'A': \ - case 'B': \ - case 'C': \ - case 'D': \ - case 'E': \ - case 'F': \ - case 'G': \ - case 'H': \ - case 'I': \ - case 'J': \ - case 'K': \ - case 'L': \ - case 'M': \ - case 'N': \ - case 'O': \ - case 'P': \ - case 'Q': \ - case 'R': \ - case 'S': \ - case 'T': \ - case 'U': \ - case 'V': \ - case 'W': \ - case 'X': \ - case 'Y': \ - case 'Z': - -#define CASE_DIGIT_CHARS \ - case '0': \ - case '1': \ - case '2': \ - case '3': \ - case '4': \ - case '5': \ - case '6': \ - case '7': \ - case '8': \ - case '9': - -#define CASE_HEX_ALPHA_CHARS \ - case 'a': \ - case 'b': \ - case 'c': \ - case 'd': \ - case 'e': \ - case 'f': \ - case 'A': \ - case 'B': \ - case 'C': \ - case 'D': \ - case 'E': \ - case 'F': - -// -// rfc7230, Appendix B -// https://tools.ietf.org/html/rfc7230 -// -// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / -// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA -// token = 1*tchar -// -#define CASE_TOKEN_CHARS \ - CASE_ALNUM_CHARS \ - case '!': \ - case '#': \ - case '$': \ - case '%': \ - case '&': \ - case '\'': \ - case '*': \ - case '+': \ - case '-': \ - case '.': \ - case '^': \ - case '_': \ - case '|': \ - case '~': \ - -#define CASE_URL_CHARS \ - CASE_ALNUM_CHARS \ - case '!': \ - case '"': \ - case '#': \ - case '$': \ - case '&': \ - case '\'': \ - case '(': \ - case ')': \ - case '*': \ - case '+': \ - case ',': \ - case '-': \ - case '.': \ - case '/': \ - case ':': \ - case ';': \ - case '<': \ - case '=': \ - case '>': \ - case '?': \ - case '@': \ - case '[': \ - case '\\': \ - case ']': \ - case '^': \ - case '_': \ - case '`': \ - case '{': \ - case '|': \ - case '}': \ - case '~': - -#define CASE_VISUAL_CHARS \ - CASE_URL_CHARS \ - case '%': - -#define CASE_VERSION_CHARS \ - CASE_TOKEN_CHARS \ - case '/': - -#define CASE_TE_CHARS \ - CASE_ALNUM_CHARS \ - case '-': - -// -// rfc7230, Appendix B -// https://tools.ietf.org/html/rfc7230 -// -// OWS = *( SP / HTAB ) -// -#define CASE_OWS_CHARS \ - case ' ': \ - case '\t': - -// -// strings -// - -typedef enum { - FHP_STR_GET, - FHP_STR_POST, - FHP_STR_HEAD, - FHP_STR_PUT, - FHP_STR_DELETE, - FHP_STR_OPTIONS, - FHP_STR_HTTP_10, - FHP_STR_HTTP_11, - FHP_STR_CONTENT_LENGTH, - FHP_STR_TRANSFER_ENCODING, - FHP_STR_GZIP, - FHP_STR_X_GZIP, - FHP_STR_DEFLATE, - FHP_STR_X_DEFLATE, - FHP_STR_COMPRESS, - FHP_STR_X_COMPRESS, - FHP_STR_CHUNKED, - FHP_STR_LAST -} fhp_str_t; - -// -// transfer encoding buffer functions -// - -static void -fhp_te_parser_buf_flush(fhp_te_parser_t * const te) { - te->buf_hash = fhp_lc_hash_push(te->buf_hash, te->buf, te->len); - te->len = 0; -} - -static void -fhp_te_parser_buf_push( - fhp_te_parser_t * const te, - uint8_t byte -) { - // flush buffer (if necessary) - if (te->len + 1 >= FHP_TE_MAX_BUF_SIZE) - fhp_te_parser_buf_flush(te); - - // push to buffer - te->buf[te->len] = byte; - te->len++; -} - -// -// transfer encoding parser functions -// - -static const fhp_te_parser_t FHP_DEFAULT_TE_PARSER = { - .state = FHP_TE_STATE_INIT, - .len = 0, - .num_tes = 0, - .err = FHP_OK, -}; - -fhp_err_t -fhp_te_parser_init(fhp_te_parser_t * const te) { - // init parser - *te = FHP_DEFAULT_TE_PARSER; - - // return succes - return FHP_OK; -} - -static fhp_err_t -fhp_te_parser_push_byte( - fhp_te_parser_t * const te, - uint8_t byte -) { -retry: - switch (te->state) { - case FHP_TE_STATE_INIT: - // set state - te->state = FHP_TE_STATE_SPACE; - goto retry; - - break; - case FHP_TE_STATE_NAME: - switch (byte) { - CASE_TE_CHARS - // add to buffer - fhp_te_parser_buf_push(te, byte); - - break; - CASE_OWS_CHARS - // flush buffer (if necessary) - if (te->len > 0) - fhp_te_parser_buf_flush(te); - - // check number of encodings - if (te->num_tes + 1 >= FHP_TE_MAX_TES) - return FHP_ERR_TOO_MANY_TES; - - // add to list of transfer encodings - // FIXME: check length - te->tes[te->num_tes] = te->buf_hash; - te->num_tes++; - - // set state - te->state = FHP_TE_STATE_IGNORE_UNTIL_COMMA; - - break; - case ',': - // flush buffer (if necessary) - if (te->len > 0) - fhp_te_parser_buf_flush(te); - - // check number of encodings - if (te->num_tes + 1 >= FHP_TE_MAX_TES) - return FHP_ERR_TOO_MANY_TES; - - // add to list of transfer encodings - // FIXME: check length - te->tes[te->num_tes] = te->buf_hash; - te->num_tes++; - - // set state - te->state = FHP_TE_STATE_SPACE; - - break; - default: - // invalid transfer encoding character - return FHP_ERR_INVALID_CHAR_IN_TE_NAME; - } - - break; - case FHP_TE_STATE_IGNORE_UNTIL_COMMA: - switch (byte) { - case ',': - // set state - te->state = FHP_TE_STATE_SPACE; - - break; - default: - // do nothing (ignore) - NULL; - } - - break; - case FHP_TE_STATE_SPACE: - switch (byte) { - CASE_OWS_CHARS - // ignore leading spaces - break; - CASE_TE_CHARS - // clear buffer, init hash - te->len = 0; - te->buf_hash = fhp_hash_init(); - - // set state - te->state = FHP_TE_STATE_NAME; - goto retry; - - break; - default: - // return error - return FHP_ERR_INVALID_CHAR_IN_TE; - } - - break; - case FHP_TE_STATE_ERROR: - // return last error - return te->err; - - break; - case FHP_TE_STATE_DONE: - // shouldn't be reached - return FHP_ERR_TE_PARSER_DONE; - - break; - default: - // never reached - return FHP_ERR_BAD_TE_STATE; - } - - // return succes - return FHP_OK; -} - -fhp_err_t -fhp_te_parser_push( - fhp_te_parser_t *te, - uint8_t * const buf, - size_t len -) { - for (size_t i = 0; i < len; i++) { - // push byte - fhp_err_t err = fhp_te_parser_push_byte(te, buf[len]); - - // check error - if (err != FHP_OK) { - // cache error - te->err = err; - - // set state - te->state = FHP_TE_STATE_ERROR; - - // return error - return err; - } - } - - // return succes - return FHP_OK; -} - -fhp_err_t -fhp_te_parser_done(fhp_te_parser_t * const te) { - uint8_t buf[1] = { 20 }; - - // flush data, check for error - fhp_err_t err = fhp_te_parser_push(te, buf, 1); - if (err != FHP_OK) - return err; - - // set state - te->state = FHP_TE_STATE_DONE; - - // return success - return FHP_OK; -} +#include "internal.h" // // context functions |