Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | #include "gate/net/httptypes.h" | ||
29 | |||
30 | #include "gate/results.h" | ||
31 | #include "gate/utilities.h" | ||
32 | #include "gate/uris.h" | ||
33 | |||
34 | 1 | gate_result_t gate_http_request_init_str(gate_http_request_t* request, char const* method, char const* path) | |
35 | { | ||
36 | gate_result_t ret; | ||
37 | gate_string_t str_method, str_path; | ||
38 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (NULL == gate_string_create(&str_method, method, gate_str_length(method))) |
39 | { | ||
40 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
41 | } | ||
42 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (NULL == gate_string_create(&str_path, path, gate_str_length(path))) |
43 | { | ||
44 | ✗ | gate_string_release(&str_method); | |
45 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
46 | } | ||
47 | 1 | ret = gate_http_request_init(request, &str_method, &str_path); | |
48 | 1 | gate_string_release(&str_path); | |
49 | 1 | gate_string_release(&str_method); | |
50 | 1 | return ret; | |
51 | } | ||
52 | |||
53 | |||
54 | 10 | gate_result_t gate_http_request_init(gate_http_request_t* request, gate_string_t const* method, gate_string_t const* path) | |
55 | { | ||
56 | 10 | gate_mem_clear(request, sizeof(gate_http_request_t)); | |
57 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
|
10 | if (method != NULL) |
58 | { | ||
59 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (NULL == gate_string_clone(&request->method, method)) |
60 | { | ||
61 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
62 | } | ||
63 | } | ||
64 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
|
10 | if (path != NULL) |
65 | { | ||
66 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (NULL == gate_string_clone(&request->path, path)) |
67 | { | ||
68 | ✗ | gate_http_request_release(request); | |
69 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
70 | } | ||
71 | } | ||
72 | |||
73 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
|
10 | if (NULL == gate_util_stringmap_create_ex(&request->headers, true, true)) |
74 | { | ||
75 | ✗ | gate_http_request_release(request); | |
76 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
77 | } | ||
78 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
|
10 | if (NULL == gate_util_stringset_create(&request->accept_types)) |
79 | { | ||
80 | ✗ | gate_http_request_release(request); | |
81 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
82 | } | ||
83 | 10 | return GATE_RESULT_OK; | |
84 | } | ||
85 | |||
86 | ✗ | gate_result_t gate_http_request_init_uri(gate_http_request_t* request, gate_string_t const* method, gate_uri_t* uri) | |
87 | { | ||
88 | gate_result_t ret; | ||
89 | ✗ | gate_string_t path = GATE_STRING_INIT_EMPTY; | |
90 | |||
91 | do | ||
92 | { | ||
93 | ✗ | ret = gate_uri_to_string(uri, &path, true); | |
94 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
95 | |||
96 | ✗ | ret = gate_http_request_init(request, method, &path); | |
97 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
98 | |||
99 | ✗ | if (!gate_string_is_empty(&uri->user_info)) | |
100 | { | ||
101 | ✗ | ret = gate_uri_parse_user_info(&uri->user_info, &request->auth_user, &request->auth_pass); | |
102 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
103 | } | ||
104 | |||
105 | } while (0); | ||
106 | |||
107 | ✗ | gate_string_release(&path); | |
108 | |||
109 | ✗ | return ret; | |
110 | } | ||
111 | |||
112 | |||
113 | |||
114 | 4 | gate_result_t gate_http_request_copy(gate_http_request_t* request, gate_http_request_t const* src) | |
115 | { | ||
116 | 4 | gate_result_t ret = GATE_RESULT_OUTOFMEMORY; | |
117 | 4 | gate_mem_clear(request, sizeof(gate_http_request_t)); | |
118 | do | ||
119 | { | ||
120 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->method, &src->method)) break; |
121 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->path, &src->path)) break; |
122 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->version, &src->version)) break; |
123 | |||
124 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->auth_user, &src->auth_user)) break; |
125 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->auth_pass, &src->auth_pass)) break; |
126 | |||
127 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_map_copy(&request->headers, &src->headers)) break; |
128 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_set_copy(&request->accept_types, &src->accept_types)) break; |
129 | |||
130 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->proxy_server, &src->proxy_server)) break; |
131 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->proxy_user, &src->proxy_user)) break; |
132 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (!gate_string_clone(&request->proxy_pass, &src->proxy_pass)) break; |
133 | |||
134 | 4 | request->upload_stream = src->upload_stream; | |
135 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (request->upload_stream) |
136 | { | ||
137 | 2 | gate_object_retain(request->upload_stream); | |
138 | } | ||
139 | |||
140 | 4 | request->connect_timeout_ms = src->connect_timeout_ms; | |
141 | 4 | request->send_timeout_ms = src->send_timeout_ms; | |
142 | 4 | request->receive_timeout_ms = src->receive_timeout_ms; | |
143 | 4 | request->proxy_port = src->proxy_port; | |
144 | |||
145 | 4 | ret = GATE_RESULT_OK; | |
146 | |||
147 | } while (0); | ||
148 | |||
149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (GATE_FAILED(ret)) |
150 | { | ||
151 | ✗ | gate_http_request_release(request); | |
152 | } | ||
153 | 4 | return ret; | |
154 | } | ||
155 | |||
156 | 14 | gate_result_t gate_http_request_release(gate_http_request_t* request) | |
157 | { | ||
158 | 14 | gate_string_release(&request->method); | |
159 | 14 | gate_string_release(&request->path); | |
160 | 14 | gate_string_release(&request->version); | |
161 | |||
162 | 14 | gate_string_release(&request->auth_user); | |
163 | 14 | gate_string_release(&request->auth_pass); | |
164 | |||
165 | 14 | gate_map_destroy(&request->headers); | |
166 | 14 | gate_set_destroy(&request->accept_types); | |
167 | |||
168 | 14 | gate_string_release(&request->proxy_server); | |
169 | 14 | gate_string_release(&request->proxy_user); | |
170 | 14 | gate_string_release(&request->proxy_pass); | |
171 | |||
172 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 9 times.
|
14 | if (request->upload_stream != NULL) |
173 | { | ||
174 | 5 | gate_object_release(request->upload_stream); | |
175 | } | ||
176 | |||
177 | 14 | gate_mem_clear(request, sizeof(gate_http_request_t)); | |
178 | 14 | return GATE_RESULT_OK; | |
179 | } | ||
180 | |||
181 | |||
182 | 10 | gate_result_t gate_http_response_init(gate_http_response_t* response) | |
183 | { | ||
184 | 10 | gate_result_t ret = GATE_RESULT_FAILED; | |
185 | do | ||
186 | { | ||
187 | 10 | gate_mem_clear(response, sizeof(gate_http_response_t)); | |
188 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
|
10 | if (NULL == gate_util_stringmap_create_ex(&response->headers, true, true)) |
189 | { | ||
190 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
191 | ✗ | break; | |
192 | } | ||
193 | } while (0); | ||
194 | 10 | return GATE_RESULT_OK; | |
195 | } | ||
196 | |||
197 | 2 | gate_result_t gate_http_response_copy(gate_http_response_t* response, gate_http_response_t const* src) | |
198 | { | ||
199 | 2 | gate_result_t ret = GATE_RESULT_OK; | |
200 | do | ||
201 | { | ||
202 | 2 | gate_mem_clear(response, sizeof(gate_http_response_t)); | |
203 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_map_copy(&response->headers, &src->headers)) |
204 | { | ||
205 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
206 | ✗ | break; | |
207 | } | ||
208 | 2 | response->response_stream = src->response_stream; | |
209 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (response->response_stream) |
210 | { | ||
211 | ✗ | gate_object_retain(response->response_stream); | |
212 | } | ||
213 | 2 | response->status_code = src->status_code; | |
214 | 2 | ret = GATE_RESULT_OK; | |
215 | } while (0); | ||
216 | 2 | return ret; | |
217 | } | ||
218 | |||
219 | 10 | gate_result_t gate_http_response_release(gate_http_response_t* response) | |
220 | { | ||
221 | 10 | gate_map_destroy(&response->headers); | |
222 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
|
10 | if (NULL != response->response_stream) |
223 | { | ||
224 | 6 | gate_object_release(response->response_stream); | |
225 | } | ||
226 | 10 | gate_mem_clear(response, sizeof(gate_http_response_t)); | |
227 | 10 | return GATE_RESULT_OK; | |
228 | } | ||
229 | |||
230 | 2 | char const* gate_http_response_status_text(gate_uint32_t status_code) | |
231 | { | ||
232 |
1/66✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
|
2 | switch (status_code) |
233 | { | ||
234 | ✗ | case 100: return "Continue"; | |
235 | ✗ | case 101: return "Switching Protocols"; | |
236 | ✗ | case 102: return "Processing"; | |
237 | ✗ | case 103: return "Early Hints"; | |
238 | 2 | case 200: return "OK"; | |
239 | ✗ | case 201: return "Created"; | |
240 | ✗ | case 202: return "Accepted"; | |
241 | ✗ | case 203: return "Non-Authoritative Information"; | |
242 | ✗ | case 204: return "No Content"; | |
243 | ✗ | case 205: return "Reset Content"; | |
244 | ✗ | case 206: return "Partial Content"; | |
245 | ✗ | case 207: return "Multi-Status"; | |
246 | ✗ | case 208: return "Already Reported"; | |
247 | ✗ | case 226: return "IM Used"; | |
248 | ✗ | case 300: return "Multiple Choices"; | |
249 | ✗ | case 301: return "Moved Permanently"; | |
250 | ✗ | case 302: return "Found"; | |
251 | ✗ | case 303: return "See Other"; | |
252 | ✗ | case 304: return "Not Modified"; | |
253 | ✗ | case 305: return "Use Proxy"; | |
254 | ✗ | case 306: return "Switch Proxy"; | |
255 | ✗ | case 307: return "Temporary Redirect"; | |
256 | ✗ | case 308: return "Permanent Redirect"; | |
257 | ✗ | case 400: return "Bad Request"; | |
258 | ✗ | case 401: return "Unauthorized"; | |
259 | ✗ | case 402: return "Payment Required"; | |
260 | ✗ | case 403: return "Forbidden"; | |
261 | ✗ | case 404: return "Not Found"; | |
262 | ✗ | case 405: return "Method Not Allowed"; | |
263 | ✗ | case 406: return "Not Acceptable"; | |
264 | ✗ | case 407: return "Proxy Authentication Required"; | |
265 | ✗ | case 408: return "Request Time-out"; | |
266 | ✗ | case 409: return "Conflict"; | |
267 | ✗ | case 410: return "Gone"; | |
268 | ✗ | case 411: return "Length Required"; | |
269 | ✗ | case 412: return "Precondition Failed"; | |
270 | ✗ | case 413: return "Request Entity Too Large"; | |
271 | ✗ | case 414: return "Request-URL Too Long"; | |
272 | ✗ | case 415: return "Unsupported Media Type"; | |
273 | ✗ | case 416: return "Requested range not satisfiable"; | |
274 | ✗ | case 417: return "Expectation Failed"; | |
275 | ✗ | case 418: return "I'm a teapot"; | |
276 | ✗ | case 420: return "Policy Not Fulfilled"; | |
277 | ✗ | case 421: return "Misdirected Request"; | |
278 | ✗ | case 422: return "Unprocessable Entity"; | |
279 | ✗ | case 423: return "Locked"; | |
280 | ✗ | case 424: return "Failed Dependency"; | |
281 | ✗ | case 425: return "Too Early"; | |
282 | ✗ | case 426: return "Upgrade Required"; | |
283 | ✗ | case 428: return "Precondition Required"; | |
284 | ✗ | case 429: return "Too Many Requests"; | |
285 | ✗ | case 431: return "Request Header Fields Too Large"; | |
286 | ✗ | case 451: return "Unavailable For Legal Reasons"; | |
287 | ✗ | case 500: return "Internal Server Error"; | |
288 | ✗ | case 501: return "Not Implemented"; | |
289 | ✗ | case 502: return "Bad Gateway"; | |
290 | ✗ | case 503: return "Service Unavailable"; | |
291 | ✗ | case 504: return "Gateway Timeout"; | |
292 | ✗ | case 505: return "HTTP Version not supported"; | |
293 | ✗ | case 506: return "Variant Also Negotiates"; | |
294 | ✗ | case 507: return "Insufficient Storage"; | |
295 | ✗ | case 508: return "Loop Detected"; | |
296 | ✗ | case 509: return "Bandwidth Limit Exceeded"; | |
297 | ✗ | case 510: return "Not Extended"; | |
298 | ✗ | case 511: return "Network Authentication Required"; | |
299 | |||
300 | } | ||
301 | ✗ | return NULL; | |
302 | } | ||
303 | |||
304 | ✗ | gate_result_t gate_http_parse_urlencoded_content(gate_string_t const* content, | |
305 | gate_flatmap_t* append_to_stringmap) | ||
306 | { | ||
307 | ✗ | gate_result_t ret = GATE_RESULT_OK; | |
308 | ✗ | gate_size_t start = 0; | |
309 | ✗ | gate_size_t pos = 0; | |
310 | ✗ | gate_string_t pair = GATE_STRING_INIT_EMPTY; | |
311 | ✗ | gate_string_t raw_key = GATE_STRING_INIT_EMPTY; | |
312 | ✗ | gate_string_t raw_value = GATE_STRING_INIT_EMPTY; | |
313 | ✗ | gate_string_t key = GATE_STRING_INIT_EMPTY; | |
314 | ✗ | gate_string_t value = GATE_STRING_INIT_EMPTY; | |
315 | ✗ | gate_size_t len = gate_string_length(content); | |
316 | |||
317 | ✗ | if (gate_flatmap_count(append_to_stringmap)) | |
318 | { | ||
319 | ✗ | if (NULL == gate_flatmap_create(append_to_stringmap, &gate_compare_string, | |
320 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, | ||
321 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor)) | ||
322 | { | ||
323 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
324 | } | ||
325 | } | ||
326 | |||
327 | ✗ | while ((start < len) && GATE_SUCCEEDED(ret)) | |
328 | { | ||
329 | ✗ | pos = gate_string_char_pos(content, '&', start); | |
330 | ✗ | if (GATE_STR_NPOS == pos) | |
331 | { | ||
332 | ✗ | gate_string_substr(&pair, content, start, GATE_STR_NPOS); | |
333 | ✗ | start = len; | |
334 | } | ||
335 | else | ||
336 | { | ||
337 | ✗ | gate_string_substr(&pair, content, start, pos - start); | |
338 | ✗ | start = pos + 1; | |
339 | } | ||
340 | ✗ | if (!gate_string_is_empty(&pair)) | |
341 | { | ||
342 | ✗ | pos = gate_string_char_pos(&pair, '=', 0); | |
343 | ✗ | if (GATE_STR_NPOS == pos) | |
344 | { | ||
345 | ✗ | gate_uri_unescape(&pair, &key); | |
346 | } | ||
347 | else | ||
348 | { | ||
349 | ✗ | gate_string_substr(&raw_key, &pair, 0, pos); | |
350 | ✗ | gate_string_substr(&raw_value, &pair, pos + 1, GATE_STR_NPOS); | |
351 | ✗ | gate_uri_unescape(&raw_key, &key); | |
352 | ✗ | gate_uri_unescape(&raw_value, &value); | |
353 | ✗ | gate_string_release(&raw_value); | |
354 | ✗ | gate_string_release(&raw_key); | |
355 | } | ||
356 | ✗ | if (!gate_string_is_empty(&key)) | |
357 | { | ||
358 | ✗ | if (NULL == gate_flatmap_add(append_to_stringmap, &key, &value)) | |
359 | { | ||
360 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
361 | } | ||
362 | } | ||
363 | ✗ | gate_string_release(&value); | |
364 | ✗ | gate_string_release(&key); | |
365 | } | ||
366 | ✗ | gate_string_release(&pair); | |
367 | } | ||
368 | ✗ | return ret; | |
369 | } | ||
370 | |||
371 | ✗ | gate_result_t gate_http_build_urlencoded_content(gate_flatmap_t const* stringmap, | |
372 | gate_strbuilder_t* append_to_builder) | ||
373 | { | ||
374 | ✗ | gate_result_t ret = GATE_RESULT_OK; | |
375 | gate_enumerator_t en; | ||
376 | gate_mapping_t const* m; | ||
377 | gate_string_t const* ptr_key; | ||
378 | gate_string_t const* ptr_value; | ||
379 | ✗ | gate_string_t key = GATE_STRING_INIT_EMPTY; | |
380 | ✗ | gate_string_t value = GATE_STRING_INIT_EMPTY; | |
381 | |||
382 | ✗ | if (NULL == gate_flatmap_enumerate(stringmap, &en)) | |
383 | { | ||
384 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
385 | } | ||
386 | |||
387 | ✗ | for (; gate_enumerator_valid(&en); gate_enumerator_next(&en)) | |
388 | { | ||
389 | ✗ | m = (gate_mapping_t const*)gate_enumerator_get(&en); | |
390 | ✗ | if (NULL == m) | |
391 | { | ||
392 | ✗ | continue; | |
393 | } | ||
394 | ✗ | ptr_key = (gate_string_t const*)m->key; | |
395 | ✗ | ptr_value = (gate_string_t const*)m->value; | |
396 | ✗ | if (gate_string_is_empty(ptr_key)) | |
397 | { | ||
398 | ✗ | continue; | |
399 | } | ||
400 | ✗ | gate_uri_escape(ptr_key, &key); | |
401 | ✗ | gate_uri_escape(ptr_value, &value); | |
402 | ✗ | gate_strbuilder_append(append_to_builder, | |
403 | GATE_PRINT_CSTR, "&", | ||
404 | GATE_PRINT_STRING, &key, | ||
405 | GATE_PRINT_CSTR, "=", | ||
406 | GATE_PRINT_STRING, &value); | ||
407 | ✗ | gate_string_release(&key); | |
408 | ✗ | gate_string_release(&value); | |
409 | } | ||
410 | ✗ | return ret; | |
411 | } | ||
412 | |||
413 | |||
414 | typedef struct gate_http_mime_mapping_class | ||
415 | { | ||
416 | char const* file_ext; | ||
417 | gate_string_t const* mime_type; | ||
418 | } gate_http_mime_mapping_t; | ||
419 | |||
420 | static gate_string_t const mimetype_text_plain = GATE_STRING_INIT_STATIC("text/plain"); | ||
421 | static gate_string_t const mimetype_text_html = GATE_STRING_INIT_STATIC("text/html"); | ||
422 | static gate_string_t const mimetype_text_richtext = GATE_STRING_INIT_STATIC("text/richtext"); | ||
423 | static gate_string_t const mimetype_text_css = GATE_STRING_INIT_STATIC("text/css"); | ||
424 | static gate_string_t const mimetype_text_xml = GATE_STRING_INIT_STATIC("text/xml"); | ||
425 | static gate_string_t const mimetype_text_js = GATE_STRING_INIT_STATIC("text/javascript"); | ||
426 | static gate_string_t const mimetype_text_tsv = GATE_STRING_INIT_STATIC("text/tab-separated-values"); | ||
427 | static gate_string_t const mimetype_text_setext = GATE_STRING_INIT_STATIC("text/x-setext"); | ||
428 | static gate_string_t const mimetype_text_sgml = GATE_STRING_INIT_STATIC("text/x-sgml"); | ||
429 | static gate_string_t const mimetype_text_jad = GATE_STRING_INIT_STATIC("text/vnd.sun.j2me.app-descriptor"); | ||
430 | static gate_string_t const mimetype_text_wml = GATE_STRING_INIT_STATIC("text/vnd.wap.wml"); | ||
431 | |||
432 | |||
433 | static gate_string_t const mimetype_image_gif = GATE_STRING_INIT_STATIC("image/gif"); | ||
434 | static gate_string_t const mimetype_image_jpeg = GATE_STRING_INIT_STATIC("image/jpeg"); | ||
435 | static gate_string_t const mimetype_image_tiff = GATE_STRING_INIT_STATIC("image/tiff"); | ||
436 | static gate_string_t const mimetype_image_cmu_raster = GATE_STRING_INIT_STATIC("image/cmu-raster"); | ||
437 | static gate_string_t const mimetype_image_freehand = GATE_STRING_INIT_STATIC("image/x-freehand"); | ||
438 | static gate_string_t const mimetype_image_ief = GATE_STRING_INIT_STATIC("image/ief"); | ||
439 | static gate_string_t const mimetype_image_anymap = GATE_STRING_INIT_STATIC("image/x-portable-anymap"); | ||
440 | static gate_string_t const mimetype_image_graymap = GATE_STRING_INIT_STATIC("image/x-portable-graymap"); | ||
441 | static gate_string_t const mimetype_image_pixmap = GATE_STRING_INIT_STATIC("image/x-portable-pixmap"); | ||
442 | static gate_string_t const mimetype_image_rgb = GATE_STRING_INIT_STATIC("image/x-rgb"); | ||
443 | static gate_string_t const mimetype_image_windowdump = GATE_STRING_INIT_STATIC("image/x-windowdump"); | ||
444 | static gate_string_t const mimetype_image_wbmp = GATE_STRING_INIT_STATIC("image/vnd.wap.wbmp"); | ||
445 | |||
446 | |||
447 | static gate_string_t const mimetype_app_octet_stream = GATE_STRING_INIT_STATIC("application/octet-stream"); | ||
448 | static gate_string_t const mimetype_app_zip = GATE_STRING_INIT_STATIC("application/zip"); | ||
449 | static gate_string_t const mimetype_app_pdf = GATE_STRING_INIT_STATIC("application/pdf"); | ||
450 | static gate_string_t const mimetype_app_postscript = GATE_STRING_INIT_STATIC("application/postscript"); | ||
451 | static gate_string_t const mimetype_app_autoconfig = GATE_STRING_INIT_STATIC("application/x-ns-proxy-autoconfig"); | ||
452 | static gate_string_t const mimetype_app_acad = GATE_STRING_INIT_STATIC("application/acad"); | ||
453 | static gate_string_t const mimetype_app_dxf = GATE_STRING_INIT_STATIC("application/dxf"); | ||
454 | static gate_string_t const mimetype_app_mif = GATE_STRING_INIT_STATIC("application/mif"); | ||
455 | static gate_string_t const mimetype_app_msword = GATE_STRING_INIT_STATIC("application/msword"); | ||
456 | static gate_string_t const mimetype_app_mspowerpoint = GATE_STRING_INIT_STATIC("application/mspowerpoint"); | ||
457 | static gate_string_t const mimetype_app_msexcel = GATE_STRING_INIT_STATIC("application/msexcel"); | ||
458 | static gate_string_t const mimetype_app_mshelp = GATE_STRING_INIT_STATIC("application/mshelp"); | ||
459 | static gate_string_t const mimetype_app_rtf = GATE_STRING_INIT_STATIC("application/rtf"); | ||
460 | static gate_string_t const mimetype_app_sh = GATE_STRING_INIT_STATIC("application/x-sh"); | ||
461 | static gate_string_t const mimetype_app_csh = GATE_STRING_INIT_STATIC("application/x-csh"); | ||
462 | static gate_string_t const mimetype_app_latex = GATE_STRING_INIT_STATIC("application/x-latex"); | ||
463 | static gate_string_t const mimetype_app_tar = GATE_STRING_INIT_STATIC("application/x-tar"); | ||
464 | static gate_string_t const mimetype_app_bcpio = GATE_STRING_INIT_STATIC("application/x-bcpio"); | ||
465 | static gate_string_t const mimetype_app_cpio = GATE_STRING_INIT_STATIC("application/x-cpio"); | ||
466 | static gate_string_t const mimetype_app_sv4cpio = GATE_STRING_INIT_STATIC("application/x-sv4cpio"); | ||
467 | static gate_string_t const mimetype_app_sv4crc = GATE_STRING_INIT_STATIC("application/x-sv4crc"); | ||
468 | static gate_string_t const mimetype_app_hdf = GATE_STRING_INIT_STATIC("application/x-hdf"); | ||
469 | static gate_string_t const mimetype_app_ustar = GATE_STRING_INIT_STATIC("application/x-ustar"); | ||
470 | static gate_string_t const mimetype_app_shar = GATE_STRING_INIT_STATIC("application/x-shar"); | ||
471 | static gate_string_t const mimetype_app_tcl = GATE_STRING_INIT_STATIC("application/x-tcl"); | ||
472 | static gate_string_t const mimetype_app_dvi = GATE_STRING_INIT_STATIC("application/x-dvi"); | ||
473 | static gate_string_t const mimetype_app_texinfo = GATE_STRING_INIT_STATIC("application/x-texinfo"); | ||
474 | static gate_string_t const mimetype_app_troff = GATE_STRING_INIT_STATIC("application/x-troff"); | ||
475 | static gate_string_t const mimetype_app_troff_man = GATE_STRING_INIT_STATIC("application/x-troff-man"); | ||
476 | static gate_string_t const mimetype_app_troff_me = GATE_STRING_INIT_STATIC("application/x-troff-me"); | ||
477 | static gate_string_t const mimetype_app_troff_ms = GATE_STRING_INIT_STATIC("application/x-troff-ms"); | ||
478 | static gate_string_t const mimetype_app_netcdf = GATE_STRING_INIT_STATIC("application/x-netcdf"); | ||
479 | static gate_string_t const mimetype_app_wais_source = GATE_STRING_INIT_STATIC("application/x-wais-source"); | ||
480 | static gate_string_t const mimetype_app_jar = GATE_STRING_INIT_STATIC("application/x-jar"); | ||
481 | static gate_string_t const mimetype_app_jnlp = GATE_STRING_INIT_STATIC("application/x-java-jnlp-file"); | ||
482 | static gate_string_t const mimetype_app_wmlc = GATE_STRING_INIT_STATIC("application/vnd.wap.wmlc"); | ||
483 | static gate_string_t const mimetype_app_wrl = GATE_STRING_INIT_STATIC("application/x-wrl+xml"); | ||
484 | |||
485 | |||
486 | static gate_string_t const mimetype_audio_basic = GATE_STRING_INIT_STATIC("audio/basic"); | ||
487 | static gate_string_t const mimetype_audio_aiff = GATE_STRING_INIT_STATIC("audio/x-aiff"); | ||
488 | static gate_string_t const mimetype_audio_dspeeh = GATE_STRING_INIT_STATIC("audio/x-dspeeh"); | ||
489 | static gate_string_t const mimetype_audio_midi = GATE_STRING_INIT_STATIC("audio/x-midi"); | ||
490 | static gate_string_t const mimetype_audio_realaudio = GATE_STRING_INIT_STATIC("audio/x-pn-realaudio"); | ||
491 | static gate_string_t const mimetype_audio_realaudio_plugin = GATE_STRING_INIT_STATIC("audio/x-pn-realaudio-plugin"); | ||
492 | |||
493 | static gate_string_t const mimetype_video_mpeg = GATE_STRING_INIT_STATIC("video/mpeg"); | ||
494 | static gate_string_t const mimetype_video_quicktime = GATE_STRING_INIT_STATIC("video/quicktime"); | ||
495 | static gate_string_t const mimetype_video_msvideo = GATE_STRING_INIT_STATIC("video/x-msvideo"); | ||
496 | static gate_string_t const mimetype_video_sgi_movie = GATE_STRING_INIT_STATIC("video/x-sgi-movie"); | ||
497 | |||
498 | |||
499 | |||
500 | |||
501 | static gate_http_mime_mapping_t gate_http_default_mime_types[] = | ||
502 | { | ||
503 | { ".txt", &mimetype_text_plain }, | ||
504 | { ".c", &mimetype_text_plain }, | ||
505 | { ".cc", &mimetype_text_plain }, | ||
506 | { ".g", &mimetype_text_plain }, | ||
507 | { ".h", &mimetype_text_plain }, | ||
508 | { ".hh", &mimetype_text_plain }, | ||
509 | { ".m", &mimetype_text_plain }, | ||
510 | { ".f90", &mimetype_text_plain }, | ||
511 | { ".rtx", &mimetype_text_richtext }, | ||
512 | { ".css", &mimetype_text_css }, | ||
513 | { ".xml", &mimetype_text_xml }, | ||
514 | { ".htm", &mimetype_text_html }, | ||
515 | { ".html", &mimetype_text_html }, | ||
516 | { ".shtm", &mimetype_text_html }, | ||
517 | { ".shtml", &mimetype_text_html }, | ||
518 | { ".js", &mimetype_text_js }, | ||
519 | { ".tsv", &mimetype_text_tsv }, | ||
520 | { ".etx", &mimetype_text_setext }, | ||
521 | { ".sgm", &mimetype_text_sgml }, | ||
522 | { ".sgml", &mimetype_text_sgml }, | ||
523 | { ".jad", &mimetype_text_jad }, | ||
524 | { ".wml", &mimetype_text_wml }, | ||
525 | |||
526 | |||
527 | { ".gif", &mimetype_image_gif }, | ||
528 | { ".jpeg", &mimetype_image_jpeg }, | ||
529 | { ".jpg", &mimetype_image_jpeg }, | ||
530 | { ".jpe", &mimetype_image_jpeg }, | ||
531 | { ".tiff", &mimetype_image_tiff }, | ||
532 | { ".tif", &mimetype_image_tiff }, | ||
533 | { ".ras", &mimetype_image_cmu_raster }, | ||
534 | { ".fh4", &mimetype_image_freehand }, | ||
535 | { ".fh5", &mimetype_image_freehand }, | ||
536 | { ".fhc", &mimetype_image_freehand }, | ||
537 | { ".ief", &mimetype_image_ief }, | ||
538 | { ".pnm", &mimetype_image_anymap }, | ||
539 | { ".PBM", &mimetype_image_anymap }, | ||
540 | { ".pgm", &mimetype_image_graymap }, | ||
541 | { ".ppm", &mimetype_image_pixmap }, | ||
542 | { ".rgb", &mimetype_image_rgb }, | ||
543 | { ".xwd", &mimetype_image_windowdump }, | ||
544 | { ".wbmp", &mimetype_image_wbmp }, | ||
545 | |||
546 | |||
547 | { ".exe", &mimetype_app_octet_stream }, | ||
548 | { ".com", &mimetype_app_octet_stream }, | ||
549 | { ".dll", &mimetype_app_octet_stream }, | ||
550 | { ".bin", &mimetype_app_octet_stream }, | ||
551 | { ".class", &mimetype_app_octet_stream }, | ||
552 | { ".zip", &mimetype_app_zip }, | ||
553 | { ".pdf", &mimetype_app_pdf }, | ||
554 | { ".ps", &mimetype_app_postscript }, | ||
555 | { ".ai", &mimetype_app_postscript }, | ||
556 | { ".eps", &mimetype_app_postscript }, | ||
557 | { ".pac", &mimetype_app_autoconfig }, | ||
558 | { ".dwg", &mimetype_app_acad }, | ||
559 | { ".dxf", &mimetype_app_dxf }, | ||
560 | { ".mif", &mimetype_app_mif }, | ||
561 | { ".doc", &mimetype_app_msword }, | ||
562 | { ".dot", &mimetype_app_msword }, | ||
563 | { ".ppt", &mimetype_app_mspowerpoint }, | ||
564 | { ".ppz", &mimetype_app_mspowerpoint }, | ||
565 | { ".pps", &mimetype_app_mspowerpoint }, | ||
566 | { ".pot", &mimetype_app_mspowerpoint }, | ||
567 | { ".xls", &mimetype_app_msexcel }, | ||
568 | { ".xla", &mimetype_app_msexcel }, | ||
569 | { ".hlp", &mimetype_app_mshelp }, | ||
570 | { ".chm", &mimetype_app_mshelp }, | ||
571 | { ".rtf", &mimetype_app_rtf }, | ||
572 | { ".sh", &mimetype_app_sh }, | ||
573 | { ".csh", &mimetype_app_csh }, | ||
574 | { ".latex", &mimetype_app_latex }, | ||
575 | { ".tar", &mimetype_app_tar }, | ||
576 | { ".bcpio", &mimetype_app_bcpio }, | ||
577 | { ".cpio", &mimetype_app_cpio }, | ||
578 | { ".sv4cpio", &mimetype_app_sv4cpio }, | ||
579 | { ".sv4crc", &mimetype_app_sv4crc }, | ||
580 | { ".hdf", &mimetype_app_hdf }, | ||
581 | { ".ustar", &mimetype_app_ustar }, | ||
582 | { ".shar", &mimetype_app_shar }, | ||
583 | { ".tcl", &mimetype_app_tcl }, | ||
584 | { ".dvi", &mimetype_app_dvi }, | ||
585 | { ".texinfo", &mimetype_app_texinfo }, | ||
586 | { ".texi", &mimetype_app_texinfo }, | ||
587 | { ".t", &mimetype_app_troff }, | ||
588 | { ".tr", &mimetype_app_troff }, | ||
589 | { ".roff", &mimetype_app_troff }, | ||
590 | { ".man", &mimetype_app_troff_man }, | ||
591 | { ".me", &mimetype_app_troff_me }, | ||
592 | { ".ms", &mimetype_app_troff_ms }, | ||
593 | { ".nc", &mimetype_app_netcdf }, | ||
594 | { ".cdf", &mimetype_app_netcdf }, | ||
595 | { ".src", &mimetype_app_wais_source }, | ||
596 | { ".jar", &mimetype_app_jar }, | ||
597 | { ".jnlp", &mimetype_app_jnlp }, | ||
598 | { ".wmlc", &mimetype_app_wmlc }, | ||
599 | { ".wrl", &mimetype_app_wrl }, | ||
600 | |||
601 | |||
602 | { ".au", &mimetype_audio_basic }, | ||
603 | { ".snd", &mimetype_audio_basic }, | ||
604 | { ".aif", &mimetype_audio_aiff }, | ||
605 | { ".aiff", &mimetype_audio_aiff }, | ||
606 | { ".aifc", &mimetype_audio_aiff }, | ||
607 | { ".dus", &mimetype_audio_dspeeh }, | ||
608 | { ".cht", &mimetype_audio_dspeeh }, | ||
609 | { ".midi", &mimetype_audio_midi }, | ||
610 | { ".mid", &mimetype_audio_midi }, | ||
611 | { ".ram", &mimetype_audio_realaudio }, | ||
612 | { ".ra", &mimetype_audio_realaudio }, | ||
613 | { ".rpm", &mimetype_audio_realaudio_plugin }, | ||
614 | |||
615 | { ".mpeg", &mimetype_video_mpeg }, | ||
616 | { ".mpg", &mimetype_video_mpeg }, | ||
617 | { ".mpe", &mimetype_video_mpeg }, | ||
618 | { ".qt", &mimetype_video_quicktime }, | ||
619 | { ".mov", &mimetype_video_quicktime }, | ||
620 | { ".avi", &mimetype_video_msvideo }, | ||
621 | { ".movie", &mimetype_video_sgi_movie } | ||
622 | }; | ||
623 | |||
624 | static gate_size_t const gate_http_default_mime_types_count = sizeof(gate_http_default_mime_types) / sizeof(gate_http_default_mime_types[0]); | ||
625 | |||
626 | |||
627 | ✗ | gate_result_t gate_http_resolve_mime_type(gate_string_t const* file_ext, gate_string_t* mine_type) | |
628 | { | ||
629 | gate_size_t ndx; | ||
630 | |||
631 | ✗ | for (ndx = 0; ndx != gate_http_default_mime_types_count; ++ndx) | |
632 | { | ||
633 | ✗ | if (gate_string_ends_with_str_ic(file_ext, gate_http_default_mime_types[ndx].file_ext)) | |
634 | { | ||
635 | ✗ | gate_string_duplicate(mine_type, gate_http_default_mime_types[ndx].mime_type); | |
636 | ✗ | return GATE_RESULT_OK; | |
637 | } | ||
638 | } | ||
639 | ✗ | gate_string_duplicate(mine_type, &mimetype_app_octet_stream); | |
640 | ✗ | return GATE_RESULT_OK; | |
641 | } | ||
642 | |||
643 | ✗ | char const* gate_http_resolve_mime_type_str(char const* file_ext) | |
644 | { | ||
645 | gate_result_t result; | ||
646 | gate_string_t ext; | ||
647 | ✗ | gate_string_t mime = GATE_STRING_INIT_EMPTY; | |
648 | ✗ | gate_string_create_static(&ext, file_ext); | |
649 | ✗ | result = gate_http_resolve_mime_type(&ext, &mime); | |
650 | ✗ | if (GATE_FAILED(result)) | |
651 | { | ||
652 | ✗ | return NULL; | |
653 | } | ||
654 | else | ||
655 | { | ||
656 | ✗ | return mime.str; | |
657 | } | ||
658 | } | ||
659 |