xref: /unit/src/nxt_http_parse.h (revision 1167)
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,
3867Svbart@nginx.com                                          u_char **pos, u_char *end);
3967Svbart@nginx.com 
4067Svbart@nginx.com     size_t                    offset;
4116Svbart@nginx.com 
4267Svbart@nginx.com     nxt_str_t                 method;
4316Svbart@nginx.com 
4467Svbart@nginx.com     u_char                    *target_start;
4567Svbart@nginx.com     u_char                    *target_end;
4667Svbart@nginx.com     u_char                    *exten_start;
4767Svbart@nginx.com     u_char                    *args_start;
4816Svbart@nginx.com 
49112Smax.romanov@nginx.com     nxt_str_t                 path;
50112Smax.romanov@nginx.com     nxt_str_t                 args;
51112Smax.romanov@nginx.com     nxt_str_t                 exten;
52112Smax.romanov@nginx.com 
5367Svbart@nginx.com     nxt_http_ver_t            version;
5467Svbart@nginx.com 
55417Svbart@nginx.com     nxt_list_t                *fields;
56417Svbart@nginx.com     nxt_mp_t                  *mem_pool;
5716Svbart@nginx.com 
5867Svbart@nginx.com     nxt_str_t                 field_name;
5967Svbart@nginx.com     nxt_str_t                 field_value;
6016Svbart@nginx.com 
61417Svbart@nginx.com     uint32_t                  field_hash;
6216Svbart@nginx.com 
6316Svbart@nginx.com     /* target with "/." */
6467Svbart@nginx.com     unsigned                  complex_target:1;
6516Svbart@nginx.com     /* target with "%" */
6667Svbart@nginx.com     unsigned                  quoted_target:1;
6716Svbart@nginx.com     /* target with " " */
6867Svbart@nginx.com     unsigned                  space_in_target:1;
6916Svbart@nginx.com     /* target with "+" */
7067Svbart@nginx.com     unsigned                  plus_in_target:1;
71*1167Svbart@nginx.com 
72*1167Svbart@nginx.com     /* Preserve encoded '/' (%2F) and '%' (%25). */
73*1167Svbart@nginx.com     unsigned                  encoded_slashes:1;
7416Svbart@nginx.com };
7516Svbart@nginx.com 
7616Svbart@nginx.com 
7760Svbart@nginx.com typedef nxt_int_t (*nxt_http_field_handler_t)(void *ctx,
7860Svbart@nginx.com                                               nxt_http_field_t *field,
79417Svbart@nginx.com                                               uintptr_t data);
8060Svbart@nginx.com 
8160Svbart@nginx.com 
8216Svbart@nginx.com typedef struct {
8316Svbart@nginx.com     nxt_str_t                 name;
8416Svbart@nginx.com     nxt_http_field_handler_t  handler;
8516Svbart@nginx.com     uintptr_t                 data;
86417Svbart@nginx.com } nxt_http_field_proc_t;
8760Svbart@nginx.com 
8860Svbart@nginx.com 
8967Svbart@nginx.com struct nxt_http_field_s {
90417Svbart@nginx.com     uint16_t                  hash;
91417Svbart@nginx.com     uint8_t                   skip;             /* 1 bit */
92417Svbart@nginx.com     uint8_t                   name_length;
93417Svbart@nginx.com     uint32_t                  value_length;
94417Svbart@nginx.com     u_char                    *name;
95417Svbart@nginx.com     u_char                    *value;
9667Svbart@nginx.com };
9767Svbart@nginx.com 
9867Svbart@nginx.com 
991059Sigor@sysoev.ru #define NXT_HTTP_FIELD_HASH_INIT        159406U
1001059Sigor@sysoev.ru #define nxt_http_field_hash_char(h, c)  (((h) << 4) + (h) + (c))
1011059Sigor@sysoev.ru #define nxt_http_field_hash_end(h)      (((h) >> 16) ^ (h))
1021059Sigor@sysoev.ru 
1031059Sigor@sysoev.ru 
104417Svbart@nginx.com nxt_int_t nxt_http_parse_request_init(nxt_http_request_parse_t *rp,
105417Svbart@nginx.com     nxt_mp_t *mp);
10616Svbart@nginx.com nxt_int_t nxt_http_parse_request(nxt_http_request_parse_t *rp,
10716Svbart@nginx.com     nxt_buf_mem_t *b);
108422Svbart@nginx.com nxt_int_t nxt_http_parse_fields(nxt_http_request_parse_t *rp,
109422Svbart@nginx.com     nxt_buf_mem_t *b);
11060Svbart@nginx.com 
111417Svbart@nginx.com nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
112417Svbart@nginx.com     nxt_http_field_proc_t items[], nxt_uint_t count);
113417Svbart@nginx.com nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
114417Svbart@nginx.com     nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level);
115417Svbart@nginx.com nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
116417Svbart@nginx.com     void *ctx);
11716Svbart@nginx.com 
11816Svbart@nginx.com 
1191159Smax.romanov@nginx.com extern const nxt_lvlhsh_proto_t  nxt_http_fields_hash_proto;
1201126Smax.romanov@nginx.com 
1211126Smax.romanov@nginx.com nxt_inline nxt_int_t
1221126Smax.romanov@nginx.com nxt_http_field_process(nxt_http_field_t *field, nxt_lvlhsh_t *hash, void *ctx)
1231126Smax.romanov@nginx.com {
1241126Smax.romanov@nginx.com     nxt_lvlhsh_query_t     lhq;
1251126Smax.romanov@nginx.com     nxt_http_field_proc_t  *proc;
1261126Smax.romanov@nginx.com 
1271126Smax.romanov@nginx.com     lhq.proto = &nxt_http_fields_hash_proto;
1281126Smax.romanov@nginx.com 
1291126Smax.romanov@nginx.com     lhq.key_hash = field->hash;
1301126Smax.romanov@nginx.com     lhq.key.length = field->name_length;
1311126Smax.romanov@nginx.com     lhq.key.start = field->name;
1321126Smax.romanov@nginx.com 
1331126Smax.romanov@nginx.com     if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) {
1341126Smax.romanov@nginx.com         return NXT_OK;
1351126Smax.romanov@nginx.com     }
1361126Smax.romanov@nginx.com 
1371126Smax.romanov@nginx.com     proc = lhq.value;
1381126Smax.romanov@nginx.com 
1391126Smax.romanov@nginx.com     return proc->handler(ctx, field, proc->data);
1401126Smax.romanov@nginx.com }
1411126Smax.romanov@nginx.com 
1421126Smax.romanov@nginx.com 
14316Svbart@nginx.com #endif /* _NXT_HTTP_PARSER_H_INCLUDED_ */
144