1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#include "internal.h"
//
// header value parser
//
fhp_err_t
fhp_header_value_parser_init(fhp_t * const fhp) {
uint32_t hash = fhp->header_name_hash;
fhp_header_value_parser_t parser = FHP_HEADER_VALUE_PARSER_NONE;
fhp_err_t err;
/* fprintf(
stderr,
"hashes: header = %u, env = %u, str = %u, str(lc) = %u\n",
hash,
fhp->env->hashes[FHP_STR_TRANSFER_ENCODING],
fhp_hash_string("Transfer-Encoding"),
fhp_lc_hash_string("Transfer-Encoding")
); */
if (hash == fhp->env->hashes[FHP_STR_TRANSFER_ENCODING]) {
// set parser type
parser = FHP_HEADER_VALUE_PARSER_TRANSFER_ENCODING;
// init parser
if ((err = fhp_te_parser_init(&(fhp->parsers.te))) != FHP_OK)
return err;
} else if (hash == fhp->env->hashes[FHP_STR_CONTENT_LENGTH]) {
// set parser type
parser = FHP_HEADER_VALUE_PARSER_CONTENT_LENGTH;
// init parser
if ((err = fhp_cl_parser_init(&(fhp->parsers.cl))) != FHP_OK)
return err;
} else {
// set default parser type
parser = FHP_HEADER_VALUE_PARSER_NONE;
}
// set value parser
fhp->header_value_parser = parser;
// return success
return FHP_OK;
}
fhp_err_t
fhp_header_value_parser_push(
fhp_t * const fhp,
uint8_t * const buf,
size_t len
) {
fhp_err_t r = FHP_OK;
switch (fhp->header_value_parser) {
case FHP_HEADER_VALUE_PARSER_TRANSFER_ENCODING:
r = fhp_te_parser_push(&(fhp->parsers.te), buf, len);
break;
case FHP_HEADER_VALUE_PARSER_CONTENT_LENGTH:
r = fhp_cl_parser_push(&(fhp->parsers.cl), buf, len);
break;
default:
// do nothing
r = FHP_OK;
break;
}
// return result
return r;
}
fhp_err_t
fhp_header_value_parser_done(fhp_t * const fhp) {
fhp_err_t r = FHP_OK;
switch (fhp->header_value_parser) {
case FHP_HEADER_VALUE_PARSER_TRANSFER_ENCODING:
// finish parsing tes
if ((r = fhp_te_parser_done(&(fhp->parsers.te), &(fhp->num_tes))) != FHP_OK)
return r;
// check number of tes
if (fhp->num_tes > FHP_MAX_TRANSFER_ENCODINGS)
return FHP_ERR_TOO_MANY_TES;
// copy tes to context
if ((r = fhp_te_parser_get_tes(&(fhp->parsers.te), fhp->tes, FHP_MAX_TRANSFER_ENCODINGS)) != FHP_OK)
return r;
// notify callback
if (!fhp->cb(fhp, FHP_TOKEN_HEADER_TRANSFER_ENCODING, 0, 0))
return FHP_ERR_CB;
break;
case FHP_HEADER_VALUE_PARSER_CONTENT_LENGTH:
// finish parsing content-length and copy to context
if ((r = fhp_cl_parser_done(&(fhp->parsers.cl), &(fhp->content_length))) != FHP_OK)
return r;
// notify callback
if (!fhp->cb(fhp, FHP_TOKEN_HEADER_CONTENT_LENGTH, 0, 0))
return FHP_ERR_CB;
break;
default:
// do nothing
r = FHP_OK;
break;
}
// clear header value parser
fhp->header_value_parser = FHP_HEADER_VALUE_PARSER_NONE;
// return result
return r;
}
|