cmogstored 1.8.1 - use default system stack size
[cmogstored.git] / http_common.rl
blob97edff43fa0e6f1c57368506f7b98469ccf890e2
1 /*
2  * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
3  * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
4  */
5 %%{
6         machine http_common;
8         LWS = (' ' | '\t');
9         LF = '\n' > { http->_p.line_end = to_u16(fpc - buf); };
10         eor = LWS*'\r'LF;
11         CTL = (cntrl | 127);
12         header_name = [a-zA-Z0-9\-]+;
13         header_value = (any -- CTL)*;
14         sep = (LWS*)|(eor LWS+);
15         b64_val = ([a-zA-Z0-9/+]{22}) > {
16                         http->_p.tmp_tip = to_u16(fpc - buf);
17                 }
18                 "=="
19                 eor > {
20                         uint16_t tmp_end = to_u16(fpc - buf);
21                         char *in = buf + http->_p.tmp_tip;
22                         size_t inlen = tmp_end - http->_p.tmp_tip;
23                         char *out = (char *)http->expect_md5;
24                         size_t outlen = sizeof(http->expect_md5);
25                         bool rc;
27                         /*
28                          * Ragel already validated the allowable bytes,
29                          * so base64_decode_ctx must succeed:
30                          */
31                         rc = base64_decode_ctx(NULL, in, inlen, out, &outlen);
32                         assert(rc == true && outlen == 16
33                                && "base64_decoder broke for HTTP");
34                         http->_p.has_md5 = 1;
35                 };
36         content_md5 = "Content-MD5:"i sep ( b64_val ) $! {
37                                 if (!http->_p.has_md5) {
38                                         errno = EINVAL;
39                                         fbreak;
40                                 }
41                         };
42         ignored_trailer := header_name ':' sep header_value eor @ {
43                 fgoto more_trailers;
44         };
45         trailer_line = ( content_md5 ) $!
46                 {
47                         if (http->_p.line_end > 0) {
48                                 assert(buf[http->_p.line_end] == '\n'
49                                        && "bad http->_p.line_end");
50                                 p = buf + http->_p.line_end + 1;
51                         } else {
52                                 p = buf;
53                         }
54                         assert(p <= pe && "overflow");
55                         fgoto ignored_trailer;
56                 };
57         trailers = trailer_line* '\r''\n' > {
58                 http->_p.chunk_state = MOG_CHUNK_STATE_DONE;
59                 http->_p.line_end = to_u16(fpc - buf);
60                 really_done = 1;
61                 fbreak;
62         };
63         more_trailers := trailers;
64 }%%