nxt_http_parse.h (1159:7c1765e01a4e) nxt_http_parse.h (1167:a49ee872e83d)
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
11typedef 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
18typedef struct nxt_http_request_parse_s nxt_http_request_parse_t;
19typedef struct nxt_http_field_s nxt_http_field_t;
20typedef struct nxt_http_fields_hash_s nxt_http_fields_hash_t;
21
22
23typedef 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
36struct 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 size_t offset;
41
42 nxt_str_t method;
43
44 u_char *target_start;
45 u_char *target_end;
46 u_char *exten_start;
47 u_char *args_start;
48
49 nxt_str_t path;
50 nxt_str_t args;
51 nxt_str_t exten;
52
53 nxt_http_ver_t version;
54
55 nxt_list_t *fields;
56 nxt_mp_t *mem_pool;
57
58 nxt_str_t field_name;
59 nxt_str_t field_value;
60
61 uint32_t field_hash;
62
63 /* target with "/." */
64 unsigned complex_target:1;
65 /* target with "%" */
66 unsigned quoted_target:1;
67 /* target with " " */
68 unsigned space_in_target:1;
69 /* target with "+" */
70 unsigned plus_in_target:1;
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
11typedef 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
18typedef struct nxt_http_request_parse_s nxt_http_request_parse_t;
19typedef struct nxt_http_field_s nxt_http_field_t;
20typedef struct nxt_http_fields_hash_s nxt_http_fields_hash_t;
21
22
23typedef 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
36struct 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 size_t offset;
41
42 nxt_str_t method;
43
44 u_char *target_start;
45 u_char *target_end;
46 u_char *exten_start;
47 u_char *args_start;
48
49 nxt_str_t path;
50 nxt_str_t args;
51 nxt_str_t exten;
52
53 nxt_http_ver_t version;
54
55 nxt_list_t *fields;
56 nxt_mp_t *mem_pool;
57
58 nxt_str_t field_name;
59 nxt_str_t field_value;
60
61 uint32_t field_hash;
62
63 /* target with "/." */
64 unsigned complex_target:1;
65 /* target with "%" */
66 unsigned quoted_target:1;
67 /* target with " " */
68 unsigned space_in_target:1;
69 /* target with "+" */
70 unsigned plus_in_target:1;
71
72 /* Preserve encoded '/' (%2F) and '%' (%25). */
73 unsigned encoded_slashes:1;
71};
72
73
74typedef nxt_int_t (*nxt_http_field_handler_t)(void *ctx,
75 nxt_http_field_t *field,
76 uintptr_t data);
77
78
79typedef struct {
80 nxt_str_t name;
81 nxt_http_field_handler_t handler;
82 uintptr_t data;
83} nxt_http_field_proc_t;
84
85
86struct nxt_http_field_s {
87 uint16_t hash;
88 uint8_t skip; /* 1 bit */
89 uint8_t name_length;
90 uint32_t value_length;
91 u_char *name;
92 u_char *value;
93};
94
95
96#define NXT_HTTP_FIELD_HASH_INIT 159406U
97#define nxt_http_field_hash_char(h, c) (((h) << 4) + (h) + (c))
98#define nxt_http_field_hash_end(h) (((h) >> 16) ^ (h))
99
100
101nxt_int_t nxt_http_parse_request_init(nxt_http_request_parse_t *rp,
102 nxt_mp_t *mp);
103nxt_int_t nxt_http_parse_request(nxt_http_request_parse_t *rp,
104 nxt_buf_mem_t *b);
105nxt_int_t nxt_http_parse_fields(nxt_http_request_parse_t *rp,
106 nxt_buf_mem_t *b);
107
108nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
109 nxt_http_field_proc_t items[], nxt_uint_t count);
110nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
111 nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level);
112nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
113 void *ctx);
114
115
116extern const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto;
117
118nxt_inline nxt_int_t
119nxt_http_field_process(nxt_http_field_t *field, nxt_lvlhsh_t *hash, void *ctx)
120{
121 nxt_lvlhsh_query_t lhq;
122 nxt_http_field_proc_t *proc;
123
124 lhq.proto = &nxt_http_fields_hash_proto;
125
126 lhq.key_hash = field->hash;
127 lhq.key.length = field->name_length;
128 lhq.key.start = field->name;
129
130 if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) {
131 return NXT_OK;
132 }
133
134 proc = lhq.value;
135
136 return proc->handler(ctx, field, proc->data);
137}
138
139
140#endif /* _NXT_HTTP_PARSER_H_INCLUDED_ */
74};
75
76
77typedef nxt_int_t (*nxt_http_field_handler_t)(void *ctx,
78 nxt_http_field_t *field,
79 uintptr_t data);
80
81
82typedef struct {
83 nxt_str_t name;
84 nxt_http_field_handler_t handler;
85 uintptr_t data;
86} nxt_http_field_proc_t;
87
88
89struct nxt_http_field_s {
90 uint16_t hash;
91 uint8_t skip; /* 1 bit */
92 uint8_t name_length;
93 uint32_t value_length;
94 u_char *name;
95 u_char *value;
96};
97
98
99#define NXT_HTTP_FIELD_HASH_INIT 159406U
100#define nxt_http_field_hash_char(h, c) (((h) << 4) + (h) + (c))
101#define nxt_http_field_hash_end(h) (((h) >> 16) ^ (h))
102
103
104nxt_int_t nxt_http_parse_request_init(nxt_http_request_parse_t *rp,
105 nxt_mp_t *mp);
106nxt_int_t nxt_http_parse_request(nxt_http_request_parse_t *rp,
107 nxt_buf_mem_t *b);
108nxt_int_t nxt_http_parse_fields(nxt_http_request_parse_t *rp,
109 nxt_buf_mem_t *b);
110
111nxt_int_t nxt_http_fields_hash(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
112 nxt_http_field_proc_t items[], nxt_uint_t count);
113nxt_uint_t nxt_http_fields_hash_collisions(nxt_lvlhsh_t *hash, nxt_mp_t *mp,
114 nxt_http_field_proc_t items[], nxt_uint_t count, nxt_bool_t level);
115nxt_int_t nxt_http_fields_process(nxt_list_t *fields, nxt_lvlhsh_t *hash,
116 void *ctx);
117
118
119extern const nxt_lvlhsh_proto_t nxt_http_fields_hash_proto;
120
121nxt_inline nxt_int_t
122nxt_http_field_process(nxt_http_field_t *field, nxt_lvlhsh_t *hash, void *ctx)
123{
124 nxt_lvlhsh_query_t lhq;
125 nxt_http_field_proc_t *proc;
126
127 lhq.proto = &nxt_http_fields_hash_proto;
128
129 lhq.key_hash = field->hash;
130 lhq.key.length = field->name_length;
131 lhq.key.start = field->name;
132
133 if (nxt_lvlhsh_find(hash, &lhq) != NXT_OK) {
134 return NXT_OK;
135 }
136
137 proc = lhq.value;
138
139 return proc->handler(ctx, field, proc->data);
140}
141
142
143#endif /* _NXT_HTTP_PARSER_H_INCLUDED_ */