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
| | /*
* Copyright (C) 2012-2013, Eric Wong <normalperson@yhbt.net>
* License: GPLv3 or later (see COPYING for details)
*/
%%{
machine http_common;
LWS = (' ' | '\t');
LF = '\n' > { http->_p.line_end = to_u16(fpc - buf); };
eor = LWS*'\r'LF;
CTL = (cntrl | 127);
header_name = [a-zA-Z0-9\-]+;
header_value = (any -- (LWS|CTL))(any -- CTL)*;
sep = (LWS*)|(eor LWS+);
b64_val = ([a-zA-Z0-9/+]{22}) > {
http->_p.tmp_tip = to_u16(fpc - buf);
}
"=="
eor > {
uint16_t tmp_end = to_u16(fpc - buf);
char *in = buf + http->_p.tmp_tip;
size_t inlen = tmp_end - http->_p.tmp_tip;
char *out = (char *)http->expect_md5;
size_t outlen = sizeof(http->expect_md5);
bool rc;
/*
* Ragel already validated the allowable bytes,
* so base64_decode_ctx must succeed:
*/
rc = base64_decode_ctx(NULL, in, inlen, out, &outlen);
assert(rc == true && outlen == 16
&& "base64_decoder broke for HTTP");
http->_p.has_md5 = 1;
};
content_md5 = "Content-MD5:"i sep ( b64_val ) $! {
if (!http->_p.has_md5) {
errno = EINVAL;
fbreak;
}
};
ignored_trailer := header_name ':' sep header_value eor @ {
fgoto more_trailers;
};
trailer_line = ( content_md5 ) $!
{
if (http->_p.line_end > 0) {
assert(buf[http->_p.line_end] == '\n'
&& "bad http->_p.line_end");
p = buf + http->_p.line_end + 1;
} else {
p = buf;
}
assert(p <= pe && "overflow");
fgoto ignored_trailer;
};
trailers = trailer_line* '\r''\n' > {
http->_p.chunk_state = MOG_CHUNK_STATE_DONE;
http->_p.line_end = to_u16(fpc - buf);
really_done = 1;
fbreak;
};
more_trailers := trailers;
}%%
|