Mercurial > projects > dreactor
view dreactor/protocol/http11_parser.d @ 11:5836613d16ac
reorg! reorg!
author | rick@minifunk |
---|---|
date | Tue, 12 Aug 2008 16:59:56 -0400 |
parents | |
children |
line wrap: on
line source
module dreactor.protocol.http11_parser; //#line 1 "http11_parser.rl" /** * Copyright (c) 2005 Zed A. Shaw, * Modified for D by Rick Richardson, 2008 * You can redistribute it and/or modify it under the same terms as Ruby. */ alias void delegate (Object data, char[] buf) element_cb; alias void delegate (Object data, char[] field, char[] value) field_cb; class Http11Parser { private int cs; size_t body_start; int content_len; size_t nread; size_t mark; size_t field_start; size_t field_len; size_t query_start; Object data; field_cb http_field; element_cb request_method; element_cb request_uri; element_cb fragment; element_cb request_path; element_cb query_string; element_cb http_version; element_cb header_done; /* * capitalizes all lower-case ASCII characters, * converts dashes to underscores. */ private void snake_upcase_char(char *c) { if (*c >= 'a' && *c <= 'z') *c &= ~0x20; else if (*c == '-') *c = '_'; } //#define LEN(AT, FPC) (FPC - buffer - parser->AT) private size_t LEN(char[] buffer, size_t at, char* fpc) { return (fpc - buffer.ptr - at); } //#define MARK(M,FPC) (parser->M = (FPC) - buffer) private void MARK(char[] buffer, size_t* item, char* fpc) { *item = fpc - buffer.ptr; } /** Machine **/ //#line 126 "http11_parser.rl" /** Data **/ //#line 70 "http11_parser.d" static byte[] _http_parser_actions = [ 0, 1, 0, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 11, 1, 12, 1, 13, 2, 1, 2, 2, 10, 7, 2, 12, 7, 3, 9, 10, 7 ]; static short[] _http_parser_key_offsets = [ 0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36, 39, 41, 44, 45, 61, 62, 78, 80, 81, 90, 99, 105, 111, 121, 130, 136, 142, 153, 159, 165, 175, 181, 187, 196, 205, 211, 217, 226, 235, 244, 253, 262, 271, 280, 289, 298, 307, 316, 325, 334, 343, 352, 361, 370, 379, 380 ]; static char[] _http_parser_trans_keys = [ 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 42u, 43u, 47u, 58u, 45u, 57u, 65u, 90u, 97u, 122u, 32u, 35u, 72u, 84u, 84u, 80u, 47u, 48u, 57u, 46u, 48u, 57u, 48u, 57u, 13u, 48u, 57u, 10u, 13u, 33u, 124u, 126u, 35u, 39u, 42u, 43u, 45u, 46u, 48u, 57u, 65u, 90u, 94u, 122u, 10u, 33u, 58u, 124u, 126u, 35u, 39u, 42u, 43u, 45u, 46u, 48u, 57u, 65u, 90u, 94u, 122u, 13u, 32u, 13u, 32u, 37u, 60u, 62u, 127u, 0u, 31u, 34u, 35u, 32u, 37u, 60u, 62u, 127u, 0u, 31u, 34u, 35u, 48u, 57u, 65u, 70u, 97u, 102u, 48u, 57u, 65u, 70u, 97u, 102u, 43u, 58u, 45u, 46u, 48u, 57u, 65u, 90u, 97u, 122u, 32u, 34u, 35u, 37u, 60u, 62u, 127u, 0u, 31u, 48u, 57u, 65u, 70u, 97u, 102u, 48u, 57u, 65u, 70u, 97u, 102u, 32u, 34u, 35u, 37u, 59u, 60u, 62u, 63u, 127u, 0u, 31u, 48u, 57u, 65u, 70u, 97u, 102u, 48u, 57u, 65u, 70u, 97u, 102u, 32u, 34u, 35u, 37u, 60u, 62u, 63u, 127u, 0u, 31u, 48u, 57u, 65u, 70u, 97u, 102u, 48u, 57u, 65u, 70u, 97u, 102u, 32u, 34u, 35u, 37u, 60u, 62u, 127u, 0u, 31u, 32u, 34u, 35u, 37u, 60u, 62u, 127u, 0u, 31u, 48u, 57u, 65u, 70u, 97u, 102u, 48u, 57u, 65u, 70u, 97u, 102u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 36u, 95u, 45u, 46u, 48u, 57u, 65u, 90u, 32u, 0 ]; static byte[] _http_parser_single_lengths = [ 0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 4, 1, 4, 2, 1, 5, 5, 0, 0, 2, 7, 0, 0, 9, 0, 0, 8, 0, 0, 7, 7, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0 ]; static byte[] _http_parser_range_lengths = [ 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 6, 0, 6, 0, 0, 2, 2, 3, 3, 4, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0 ]; static short[] _http_parser_index_offsets = [ 0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36, 39, 41, 44, 46, 57, 59, 70, 73, 75, 83, 91, 95, 99, 106, 115, 119, 123, 134, 138, 142, 152, 156, 160, 169, 178, 182, 186, 193, 200, 207, 214, 221, 228, 235, 242, 249, 256, 263, 270, 277, 284, 291, 298, 305, 312, 314 ]; static byte[] _http_parser_indicies = [ 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 1, 4, 5, 6, 7, 5, 5, 5, 1, 8, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1, 16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27, 25, 26, 28, 29, 31, 1, 1, 1, 1, 1, 30, 29, 33, 1, 1, 1, 1, 1, 32, 34, 34, 34, 1, 32, 32, 32, 1, 35, 36, 35, 35, 35, 35, 1, 8, 1, 9, 37, 1, 1, 1, 1, 36, 38, 38, 38, 1, 36, 36, 36, 1, 39, 1, 41, 42, 43, 1, 1, 44, 1, 1, 40, 45, 45, 45, 1, 40, 40, 40, 1, 8, 1, 9, 47, 1, 1, 48, 1, 1, 46, 49, 49, 49, 1, 46, 46, 46, 1, 50, 1, 52, 53, 1, 1, 1, 1, 51, 54, 1, 56, 57, 1, 1, 1, 1, 55, 58, 58, 58, 1, 55, 55, 55, 1, 2, 59, 59, 59, 59, 59, 1, 2, 60, 60, 60, 60, 60, 1, 2, 61, 61, 61, 61, 61, 1, 2, 62, 62, 62, 62, 62, 1, 2, 63, 63, 63, 63, 63, 1, 2, 64, 64, 64, 64, 64, 1, 2, 65, 65, 65, 65, 65, 1, 2, 66, 66, 66, 66, 66, 1, 2, 67, 67, 67, 67, 67, 1, 2, 68, 68, 68, 68, 68, 1, 2, 69, 69, 69, 69, 69, 1, 2, 70, 70, 70, 70, 70, 1, 2, 71, 71, 71, 71, 71, 1, 2, 72, 72, 72, 72, 72, 1, 2, 73, 73, 73, 73, 73, 1, 2, 74, 74, 74, 74, 74, 1, 2, 75, 75, 75, 75, 75, 1, 2, 76, 76, 76, 76, 76, 1, 2, 1, 1, 0 ]; static byte[] _http_parser_trans_targs_wi = [ 2, 0, 3, 38, 4, 24, 28, 25, 5, 20, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 57, 17, 18, 19, 14, 18, 19, 5, 21, 22, 21, 22, 23, 24, 25, 26, 27, 5, 28, 20, 29, 31, 34, 30, 31, 32, 34, 33, 5, 35, 20, 36, 5, 35, 20, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 ]; static byte[] _http_parser_trans_actions_wi = [ 1, 0, 11, 0, 1, 1, 1, 1, 13, 13, 1, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 25, 23, 3, 5, 7, 9, 7, 0, 15, 1, 1, 0, 0, 0, 0, 0, 0, 0, 31, 0, 31, 0, 21, 21, 0, 0, 0, 0, 0, 34, 17, 34, 17, 28, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; static int http_parser_start = 1; static int http_parser_first_final = 57; static int http_parser_error = 0; static int http_parser_en_main = 1; //#line 130 "http11_parser.rl" this () { cs = 0; //#line 255 "http11_parser.d" { cs = http_parser_start; } //#line 135 "http11_parser.rl" body_start = 0; content_len = 0; mark = 0; nread = 0; field_len = 0; field_start = 0; } /** exec **/ public size_t execute(char[] buffer, size_t off = 0) { char* p, pe; int len = buffer.length; assert(off <= len && "offset past end of buffer"); p = buffer.ptr+off; pe = buffer.ptr+len; /* assert(*pe == '\0' && "pointer does not end on NUL"); */ assert(pe - p == len - off && "pointers aren't same distance"); //#line 284 "http11_parser.d" { int _klen; uint _trans; byte* _acts; uint _nacts; char* _keys; if ( p == pe ) goto _out; if ( cs == 0 ) goto _out; _resume: _keys = &_http_parser_trans_keys[_http_parser_key_offsets[cs]]; _trans = _http_parser_index_offsets[cs]; _klen = _http_parser_single_lengths[cs]; if ( _klen > 0 ) { char* _lower = _keys; char* _mid; char* _upper = _keys + _klen - 1; while (1) { if ( _upper < _lower ) break; _mid = _lower + ((_upper-_lower) >> 1); if ( (*p) < *_mid ) _upper = _mid - 1; else if ( (*p) > *_mid ) _lower = _mid + 1; else { _trans += (_mid - _keys); goto _match; } } _keys += _klen; _trans += _klen; } _klen = _http_parser_range_lengths[cs]; if ( _klen > 0 ) { char* _lower = _keys; char* _mid; char* _upper = _keys + (_klen<<1) - 2; while (1) { if ( _upper < _lower ) break; _mid = _lower + (((_upper-_lower) >> 1) & ~1); if ( (*p) < _mid[0] ) _upper = _mid - 2; else if ( (*p) > _mid[1] ) _lower = _mid + 2; else { _trans += ((_mid - _keys)>>1); goto _match; } } _trans += _klen; } _match: _trans = _http_parser_indicies[_trans]; cs = _http_parser_trans_targs_wi[_trans]; if ( _http_parser_trans_actions_wi[_trans] == 0 ) goto _again; _acts = &_http_parser_actions[_http_parser_trans_actions_wi[_trans]]; _nacts = cast(uint) *_acts++; while ( _nacts-- > 0 ) { switch ( *_acts++ ) { case 0: //#line 67 "http11_parser.rl" {buffer.MARK(&mark, p); } break; case 1: //#line 70 "http11_parser.rl" { buffer.MARK(&field_start, p); } break; case 2: //#line 71 "http11_parser.rl" { snake_upcase_char(cast(char *)p); } break; case 3: //#line 72 "http11_parser.rl" { field_len = buffer.LEN(field_start, p); } break; case 4: //#line 76 "http11_parser.rl" { buffer.MARK(&mark, p); } break; case 5: //#line 77 "http11_parser.rl" { if(http_field) http_field(data, buffer[field_start .. field_start+field_len], buffer[mark .. $]); } break; case 6: //#line 85 "http11_parser.rl" { if(request_method) request_method(data, buffer[mark .. $]); } break; case 7: //#line 90 "http11_parser.rl" { if(request_uri) request_uri(data, buffer[mark .. $]); } break; case 8: //#line 95 "http11_parser.rl" { if(fragment) fragment(data, buffer[mark .. $]); } break; case 9: //#line 100 "http11_parser.rl" {buffer.MARK(&query_start, p); } break; case 10: //#line 102 "http11_parser.rl" { if(query_string) query_string(data, buffer[query_start .. $]); } break; case 11: //#line 107 "http11_parser.rl" { if(http_version) http_version(data, buffer[mark .. $]); } break; case 12: //#line 112 "http11_parser.rl" { if(request_path) request_path(data, buffer[mark .. $]); } break; case 13: //#line 117 "http11_parser.rl" { body_start = p - buffer.ptr + 1; if(header_done) header_done(data, p[1 .. (pe - p - 1)]); if (true) goto _out; } break; //#line 446 "http11_parser.d" default: break; } } _again: if ( cs == 0 ) goto _out; if ( ++p != pe ) goto _resume; _out: {} } //#line 159 "http11_parser.rl" //parser->cs = cs; nread += p - (buffer.ptr + off); assert(p <= pe && "buffer overflow after parsing execute"); assert(nread <= len && "nread longer than length"); assert(body_start <= len && "body starts after buffer end"); assert(mark < len && "mark is after buffer end"); assert(field_len <= len && "field has length longer than whole buffer"); assert(field_start < len && "field starts after buffer end"); return(nread); } public int finish() { if (has_error() ) { return -1; } else if (is_finished() ) { return 1; } else { return 0; } } public bool has_error() { return cs == http_parser_error; } public bool is_finished() { return cs >= http_parser_first_final; } public void setData(Object d) { data = d; } }