xref: /unit/src/nxt_http_parse.h (revision 1505:d18f2b38596b)
1 
2 /*
3  * Copyright (C) NGINX, Inc.
4  * Copyright (C) Valentin V. Bartenev
5  */
6 
7 #ifndef _NXT_HTTP_PARSER_H_INCLUDED_
8 #define _NXT_HTTP_PARSER_H_INCLUDED_
9 
10 
11 typedef enum {
12     NXT_HTTP_PARSE_INVALID = 1,
13     NXT_HTTP_PARSE_UNSUPPORTED_VERSION,
14     NXT_HTTP_PARSE_TOO_LARGE_FIELD,
15 } nxt_http_parse_error_t;
16 
17 
18 typedef struct nxt_http_request_parse_s  nxt_http_request_parse_t;
19 typedef struct nxt_http_field_s          nxt_http_field_t;
20 typedef struct nxt_http_fields_hash_s    nxt_http_fields_hash_t;
21 
22 
23 typedef union {
24     u_char                    str[8];
25     uint64_t                  ui64;
26 
27     struct {
28         u_char                prefix[5];
29         u_char                major;
30         u_char                point;
31         u_char                minor;
32     } s;
33 } nxt_http_ver_t;
34 
35 
36 struct nxt_http_request_parse_s {
37     nxt_int_t                 (*handler)(nxt_http_request_parse_t *rp,
38                                          u_char **pos, u_char *end);
39 
40     nxt_str_t                 method;
41 
42     u_char                    *target_start;
43     u_char                    *target_end;
44 
45     nxt_str_t                 path;
46     nxt_str_t                 args;
47 
48     nxt_http_ver_t            version;
49 
50     nxt_list_t                *fields;
51     nxt_mp_t                  *mem_pool;
52 
53     nxt_str_t                 field_name;
54     nxt_str_t                 field_value;
55 
56     uint32_t                  field_hash;
57 
58     /* target with "/." */
59     uint8_t                   complex_target;   /* 1 bit */
60     /* target with "%" */
61     uint8_t                   quoted_target;    /* 1 bit */
62     /* target with " " */
63     uint8_t                   space_in_target;  /* 1 bit */
64 
65     /* Preserve encoded '/' (%2F) and '%' (%25). */
66     uint8_t                   encoded_slashes;  /* 1 bit */
67 };
68 
69 
70 typedef nxt_int_t (*nxt_http_field_handler_t)(void *ctx,
71                                               nxt_http_field_t *field,
72                                               uintptr_t data);
73 
74 
75 typedef struct {
76     nxt_str_t                 name;
77     nxt_http_field_handler_t  handler;
78     uintptr_t                 data;
79 } nxt_http_field_proc_t;
80 
81 
82 struct nxt_http_field_s {
83     uint16_t                  hash;
84     uint8_t                   skip:1;
85     uint8_t                   hopbyhop:1;
86     uint8_t                   name_length;
87     uint32_t                  value_length;
88     u_char                    *name;
89     u_char                    *value;
90 };
91 
92 
93 typedef struct {
94     u_char                    *pos;
95     nxt_mp_t                  *mem_pool;
96 
97     uint64_t                  chunk_size;
98 
99     uint8_t                   state;
100     uint8_t                   last;         /* 1 bit */
101     uint8_t                   chunk_error;  /* 1 bit */
102     uint8_t                   error;        /* 1 bit */
103 } nxt_http_chunk_parse_t;
104 
105 
106 #define NXT_HTTP_FIELD_HASH_INIT        159406U
107 #define nxt_http_field_hash_char(h, c)  (((h) << 4) + (h) + (c))
108 #define nxt_http_field_hash_end(h)      (((h) >> 16) ^ (h))
109 
110 
111 nxt_int_t nxt_http_parse_request_init(nxt_http_request_parse_t *rp,
112     nxt_mp_t *mp);
113 nxt_int_t nxt_http_parse_request(nxt_http_request_parse_t *rp,
114     nxt_buf_mem_t *b);
115 nxt_int_t nxt_http_parse_fields(nxt_http_request_parse_t *rp,
116     nxt_buf_mem_t *b);
117 
118 nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash,
119     nxt_http_field_proc_t items[], nxt_uint_t count);
120 nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash,
121     nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level);
122 nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
123     void *ctx);
124 
125 nxt_buf_t *nxt_http_chunk_parse(nxt_task_t *task, nxt_http_chunk_parse_t *hcp,
126     nxt_buf_t *in);
127 
128 
129 extern const nxt_lvlhsh_proto_t  nxt_http_fields_hash_proto;
130 
131 nxt_inline nxt_int_t
132 nxt_http_field_process(nxt_http_field_t *field, nxt_lvlhsh_t *hash, void *ctx)
133 {
134     nxt_lvlhsh_query_t     lhq;
135     nxt_http_field_proc_t  *proc;
136 
137     lhq.proto = &nxt_http_fields_hash_proto;
138 
139     lhq.key_hash = field->hash;
140     lhq.key.length = field->name_length;
141     lhq.key.start = field->name;
142 
143     if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) {
144         return NXT_OK;
145     }
146 
147     proc = lhq.value;
148 
149     return proc->handler(ctx, field, proc->data);
150 }
151 
152 
153 #endif /* _NXT_HTTP_PARSER_H_INCLUDED_ */
154