summaryrefslogtreecommitdiff
path: root/fhp.c
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2016-08-28 00:37:50 -0400
committerPaul Duncan <pabs@pablotron.org>2016-08-28 00:37:50 -0400
commit0089842c454e51367a10dd86856cca8884bd2f01 (patch)
tree22837d11a1c7776f38b77ab487cbf2f759380e01 /fhp.c
parent14b04c962ee670e459f3e829e701da7fe1e57048 (diff)
downloadlibfhp-0089842c454e51367a10dd86856cca8884bd2f01.tar.bz2
libfhp-0089842c454e51367a10dd86856cca8884bd2f01.zip
add internal.h and te-parser.c
Diffstat (limited to 'fhp.c')
-rw-r--r--fhp.c403
1 files changed, 1 insertions, 402 deletions
diff --git a/fhp.c b/fhp.c
index 917141d..a2ba7a2 100644
--- a/fhp.c
+++ b/fhp.c
@@ -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