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 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_ */
|