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);