#include "internal.h" // // header value parser // fhp_err_t fhp_header_value_parser_init(fhp_t * const fhp) { uint32_t hash = fhp->header_name_hash; fhp_header_value_parser_t parser = FHP_HEADER_VALUE_PARSER_NONE; fhp_err_t err; /* fprintf( stderr, "hashes: header = %u, env = %u, str = %u, str(lc) = %u\n", hash, fhp->env->hashes[FHP_STR_TRANSFER_ENCODING], fhp_hash_string("Transfer-Encoding"), fhp_lc_hash_string("Transfer-Encoding") ); */ if (hash == fhp->env->hashes[FHP_STR_TRANSFER_ENCODING]) { // set parser type parser = FHP_HEADER_VALUE_PARSER_TRANSFER_ENCODING; // init parser if ((err = fhp_te_parser_init(&(fhp->parsers.te))) != FHP_OK) return err; } else if (hash == fhp->env->hashes[FHP_STR_CONTENT_LENGTH]) { // set parser type parser = FHP_HEADER_VALUE_PARSER_CONTENT_LENGTH; // init parser if ((err = fhp_cl_parser_init(&(fhp->parsers.cl))) != FHP_OK) return err; } else { // set default parser type parser = FHP_HEADER_VALUE_PARSER_NONE; } // set value parser fhp->header_value_parser = parser; // return success return FHP_OK; } fhp_err_t fhp_header_value_parser_push( fhp_t * const fhp, uint8_t * const buf, size_t len ) { fhp_err_t r = FHP_OK; switch (fhp->header_value_parser) { case FHP_HEADER_VALUE_PARSER_TRANSFER_ENCODING: r = fhp_te_parser_push(&(fhp->parsers.te), buf, len); break; case FHP_HEADER_VALUE_PARSER_CONTENT_LENGTH: r = fhp_cl_parser_push(&(fhp->parsers.cl), buf, len); break; default: // do nothing r = FHP_OK; break; } // return result return r; } fhp_err_t fhp_header_value_parser_done(fhp_t * const fhp) { fhp_err_t r = FHP_OK; switch (fhp->header_value_parser) { case FHP_HEADER_VALUE_PARSER_TRANSFER_ENCODING: // finish parsing tes if ((r = fhp_te_parser_done(&(fhp->parsers.te), &(fhp->num_tes))) != FHP_OK) return r; // check number of tes if (fhp->num_tes > FHP_MAX_TRANSFER_ENCODINGS) return FHP_ERR_TOO_MANY_TES; // copy tes to context if ((r = fhp_te_parser_get_tes(&(fhp->parsers.te), fhp->tes, FHP_MAX_TRANSFER_ENCODINGS)) != FHP_OK) return r; // notify callback if (!fhp->cb(fhp, FHP_TOKEN_HEADER_TRANSFER_ENCODING, 0, 0)) return FHP_ERR_CB; break; case FHP_HEADER_VALUE_PARSER_CONTENT_LENGTH: // finish parsing content-length and copy to context if ((r = fhp_cl_parser_done(&(fhp->parsers.cl), &(fhp->content_length))) != FHP_OK) return r; // notify callback if (!fhp->cb(fhp, FHP_TOKEN_HEADER_CONTENT_LENGTH, 0, 0)) return FHP_ERR_CB; break; default: // do nothing r = FHP_OK; break; } // clear header value parser fhp->header_value_parser = FHP_HEADER_VALUE_PARSER_NONE; // return result return r; }