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,
382139Sandrew@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;
442430Salx@nginx.com u_char *request_line_end;
4516Svbart@nginx.com
46112Smax.romanov@nginx.com nxt_str_t path;
47112Smax.romanov@nginx.com nxt_str_t args;
48112Smax.romanov@nginx.com
4967Svbart@nginx.com nxt_http_ver_t version;
5067Svbart@nginx.com
51417Svbart@nginx.com nxt_list_t *fields;
52417Svbart@nginx.com nxt_mp_t *mem_pool;
5316Svbart@nginx.com
5467Svbart@nginx.com nxt_str_t field_name;
5567Svbart@nginx.com nxt_str_t field_value;
5616Svbart@nginx.com
57417Svbart@nginx.com uint32_t field_hash;
5816Svbart@nginx.com
591709Svbart@nginx.com uint8_t skip_field; /* 1 bit */
601709Svbart@nginx.com uint8_t discard_unsafe_fields; /* 1 bit */
611709Svbart@nginx.com
6216Svbart@nginx.com /* target with "/." */
631709Svbart@nginx.com uint8_t complex_target; /* 1 bit */
641709Svbart@nginx.com #if 0
6516Svbart@nginx.com /* target with "%" */
661709Svbart@nginx.com uint8_t quoted_target; /* 1 bit */
6716Svbart@nginx.com /* target with " " */
681709Svbart@nginx.com uint8_t space_in_target; /* 1 bit */
691709Svbart@nginx.com #endif
701167Svbart@nginx.com /* Preserve encoded '/' (%2F) and '%' (%25). */
711709Svbart@nginx.com uint8_t encoded_slashes; /* 1 bit */
7216Svbart@nginx.com };
7316Svbart@nginx.com
7416Svbart@nginx.com
7560Svbart@nginx.com typedef nxt_int_t (*nxt_http_field_handler_t)(void *ctx,
7660Svbart@nginx.com nxt_http_field_t *field,
77417Svbart@nginx.com uintptr_t data);
7860Svbart@nginx.com
7960Svbart@nginx.com
8016Svbart@nginx.com typedef struct {
8116Svbart@nginx.com nxt_str_t name;
8216Svbart@nginx.com nxt_http_field_handler_t handler;
8316Svbart@nginx.com uintptr_t data;
84417Svbart@nginx.com } nxt_http_field_proc_t;
8560Svbart@nginx.com
8660Svbart@nginx.com
8767Svbart@nginx.com struct nxt_http_field_s {
88417Svbart@nginx.com uint16_t hash;
891270Sigor@sysoev.ru uint8_t skip:1;
901270Sigor@sysoev.ru uint8_t hopbyhop:1;
91417Svbart@nginx.com uint8_t name_length;
92417Svbart@nginx.com uint32_t value_length;
93417Svbart@nginx.com u_char *name;
94417Svbart@nginx.com u_char *value;
9567Svbart@nginx.com };
9667Svbart@nginx.com
9767Svbart@nginx.com
981505Sigor@sysoev.ru typedef struct {
991505Sigor@sysoev.ru u_char *pos;
1001505Sigor@sysoev.ru nxt_mp_t *mem_pool;
1011505Sigor@sysoev.ru
1021505Sigor@sysoev.ru uint64_t chunk_size;
1031505Sigor@sysoev.ru
1041505Sigor@sysoev.ru uint8_t state;
1051505Sigor@sysoev.ru uint8_t last; /* 1 bit */
1061505Sigor@sysoev.ru uint8_t chunk_error; /* 1 bit */
1071505Sigor@sysoev.ru uint8_t error; /* 1 bit */
1081505Sigor@sysoev.ru } nxt_http_chunk_parse_t;
1091505Sigor@sysoev.ru
1101505Sigor@sysoev.ru
1111059Sigor@sysoev.ru #define NXT_HTTP_FIELD_HASH_INIT 159406U
1121059Sigor@sysoev.ru #define nxt_http_field_hash_char(h, c) (((h) << 4) + (h) + (c))
1131059Sigor@sysoev.ru #define nxt_http_field_hash_end(h) (((h) >> 16) ^ (h))
1141059Sigor@sysoev.ru
1151059Sigor@sysoev.ru
116417Svbart@nginx.com nxt_int_t nxt_http_parse_request_init(nxt_http_request_parse_t *rp,
117417Svbart@nginx.com nxt_mp_t *mp);
11816Svbart@nginx.com nxt_int_t nxt_http_parse_request(nxt_http_request_parse_t *rp,
11916Svbart@nginx.com nxt_buf_mem_t *b);
120422Svbart@nginx.com nxt_int_t nxt_http_parse_fields(nxt_http_request_parse_t *rp,
121422Svbart@nginx.com nxt_buf_mem_t *b);
12260Svbart@nginx.com
1231459Smax.romanov@nginx.com nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash,
124417Svbart@nginx.com nxt_http_field_proc_t items[], nxt_uint_t count);
1251459Smax.romanov@nginx.com nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash,
126417Svbart@nginx.com nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level);
127417Svbart@nginx.com nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
128417Svbart@nginx.com void *ctx);
12916Svbart@nginx.com
130*2448Sz.hong@f5.com nxt_int_t nxt_http_parse_complex_target(nxt_http_request_parse_t *rp);
1311505Sigor@sysoev.ru nxt_buf_t *nxt_http_chunk_parse(nxt_task_t *task, nxt_http_chunk_parse_t *hcp,
1321505Sigor@sysoev.ru nxt_buf_t *in);
1331505Sigor@sysoev.ru
13416Svbart@nginx.com
1351159Smax.romanov@nginx.com extern const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto;
1361126Smax.romanov@nginx.com
1371126Smax.romanov@nginx.com nxt_inline nxt_int_t
nxt_http_field_process(nxt_http_field_t * field,nxt_lvlhsh_t * hash,void * ctx)1381126Smax.romanov@nginx.com nxt_http_field_process(nxt_http_field_t *field, nxt_lvlhsh_t *hash, void *ctx)
1391126Smax.romanov@nginx.com {
1401126Smax.romanov@nginx.com nxt_lvlhsh_query_t lhq;
1411126Smax.romanov@nginx.com nxt_http_field_proc_t *proc;
1421126Smax.romanov@nginx.com
1431126Smax.romanov@nginx.com lhq.proto = &nxt_http_fields_hash_proto;
1441126Smax.romanov@nginx.com
1451126Smax.romanov@nginx.com lhq.key_hash = field->hash;
1461126Smax.romanov@nginx.com lhq.key.length = field->name_length;
1471126Smax.romanov@nginx.com lhq.key.start = field->name;
1481126Smax.romanov@nginx.com
1491126Smax.romanov@nginx.com if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) {
1501126Smax.romanov@nginx.com return NXT_OK;
1511126Smax.romanov@nginx.com }
1521126Smax.romanov@nginx.com
1531126Smax.romanov@nginx.com proc = lhq.value;
1541126Smax.romanov@nginx.com
1551126Smax.romanov@nginx.com return proc->handler(ctx, field, proc->data);
1561126Smax.romanov@nginx.com }
1571126Smax.romanov@nginx.com
1581126Smax.romanov@nginx.com
15916Svbart@nginx.com #endif /* _NXT_HTTP_PARSER_H_INCLUDED_ */
160