116Svbart@nginx.com 216Svbart@nginx.com /* 316Svbart@nginx.com * Copyright (C) NGINX, Inc. 416Svbart@nginx.com * Copyright (C) Valentin V. Bartenev 516Svbart@nginx.com */ 616Svbart@nginx.com 716Svbart@nginx.com #ifndef _NXT_HTTP_PARSER_H_INCLUDED_ 816Svbart@nginx.com #define _NXT_HTTP_PARSER_H_INCLUDED_ 916Svbart@nginx.com 1016Svbart@nginx.com 11480Svbart@nginx.com typedef enum { 12480Svbart@nginx.com NXT_HTTP_PARSE_INVALID = 1, 13482Svbart@nginx.com NXT_HTTP_PARSE_UNSUPPORTED_VERSION, 14480Svbart@nginx.com NXT_HTTP_PARSE_TOO_LARGE_FIELD, 15480Svbart@nginx.com } nxt_http_parse_error_t; 16480Svbart@nginx.com 17480Svbart@nginx.com 1816Svbart@nginx.com typedef struct nxt_http_request_parse_s nxt_http_request_parse_t; 1967Svbart@nginx.com typedef struct nxt_http_field_s nxt_http_field_t; 2016Svbart@nginx.com typedef struct nxt_http_fields_hash_s nxt_http_fields_hash_t; 2116Svbart@nginx.com 2260Svbart@nginx.com 2360Svbart@nginx.com typedef union { 24417Svbart@nginx.com u_char str[8]; 25417Svbart@nginx.com uint64_t ui64; 26481Svbart@nginx.com 27481Svbart@nginx.com struct { 28481Svbart@nginx.com u_char prefix[5]; 29481Svbart@nginx.com u_char major; 30481Svbart@nginx.com u_char point; 31481Svbart@nginx.com u_char minor; 32481Svbart@nginx.com } s; 3360Svbart@nginx.com } nxt_http_ver_t; 3416Svbart@nginx.com 3516Svbart@nginx.com 3616Svbart@nginx.com struct nxt_http_request_parse_s { 3767Svbart@nginx.com nxt_int_t (*handler)(nxt_http_request_parse_t *rp, 38*2139Sandrew@digital-domain.net u_char **pos, const u_char *end); 3967Svbart@nginx.com 4067Svbart@nginx.com nxt_str_t method; 4116Svbart@nginx.com 4267Svbart@nginx.com u_char *target_start; 4367Svbart@nginx.com u_char *target_end; 4416Svbart@nginx.com 45112Smax.romanov@nginx.com nxt_str_t path; 46112Smax.romanov@nginx.com nxt_str_t args; 47112Smax.romanov@nginx.com 4867Svbart@nginx.com nxt_http_ver_t version; 4967Svbart@nginx.com 50417Svbart@nginx.com nxt_list_t *fields; 51417Svbart@nginx.com nxt_mp_t *mem_pool; 5216Svbart@nginx.com 5367Svbart@nginx.com nxt_str_t field_name; 5467Svbart@nginx.com nxt_str_t field_value; 5516Svbart@nginx.com 56417Svbart@nginx.com uint32_t field_hash; 5716Svbart@nginx.com 581709Svbart@nginx.com uint8_t skip_field; /* 1 bit */ 591709Svbart@nginx.com uint8_t discard_unsafe_fields; /* 1 bit */ 601709Svbart@nginx.com 6116Svbart@nginx.com /* target with "/." */ 621709Svbart@nginx.com uint8_t complex_target; /* 1 bit */ 631709Svbart@nginx.com #if 0 6416Svbart@nginx.com /* target with "%" */ 651709Svbart@nginx.com uint8_t quoted_target; /* 1 bit */ 6616Svbart@nginx.com /* target with " " */ 671709Svbart@nginx.com uint8_t space_in_target; /* 1 bit */ 681709Svbart@nginx.com #endif 691167Svbart@nginx.com /* Preserve encoded '/' (%2F) and '%' (%25). */ 701709Svbart@nginx.com uint8_t encoded_slashes; /* 1 bit */ 7116Svbart@nginx.com }; 7216Svbart@nginx.com 7316Svbart@nginx.com 7460Svbart@nginx.com typedef nxt_int_t (*nxt_http_field_handler_t)(void *ctx, 7560Svbart@nginx.com nxt_http_field_t *field, 76417Svbart@nginx.com uintptr_t data); 7760Svbart@nginx.com 7860Svbart@nginx.com 7916Svbart@nginx.com typedef struct { 8016Svbart@nginx.com nxt_str_t name; 8116Svbart@nginx.com nxt_http_field_handler_t handler; 8216Svbart@nginx.com uintptr_t data; 83417Svbart@nginx.com } nxt_http_field_proc_t; 8460Svbart@nginx.com 8560Svbart@nginx.com 8667Svbart@nginx.com struct nxt_http_field_s { 87417Svbart@nginx.com uint16_t hash; 881270Sigor@sysoev.ru uint8_t skip:1; 891270Sigor@sysoev.ru uint8_t hopbyhop:1; 90417Svbart@nginx.com uint8_t name_length; 91417Svbart@nginx.com uint32_t value_length; 92417Svbart@nginx.com u_char *name; 93417Svbart@nginx.com u_char *value; 9467Svbart@nginx.com }; 9567Svbart@nginx.com 9667Svbart@nginx.com 971505Sigor@sysoev.ru typedef struct { 981505Sigor@sysoev.ru u_char *pos; 991505Sigor@sysoev.ru nxt_mp_t *mem_pool; 1001505Sigor@sysoev.ru 1011505Sigor@sysoev.ru uint64_t chunk_size; 1021505Sigor@sysoev.ru 1031505Sigor@sysoev.ru uint8_t state; 1041505Sigor@sysoev.ru uint8_t last; /* 1 bit */ 1051505Sigor@sysoev.ru uint8_t chunk_error; /* 1 bit */ 1061505Sigor@sysoev.ru uint8_t error; /* 1 bit */ 1071505Sigor@sysoev.ru } nxt_http_chunk_parse_t; 1081505Sigor@sysoev.ru 1091505Sigor@sysoev.ru 1101059Sigor@sysoev.ru #define NXT_HTTP_FIELD_HASH_INIT 159406U 1111059Sigor@sysoev.ru #define nxt_http_field_hash_char(h, c) (((h) << 4) + (h) + (c)) 1121059Sigor@sysoev.ru #define nxt_http_field_hash_end(h) (((h) >> 16) ^ (h)) 1131059Sigor@sysoev.ru 1141059Sigor@sysoev.ru 115417Svbart@nginx.com nxt_int_t nxt_http_parse_request_init(nxt_http_request_parse_t *rp, 116417Svbart@nginx.com nxt_mp_t *mp); 11716Svbart@nginx.com nxt_int_t nxt_http_parse_request(nxt_http_request_parse_t *rp, 11816Svbart@nginx.com nxt_buf_mem_t *b); 119422Svbart@nginx.com nxt_int_t nxt_http_parse_fields(nxt_http_request_parse_t *rp, 120422Svbart@nginx.com nxt_buf_mem_t *b); 12160Svbart@nginx.com 1221459Smax.romanov@nginx.com nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash, 123417Svbart@nginx.com nxt_http_field_proc_t items[], nxt_uint_t count); 1241459Smax.romanov@nginx.com nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, 125417Svbart@nginx.com nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level); 126417Svbart@nginx.com nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash, 127417Svbart@nginx.com void *ctx); 12816Svbart@nginx.com 1291505Sigor@sysoev.ru nxt_buf_t *nxt_http_chunk_parse(nxt_task_t *task, nxt_http_chunk_parse_t *hcp, 1301505Sigor@sysoev.ru nxt_buf_t *in); 1311505Sigor@sysoev.ru 13216Svbart@nginx.com 1331159Smax.romanov@nginx.com extern const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto; 1341126Smax.romanov@nginx.com 1351126Smax.romanov@nginx.com nxt_inline nxt_int_t 1361126Smax.romanov@nginx.com nxt_http_field_process(nxt_http_field_t *field, nxt_lvlhsh_t *hash, void *ctx) 1371126Smax.romanov@nginx.com { 1381126Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq; 1391126Smax.romanov@nginx.com nxt_http_field_proc_t *proc; 1401126Smax.romanov@nginx.com 1411126Smax.romanov@nginx.com lhq.proto = &nxt_http_fields_hash_proto; 1421126Smax.romanov@nginx.com 1431126Smax.romanov@nginx.com lhq.key_hash = field->hash; 1441126Smax.romanov@nginx.com lhq.key.length = field->name_length; 1451126Smax.romanov@nginx.com lhq.key.start = field->name; 1461126Smax.romanov@nginx.com 1471126Smax.romanov@nginx.com if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) { 1481126Smax.romanov@nginx.com return NXT_OK; 1491126Smax.romanov@nginx.com } 1501126Smax.romanov@nginx.com 1511126Smax.romanov@nginx.com proc = lhq.value; 1521126Smax.romanov@nginx.com 1531126Smax.romanov@nginx.com return proc->handler(ctx, field, proc->data); 1541126Smax.romanov@nginx.com } 1551126Smax.romanov@nginx.com 1561126Smax.romanov@nginx.com 15716Svbart@nginx.com #endif /* _NXT_HTTP_PARSER_H_INCLUDED_ */ 158