1 // Copyright (c) 2013 Heapsource.com and Contributors - http://www.heapsource.com 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 // 21 22 module http.parser.c; 23 import std.conv; 24 import std.c.stdlib; 25 import std.stdint; 26 import std.bitmanip; 27 import std.stdint; 28 29 extern(C): 30 struct http_parser; 31 32 alias int function (http_parser*, ubyte *at, size_t length) http_data_cb; 33 alias int function (http_parser*) http_cb; 34 35 enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; 36 37 struct http_parser_settings { 38 http_cb on_message_begin; 39 http_data_cb on_url; 40 http_data_cb on_status_complete; 41 http_data_cb on_header_field; 42 http_data_cb on_header_value; 43 http_cb on_headers_complete; 44 http_data_cb on_body; 45 http_cb on_message_complete; 46 }; 47 48 void http_parser_init(http_parser *parser, http_parser_type type); 49 size_t http_parser_execute(http_parser *parser, http_parser_settings *settings, ubyte * data, size_t len); 50 51 const(char) * duv_http_errno_name(http_parser *parser); 52 const(char) * duv_http_errno_description(http_parser *parser); 53 54 http_parser * duv_alloc_http_parser(); 55 void duv_free_http_parser(http_parser * parser); 56 57 void duv_set_http_parser_data(http_parser * parser, void * data); 58 void * duv_get_http_parser_data(http_parser * parser); 59 60 ubyte duv_http_parser_get_errno(http_parser * parser); 61 62 template http_parser_cb(string Name) { 63 const char[] http_parser_cb = "static int duv_http_parser_" ~ Name ~ "(http_parser * parser) { void * _self = duv_get_http_parser_data(parser); HttpParser self = cast(HttpParser)_self; return self._" ~ Name ~ "(); }"; 64 } 65 66 template http_parser_data_cb(string Name) { 67 const char[] http_parser_data_cb = "static int duv_http_parser_" ~ Name ~ "(http_parser * parser, ubyte * at, size_t len) { HttpParser self = cast(HttpParser)duv_get_http_parser_data(parser); return self._" ~ Name ~ "(at[0 .. len]); }"; 68 } 69 70 immutable(char) * duv_http_method_str(http_parser * parser); 71 72 ushort duv_http_major(http_parser * parser); 73 ushort duv_http_minor(http_parser * parser); 74 uint duv_http_status_code(http_parser * parser); 75 76 enum http_parser_url_fields 77 { 78 UF_SCHEMA = 0, 79 UF_HOST = 1, 80 UF_PORT = 2, 81 UF_PATH = 3, 82 UF_QUERY = 4, 83 UF_FRAGMENT = 5, 84 UF_USERINFO = 6, 85 UF_MAX = 7, 86 }; 87 88 struct http_parser_url; 89 90 int http_parser_parse_url(immutable(char)* buf, size_t buflen, int is_connect, http_parser_url *u); 91 92 size_t http_parser_url_size(); 93 94 http_parser_url * alloc_http_parser_url() { 95 return cast(http_parser_url*)malloc(http_parser_url_size()); 96 } 97 98 void free_http_parser_url(http_parser_url * u) { 99 if(u !is null) { 100 free(cast(void*)u); 101 } 102 } 103 104 struct http_parser_url_field { 105 uint16_t off; 106 uint16_t len; 107 }; 108 109 http_parser_url_field http_parser_get_field(http_parser_url * url, http_parser_url_fields field); 110 111 uint16_t http_parser_get_port(http_parser_url * url); 112 uint16_t http_parser_get_fieldset(http_parser_url * url); 113 114 string http_parser_get_field_string(http_parser_url * url, string rawUri, http_parser_url_fields field) { 115 auto fieldset = http_parser_get_fieldset(url); 116 auto f = http_parser_get_field(url, field); 117 auto ifs = fieldset & (1 << field); 118 string data = null; 119 if(ifs != 0) { 120 data = rawUri[f.off..(f.off + f.len)]; 121 } 122 return data; 123 } 124 125 int http_body_is_final(http_parser *parser); 126 127 ulong http_parser_get_content_length(http_parser * parser);