| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* GATE PROJECT LICENSE: | ||
| 2 | +----------------------------------------------------------------------------+ | ||
| 3 | | Copyright (c) 2018-2026, 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 | 3 | gate_result_t gate_http_request_init_str(gate_http_request_t* request, char const* method, char const* host, char const* path) | |
| 35 | { | ||
| 36 | gate_result_t ret; | ||
| 37 | gate_string_t str_method, str_path, str_host; | ||
| 38 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | 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 3 times.
|
3 | 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/2✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | if (NULL == gate_string_create(&str_host, host, gate_str_length(host))) |
| 48 | { | ||
| 49 | ✗ | gate_string_release(&str_method); | |
| 50 | ✗ | gate_string_release(&str_path); | |
| 51 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 52 | } | ||
| 53 | 3 | ret = gate_http_request_init(request, &str_method, &str_host, &str_path); | |
| 54 | 3 | gate_string_release(&str_host); | |
| 55 | 3 | gate_string_release(&str_path); | |
| 56 | 3 | gate_string_release(&str_method); | |
| 57 | 3 | return ret; | |
| 58 | } | ||
| 59 | |||
| 60 | |||
| 61 | 28 | gate_result_t gate_http_request_init(gate_http_request_t* request, gate_string_t const* method, gate_string_t const* host, gate_string_t const* path) | |
| 62 | { | ||
| 63 | 28 | gate_mem_clear(request, sizeof(gate_http_request_t)); | |
| 64 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
|
28 | if (method != NULL) |
| 65 | { | ||
| 66 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
|
24 | if (NULL == gate_string_clone(&request->method, method)) |
| 67 | { | ||
| 68 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 69 | } | ||
| 70 | } | ||
| 71 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
|
28 | if (path != NULL) |
| 72 | { | ||
| 73 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
|
24 | if (NULL == gate_string_clone(&request->path, path)) |
| 74 | { | ||
| 75 | ✗ | gate_http_request_release(request); | |
| 76 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 77 | } | ||
| 78 | } | ||
| 79 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
|
28 | if (host != NULL) |
| 80 | { | ||
| 81 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
|
24 | if (NULL == gate_string_clone(&request->host, host)) |
| 82 | { | ||
| 83 | ✗ | gate_http_request_release(request); | |
| 84 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
|
28 | if (NULL == gate_util_stringmap_create_ex(&request->headers, true, true)) |
| 89 | { | ||
| 90 | ✗ | gate_http_request_release(request); | |
| 91 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 92 | } | ||
| 93 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
|
28 | if (NULL == gate_util_stringset_create(&request->accept_types)) |
| 94 | { | ||
| 95 | ✗ | gate_http_request_release(request); | |
| 96 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 97 | } | ||
| 98 | 28 | return GATE_RESULT_OK; | |
| 99 | } | ||
| 100 | |||
| 101 | 1 | gate_result_t gate_http_request_init_uri(gate_http_request_t* request, gate_string_t const* method, gate_uri_t const* uri) | |
| 102 | { | ||
| 103 | gate_result_t ret; | ||
| 104 | 1 | gate_string_t path = GATE_STRING_INIT_EMPTY; | |
| 105 | |||
| 106 | do | ||
| 107 | { | ||
| 108 | 1 | gate_mem_clear(request, sizeof(gate_http_request_t)); | |
| 109 | |||
| 110 | 1 | ret = gate_uri_to_string(uri, &path, true); | |
| 111 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(ret); |
| 112 | |||
| 113 | 1 | ret = gate_http_request_init(request, method, &uri->host, &path); | |
| 114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(ret); |
| 115 | |||
| 116 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (!gate_string_is_empty(&uri->user_info)) |
| 117 | { | ||
| 118 | ✗ | ret = gate_uri_parse_user_info(&uri->user_info, &request->auth_user, &request->auth_pass); | |
| 119 | ✗ | GATE_BREAK_IF_FAILED(ret); | |
| 120 | } | ||
| 121 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if (!gate_string_is_empty(&uri->host)) |
| 122 | { | ||
| 123 | static const gate_string_t host_key = GATE_STRING_INIT_STATIC(GATE_HTTP_HEADER_HOST); | ||
| 124 | 1 | gate_util_stringmap_add_string(&request->headers, &host_key, &uri->host); | |
| 125 | } | ||
| 126 | |||
| 127 | } while (0); | ||
| 128 | |||
| 129 | 1 | gate_string_release(&path); | |
| 130 | |||
| 131 | 1 | return ret; | |
| 132 | } | ||
| 133 | |||
| 134 | |||
| 135 | |||
| 136 | 8 | gate_result_t gate_http_request_copy(gate_http_request_t* request, gate_http_request_t const* src) | |
| 137 | { | ||
| 138 | 8 | gate_result_t ret = GATE_RESULT_OUTOFMEMORY; | |
| 139 | 8 | gate_mem_clear(request, sizeof(gate_http_request_t)); | |
| 140 | do | ||
| 141 | { | ||
| 142 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->method, &src->method)) break; |
| 143 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->path, &src->path)) break; |
| 144 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->version, &src->version)) break; |
| 145 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->host, &src->host)) break; |
| 146 | |||
| 147 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->auth_user, &src->auth_user)) break; |
| 148 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->auth_pass, &src->auth_pass)) break; |
| 149 | |||
| 150 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_map_copy(&request->headers, &src->headers)) break; |
| 151 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_set_copy(&request->accept_types, &src->accept_types)) break; |
| 152 | |||
| 153 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->proxy_server, &src->proxy_server)) break; |
| 154 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->proxy_user, &src->proxy_user)) break; |
| 155 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (!gate_string_clone(&request->proxy_pass, &src->proxy_pass)) break; |
| 156 | |||
| 157 | 8 | request->upload_stream = src->upload_stream; | |
| 158 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
|
8 | if (request->upload_stream) |
| 159 | { | ||
| 160 | 5 | gate_object_retain(request->upload_stream); | |
| 161 | } | ||
| 162 | |||
| 163 | 8 | request->connect_timeout_ms = src->connect_timeout_ms; | |
| 164 | 8 | request->send_timeout_ms = src->send_timeout_ms; | |
| 165 | 8 | request->receive_timeout_ms = src->receive_timeout_ms; | |
| 166 | 8 | request->proxy_port = src->proxy_port; | |
| 167 | |||
| 168 | 8 | ret = GATE_RESULT_OK; | |
| 169 | |||
| 170 | } while (0); | ||
| 171 | |||
| 172 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (GATE_FAILED(ret)) |
| 173 | { | ||
| 174 | ✗ | gate_http_request_release(request); | |
| 175 | } | ||
| 176 | 8 | return ret; | |
| 177 | } | ||
| 178 | |||
| 179 | 36 | gate_result_t gate_http_request_release(gate_http_request_t* request) | |
| 180 | { | ||
| 181 | 36 | gate_string_release(&request->method); | |
| 182 | 36 | gate_string_release(&request->path); | |
| 183 | 36 | gate_string_release(&request->version); | |
| 184 | 36 | gate_string_release(&request->host); | |
| 185 | |||
| 186 | 36 | gate_string_release(&request->auth_user); | |
| 187 | 36 | gate_string_release(&request->auth_pass); | |
| 188 | |||
| 189 | 36 | gate_map_destroy(&request->headers); | |
| 190 | 36 | gate_set_destroy(&request->accept_types); | |
| 191 | |||
| 192 | 36 | gate_string_release(&request->proxy_server); | |
| 193 | 36 | gate_string_release(&request->proxy_user); | |
| 194 | 36 | gate_string_release(&request->proxy_pass); | |
| 195 | |||
| 196 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 25 times.
|
36 | if (request->upload_stream != NULL) |
| 197 | { | ||
| 198 | 11 | gate_object_release(request->upload_stream); | |
| 199 | } | ||
| 200 | |||
| 201 | 36 | gate_mem_clear(request, sizeof(gate_http_request_t)); | |
| 202 | 36 | return GATE_RESULT_OK; | |
| 203 | } | ||
| 204 | |||
| 205 | static gate_string_t const default_http_version = GATE_STRING_INIT_STATIC("1.1"); | ||
| 206 | |||
| 207 | 3 | gate_result_t gate_http_request_build_header(gate_http_request_t* request, gate_stream_t* stream) | |
| 208 | { | ||
| 209 | 3 | gate_result_t ret = GATE_RESULT_FAILED; | |
| 210 | |||
| 211 | do | ||
| 212 | { | ||
| 213 | 3 | gate_int64_t content_length = -1; | |
| 214 | gate_map_iterator_t iter, iterend; | ||
| 215 | gate_controlstream_t* ptr_upload; | ||
| 216 | gate_result_t result; | ||
| 217 | 3 | gate_bool_t keep_alive = false; | |
| 218 | |||
| 219 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | gate_stream_print(stream, |
| 220 | GATE_PRINT_STRING, &request->method, | ||
| 221 | GATE_PRINT_CSTR, " ", | ||
| 222 | GATE_PRINT_STRING, &request->path, | ||
| 223 | GATE_PRINT_CSTR, " HTTP/", | ||
| 224 | 3 | GATE_PRINT_STRING, (gate_string_is_empty(&request->version) ? &default_http_version : &request->version), | |
| 225 | GATE_PRINT_CRLF, | ||
| 226 | GATE_PRINT_END); | ||
| 227 | |||
| 228 | 3 | gate_stream_print(stream, | |
| 229 | GATE_PRINT_CSTR, GATE_HTTP_HEADER_HOST, | ||
| 230 | GATE_PRINT_CSTR, ": ", | ||
| 231 | GATE_PRINT_STRING, &request->host, | ||
| 232 | GATE_PRINT_CRLF, GATE_PRINT_END); | ||
| 233 | |||
| 234 | |||
| 235 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
|
3 | if (!gate_set_is_empty(&request->accept_types)) |
| 236 | { | ||
| 237 | 1 | gate_stream_print_cstr(stream, "Accept: "); | |
| 238 | 1 | iter = gate_set_first(&request->accept_types); | |
| 239 | 1 | iterend = gate_set_end(&request->accept_types); | |
| 240 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | while (iter != iterend) |
| 241 | { | ||
| 242 | 1 | gate_string_t const* ptr_key = (gate_string_t const*)gate_map_iterator_key(iter); | |
| 243 | 1 | gate_stream_print_string(stream, ptr_key); | |
| 244 | 1 | iter = gate_set_iterator_next(iter); | |
| 245 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (iter != iterend) |
| 246 | { | ||
| 247 | ✗ | gate_stream_print_cstr(stream, ", "); | |
| 248 | } | ||
| 249 | } | ||
| 250 | 1 | gate_stream_print(stream, GATE_PRINT_CRLF, GATE_PRINT_END); | |
| 251 | } | ||
| 252 | |||
| 253 | 3 | iter = gate_map_first(&request->headers); | |
| 254 | 3 | iterend = gate_map_end(&request->headers); | |
| 255 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3 times.
|
8 | for (; iter != iterend; iter = gate_map_iterator_next(iter)) |
| 256 | { | ||
| 257 | 5 | gate_string_t const* ptr_key = (gate_string_t const*)gate_map_iterator_key(iter); | |
| 258 | 5 | gate_string_t const* ptr_value = (gate_string_t const*)gate_map_iterator_value(iter); | |
| 259 | |||
| 260 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
|
5 | if (gate_string_equals_str_ic(ptr_key, GATE_HTTP_HEADER_CONNECTION)) |
| 261 | { | ||
| 262 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | if (gate_string_equals_str_ic(ptr_value, GATE_HTTP_HEADERVALUE_CONNECTION_KEEPALIVE)) |
| 263 | { | ||
| 264 | 1 | keep_alive = true; | |
| 265 | } | ||
| 266 | 1 | continue; | |
| 267 | } | ||
| 268 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
4 | if (gate_string_equals_str_ic(ptr_key, GATE_HTTP_HEADER_CONTENTLENGTH)) |
| 269 | { | ||
| 270 | 1 | gate_string_parse_int(ptr_value, &content_length); | |
| 271 | 1 | continue; | |
| 272 | } | ||
| 273 | 3 | gate_stream_print(stream, | |
| 274 | GATE_PRINT_STRING, ptr_key, | ||
| 275 | GATE_PRINT_CSTR, ": ", | ||
| 276 | GATE_PRINT_STRING, gate_map_iterator_value(iter), | ||
| 277 | GATE_PRINT_CRLF, | ||
| 278 | GATE_PRINT_END); | ||
| 279 | } | ||
| 280 | |||
| 281 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (request->upload_stream) |
| 282 | { | ||
| 283 | 1 | content_length = -1; /* no content length */ | |
| 284 | } | ||
| 285 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (request->upload_stream) |
| 286 | { | ||
| 287 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (gate_object_implements_interface((gate_object_t*)request->upload_stream, GATE_INTERFACE_NAME_CONTROLSTREAM)) |
| 288 | { | ||
| 289 | ✗ | ptr_upload = (gate_controlstream_t*)request->upload_stream; | |
| 290 | ✗ | result = gate_stream_get_size(ptr_upload, &content_length); | |
| 291 | ✗ | if (GATE_FAILED(result)) | |
| 292 | { | ||
| 293 | ✗ | content_length = -1; /* no content length */ | |
| 294 | ✗ | keep_alive = false; | |
| 295 | } | ||
| 296 | } | ||
| 297 | else | ||
| 298 | { | ||
| 299 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (content_length >= 0) |
| 300 | { | ||
| 301 | /* content length was user-specified -> trust it */ | ||
| 302 | } | ||
| 303 | else | ||
| 304 | { | ||
| 305 | /* end of stream == end of content, no keep alive possible */ | ||
| 306 | 1 | keep_alive = false; | |
| 307 | } | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (content_length >= 0) |
| 312 | { | ||
| 313 | 1 | gate_stream_print(stream, | |
| 314 | GATE_PRINT_CSTR, GATE_HTTP_HEADER_CONTENTLENGTH, | ||
| 315 | GATE_PRINT_CSTR, ": ", | ||
| 316 | GATE_PRINT_I64, content_length, | ||
| 317 | GATE_PRINT_CRLF, GATE_PRINT_END); | ||
| 318 | } | ||
| 319 | |||
| 320 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | gate_stream_print(stream, |
| 321 | GATE_PRINT_CSTR, GATE_HTTP_HEADER_CONNECTION, | ||
| 322 | GATE_PRINT_CSTR, ": ", | ||
| 323 | GATE_PRINT_CSTR, (keep_alive ? GATE_HTTP_HEADERVALUE_CONNECTION_KEEPALIVE : GATE_HTTP_HEADERVALUE_CONNECTION_CLOSE), | ||
| 324 | GATE_PRINT_CRLF, | ||
| 325 | GATE_PRINT_END); | ||
| 326 | |||
| 327 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | gate_util_stringmap_add(&request->headers, |
| 328 | GATE_HTTP_HEADER_CONNECTION, | ||
| 329 | keep_alive ? GATE_HTTP_HEADERVALUE_CONNECTION_KEEPALIVE : GATE_HTTP_HEADERVALUE_CONNECTION_CLOSE); | ||
| 330 | |||
| 331 | /* finish HTTP header */ | ||
| 332 | 3 | gate_stream_print(stream, | |
| 333 | GATE_PRINT_CRLF, | ||
| 334 | GATE_PRINT_END); | ||
| 335 | |||
| 336 | /* generate output string */ | ||
| 337 | 3 | ret = GATE_RESULT_OK; | |
| 338 | } while (0); | ||
| 339 | |||
| 340 | 3 | return ret; | |
| 341 | } | ||
| 342 | |||
| 343 | 2 | gate_result_t gate_http_request_build_upload_chunk(gate_http_request_t const* request, gate_stream_t* stream, gate_size_t chunk_size, gate_size_t* ptr_transferred) | |
| 344 | { | ||
| 345 | gate_result_t ret; | ||
| 346 | 2 | gate_uint64_t transferred = 0; | |
| 347 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (chunk_size == 0) |
| 348 | { | ||
| 349 | 2 | chunk_size = GATE_MAX_COPYBUFFER_LENGTH; | |
| 350 | } | ||
| 351 | 2 | ret = gate_stream_transfer_limit(request->upload_stream, chunk_size, stream, &transferred); | |
| 352 | 2 | *ptr_transferred = (gate_size_t)transferred; | |
| 353 | 2 | return ret; | |
| 354 | } | ||
| 355 | |||
| 356 | |||
| 357 | 27 | gate_result_t gate_http_response_init(gate_http_response_t* response) | |
| 358 | { | ||
| 359 | 27 | gate_result_t ret = GATE_RESULT_FAILED; | |
| 360 | do | ||
| 361 | { | ||
| 362 | 27 | gate_mem_clear(response, sizeof(gate_http_response_t)); | |
| 363 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
|
27 | if (NULL == gate_util_stringmap_create_ex(&response->headers, true, true)) |
| 364 | { | ||
| 365 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
| 366 | ✗ | break; | |
| 367 | } | ||
| 368 | } while (0); | ||
| 369 | 27 | return GATE_RESULT_OK; | |
| 370 | } | ||
| 371 | |||
| 372 | 2 | gate_result_t gate_http_response_copy(gate_http_response_t* response, gate_http_response_t const* src) | |
| 373 | { | ||
| 374 | 2 | gate_result_t ret = GATE_RESULT_OK; | |
| 375 | do | ||
| 376 | { | ||
| 377 | 2 | gate_mem_clear(response, sizeof(gate_http_response_t)); | |
| 378 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_map_copy(&response->headers, &src->headers)) |
| 379 | { | ||
| 380 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
| 381 | ✗ | break; | |
| 382 | } | ||
| 383 | 2 | response->response_stream = src->response_stream; | |
| 384 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (response->response_stream) |
| 385 | { | ||
| 386 | ✗ | gate_object_retain(response->response_stream); | |
| 387 | } | ||
| 388 | 2 | response->status_code = src->status_code; | |
| 389 | 2 | ret = GATE_RESULT_OK; | |
| 390 | } while (0); | ||
| 391 | 2 | return ret; | |
| 392 | } | ||
| 393 | |||
| 394 | 25 | gate_result_t gate_http_response_release(gate_http_response_t* response) | |
| 395 | { | ||
| 396 | 25 | gate_map_destroy(&response->headers); | |
| 397 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 4 times.
|
25 | if (NULL != response->response_stream) |
| 398 | { | ||
| 399 | 21 | gate_object_release(response->response_stream); | |
| 400 | } | ||
| 401 | 25 | gate_mem_clear(response, sizeof(gate_http_response_t)); | |
| 402 | 25 | return GATE_RESULT_OK; | |
| 403 | } | ||
| 404 | |||
| 405 | 69 | char const* gate_http_response_status_text(gate_uint32_t status_code) | |
| 406 | { | ||
| 407 |
65/66✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 1 times.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 1 times.
✓ Branch 22 taken 1 times.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 1 times.
✓ Branch 25 taken 1 times.
✓ Branch 26 taken 1 times.
✓ Branch 27 taken 1 times.
✓ Branch 28 taken 1 times.
✓ Branch 29 taken 1 times.
✓ Branch 30 taken 1 times.
✓ Branch 31 taken 1 times.
✓ Branch 32 taken 1 times.
✓ Branch 33 taken 1 times.
✓ Branch 34 taken 1 times.
✓ Branch 35 taken 1 times.
✓ Branch 36 taken 1 times.
✓ Branch 37 taken 1 times.
✓ Branch 38 taken 1 times.
✓ Branch 39 taken 1 times.
✓ Branch 40 taken 1 times.
✓ Branch 41 taken 1 times.
✓ Branch 42 taken 1 times.
✓ Branch 43 taken 1 times.
✓ Branch 44 taken 1 times.
✓ Branch 45 taken 1 times.
✓ Branch 46 taken 1 times.
✓ Branch 47 taken 1 times.
✓ Branch 48 taken 1 times.
✓ Branch 49 taken 1 times.
✓ Branch 50 taken 1 times.
✓ Branch 51 taken 1 times.
✓ Branch 52 taken 1 times.
✓ Branch 53 taken 1 times.
✓ Branch 54 taken 1 times.
✓ Branch 55 taken 1 times.
✓ Branch 56 taken 1 times.
✓ Branch 57 taken 1 times.
✓ Branch 58 taken 1 times.
✓ Branch 59 taken 1 times.
✓ Branch 60 taken 1 times.
✓ Branch 61 taken 1 times.
✓ Branch 62 taken 1 times.
✓ Branch 63 taken 1 times.
✓ Branch 64 taken 1 times.
✗ Branch 65 not taken.
|
69 | switch (status_code) |
| 408 | { | ||
| 409 | 1 | case 100: return "Continue"; | |
| 410 | 1 | case 101: return "Switching Protocols"; | |
| 411 | 1 | case 102: return "Processing"; | |
| 412 | 1 | case 103: return "Early Hints"; | |
| 413 | 5 | case 200: return "OK"; | |
| 414 | 1 | case 201: return "Created"; | |
| 415 | 1 | case 202: return "Accepted"; | |
| 416 | 1 | case 203: return "Non-Authoritative Information"; | |
| 417 | 1 | case 204: return "No Content"; | |
| 418 | 1 | case 205: return "Reset Content"; | |
| 419 | 1 | case 206: return "Partial Content"; | |
| 420 | 1 | case 207: return "Multi-Status"; | |
| 421 | 1 | case 208: return "Already Reported"; | |
| 422 | 1 | case 226: return "IM Used"; | |
| 423 | 1 | case 300: return "Multiple Choices"; | |
| 424 | 1 | case 301: return "Moved Permanently"; | |
| 425 | 1 | case 302: return "Found"; | |
| 426 | 1 | case 303: return "See Other"; | |
| 427 | 1 | case 304: return "Not Modified"; | |
| 428 | 1 | case 305: return "Use Proxy"; | |
| 429 | 1 | case 306: return "Switch Proxy"; | |
| 430 | 1 | case 307: return "Temporary Redirect"; | |
| 431 | 1 | case 308: return "Permanent Redirect"; | |
| 432 | 1 | case 400: return "Bad Request"; | |
| 433 | 1 | case 401: return "Unauthorized"; | |
| 434 | 1 | case 402: return "Payment Required"; | |
| 435 | 1 | case 403: return "Forbidden"; | |
| 436 | 1 | case 404: return "Not Found"; | |
| 437 | 1 | case 405: return "Method Not Allowed"; | |
| 438 | 1 | case 406: return "Not Acceptable"; | |
| 439 | 1 | case 407: return "Proxy Authentication Required"; | |
| 440 | 1 | case 408: return "Request Time-out"; | |
| 441 | 1 | case 409: return "Conflict"; | |
| 442 | 1 | case 410: return "Gone"; | |
| 443 | 1 | case 411: return "Length Required"; | |
| 444 | 1 | case 412: return "Precondition Failed"; | |
| 445 | 1 | case 413: return "Request Entity Too Large"; | |
| 446 | 1 | case 414: return "Request-URL Too Long"; | |
| 447 | 1 | case 415: return "Unsupported Media Type"; | |
| 448 | 1 | case 416: return "Requested range not satisfiable"; | |
| 449 | 1 | case 417: return "Expectation Failed"; | |
| 450 | 1 | case 418: return "I'm a teapot"; | |
| 451 | 1 | case 420: return "Policy Not Fulfilled"; | |
| 452 | 1 | case 421: return "Misdirected Request"; | |
| 453 | 1 | case 422: return "Unprocessable Entity"; | |
| 454 | 1 | case 423: return "Locked"; | |
| 455 | 1 | case 424: return "Failed Dependency"; | |
| 456 | 1 | case 425: return "Too Early"; | |
| 457 | 1 | case 426: return "Upgrade Required"; | |
| 458 | 1 | case 428: return "Precondition Required"; | |
| 459 | 1 | case 429: return "Too Many Requests"; | |
| 460 | 1 | case 431: return "Request Header Fields Too Large"; | |
| 461 | 1 | case 451: return "Unavailable For Legal Reasons"; | |
| 462 | 1 | case 500: return "Internal Server Error"; | |
| 463 | 1 | case 501: return "Not Implemented"; | |
| 464 | 1 | case 502: return "Bad Gateway"; | |
| 465 | 1 | case 503: return "Service Unavailable"; | |
| 466 | 1 | case 504: return "Gateway Timeout"; | |
| 467 | 1 | case 505: return "HTTP Version not supported"; | |
| 468 | 1 | case 506: return "Variant Also Negotiates"; | |
| 469 | 1 | case 507: return "Insufficient Storage"; | |
| 470 | 1 | case 508: return "Loop Detected"; | |
| 471 | 1 | case 509: return "Bandwidth Limit Exceeded"; | |
| 472 | 1 | case 510: return "Not Extended"; | |
| 473 | 1 | case 511: return "Network Authentication Required"; | |
| 474 | |||
| 475 | } | ||
| 476 | ✗ | return NULL; | |
| 477 | } | ||
| 478 | |||
| 479 | 1 | gate_result_t gate_http_parse_urlencoded_content(gate_string_t const* content, | |
| 480 | gate_flatmap_t* append_to_stringmap) | ||
| 481 | { | ||
| 482 | 1 | gate_result_t ret = GATE_RESULT_OK; | |
| 483 | 1 | gate_size_t start = 0; | |
| 484 | 1 | gate_size_t pos = 0; | |
| 485 | 1 | gate_string_t pair = GATE_STRING_INIT_EMPTY; | |
| 486 | 1 | gate_string_t raw_key = GATE_STRING_INIT_EMPTY; | |
| 487 | 1 | gate_string_t raw_value = GATE_STRING_INIT_EMPTY; | |
| 488 | 1 | gate_string_t key = GATE_STRING_INIT_EMPTY; | |
| 489 | 1 | gate_string_t value = GATE_STRING_INIT_EMPTY; | |
| 490 | 1 | gate_size_t len = gate_string_length(content); | |
| 491 | |||
| 492 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (gate_flatmap_count(append_to_stringmap)) |
| 493 | { | ||
| 494 | ✗ | if (NULL == gate_flatmap_create(append_to_stringmap, &gate_compare_string, | |
| 495 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor, | ||
| 496 | sizeof(gate_string_t), &gate_string_copy_constructor, &gate_string_destructor)) | ||
| 497 | { | ||
| 498 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
4 | while ((start < len) && GATE_SUCCEEDED(ret)) |
| 503 | { | ||
| 504 | 3 | pos = gate_string_char_pos(content, '&', start); | |
| 505 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (GATE_STR_NPOS == pos) |
| 506 | { | ||
| 507 | 1 | gate_string_substr(&pair, content, start, GATE_STR_NPOS); | |
| 508 | 1 | start = len; | |
| 509 | } | ||
| 510 | else | ||
| 511 | { | ||
| 512 | 2 | gate_string_substr(&pair, content, start, pos - start); | |
| 513 | 2 | start = pos + 1; | |
| 514 | } | ||
| 515 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | if (!gate_string_is_empty(&pair)) |
| 516 | { | ||
| 517 | 2 | pos = gate_string_char_pos(&pair, '=', 0); | |
| 518 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (GATE_STR_NPOS == pos) |
| 519 | { | ||
| 520 | ✗ | gate_uri_unescape(&pair, &key); | |
| 521 | } | ||
| 522 | else | ||
| 523 | { | ||
| 524 | 2 | gate_string_substr(&raw_key, &pair, 0, pos); | |
| 525 | 2 | gate_string_substr(&raw_value, &pair, pos + 1, GATE_STR_NPOS); | |
| 526 | 2 | gate_uri_unescape(&raw_key, &key); | |
| 527 | 2 | gate_uri_unescape(&raw_value, &value); | |
| 528 | 2 | gate_string_release(&raw_value); | |
| 529 | 2 | gate_string_release(&raw_key); | |
| 530 | } | ||
| 531 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if (!gate_string_is_empty(&key)) |
| 532 | { | ||
| 533 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (NULL == gate_flatmap_add(append_to_stringmap, &key, &value)) |
| 534 | { | ||
| 535 | ✗ | ret = GATE_RESULT_OUTOFMEMORY; | |
| 536 | } | ||
| 537 | } | ||
| 538 | 2 | gate_string_release(&value); | |
| 539 | 2 | gate_string_release(&key); | |
| 540 | } | ||
| 541 | 3 | gate_string_release(&pair); | |
| 542 | } | ||
| 543 | 1 | return ret; | |
| 544 | } | ||
| 545 | |||
| 546 | 1 | gate_result_t gate_http_build_urlencoded_content(gate_flatmap_t const* stringmap, | |
| 547 | gate_strbuilder_t* append_to_builder) | ||
| 548 | { | ||
| 549 | 1 | gate_result_t ret = GATE_RESULT_OK; | |
| 550 | gate_enumerator_t en; | ||
| 551 | |||
| 552 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (NULL == gate_flatmap_enumerate(stringmap, &en)) |
| 553 | { | ||
| 554 | ✗ | return GATE_RESULT_OUTOFMEMORY; | |
| 555 | } | ||
| 556 | |||
| 557 |
2/2✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
|
3 | for (; gate_enumerator_valid(&en); gate_enumerator_next(&en)) |
| 558 | { | ||
| 559 | 2 | gate_mapping_t const* m = (gate_mapping_t const*)gate_enumerator_get(&en); | |
| 560 | gate_string_t const* ptr_key; | ||
| 561 | gate_string_t const* ptr_value; | ||
| 562 | 2 | gate_string_t key = GATE_STRING_INIT_EMPTY; | |
| 563 | 2 | gate_string_t value = GATE_STRING_INIT_EMPTY; | |
| 564 | |||
| 565 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (NULL == m) |
| 566 | { | ||
| 567 | ✗ | continue; | |
| 568 | } | ||
| 569 | 2 | ptr_key = (gate_string_t const*)m->key; | |
| 570 | 2 | ptr_value = (gate_string_t const*)m->value; | |
| 571 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (gate_string_is_empty(ptr_key)) |
| 572 | { | ||
| 573 | ✗ | continue; | |
| 574 | } | ||
| 575 | 2 | gate_uri_escape(ptr_key, &key); | |
| 576 | 2 | gate_uri_escape(ptr_value, &value); | |
| 577 | 2 | gate_strbuilder_append(append_to_builder, | |
| 578 | GATE_PRINT_CSTR, "&", | ||
| 579 | GATE_PRINT_STRING, &key, | ||
| 580 | GATE_PRINT_CSTR, "=", | ||
| 581 | GATE_PRINT_STRING, &value); | ||
| 582 | 2 | gate_string_release(&key); | |
| 583 | 2 | gate_string_release(&value); | |
| 584 | } | ||
| 585 | 1 | return ret; | |
| 586 | } | ||
| 587 | |||
| 588 | |||
| 589 | typedef struct gate_http_mime_mapping_class | ||
| 590 | { | ||
| 591 | char const* file_ext; | ||
| 592 | gate_string_t const* mime_type; | ||
| 593 | } gate_http_mime_mapping_t; | ||
| 594 | |||
| 595 | static gate_string_t const mimetype_text_plain = GATE_STRING_INIT_STATIC("text/plain"); | ||
| 596 | static gate_string_t const mimetype_text_html = GATE_STRING_INIT_STATIC("text/html"); | ||
| 597 | static gate_string_t const mimetype_text_richtext = GATE_STRING_INIT_STATIC("text/richtext"); | ||
| 598 | static gate_string_t const mimetype_text_css = GATE_STRING_INIT_STATIC("text/css"); | ||
| 599 | static gate_string_t const mimetype_text_xml = GATE_STRING_INIT_STATIC("text/xml"); | ||
| 600 | static gate_string_t const mimetype_text_js = GATE_STRING_INIT_STATIC("text/javascript"); | ||
| 601 | static gate_string_t const mimetype_text_tsv = GATE_STRING_INIT_STATIC("text/tab-separated-values"); | ||
| 602 | static gate_string_t const mimetype_text_setext = GATE_STRING_INIT_STATIC("text/x-setext"); | ||
| 603 | static gate_string_t const mimetype_text_sgml = GATE_STRING_INIT_STATIC("text/x-sgml"); | ||
| 604 | static gate_string_t const mimetype_text_jad = GATE_STRING_INIT_STATIC("text/vnd.sun.j2me.app-descriptor"); | ||
| 605 | static gate_string_t const mimetype_text_wml = GATE_STRING_INIT_STATIC("text/vnd.wap.wml"); | ||
| 606 | |||
| 607 | |||
| 608 | static gate_string_t const mimetype_image_gif = GATE_STRING_INIT_STATIC("image/gif"); | ||
| 609 | static gate_string_t const mimetype_image_jpeg = GATE_STRING_INIT_STATIC("image/jpeg"); | ||
| 610 | static gate_string_t const mimetype_image_tiff = GATE_STRING_INIT_STATIC("image/tiff"); | ||
| 611 | static gate_string_t const mimetype_image_cmu_raster = GATE_STRING_INIT_STATIC("image/cmu-raster"); | ||
| 612 | static gate_string_t const mimetype_image_freehand = GATE_STRING_INIT_STATIC("image/x-freehand"); | ||
| 613 | static gate_string_t const mimetype_image_ief = GATE_STRING_INIT_STATIC("image/ief"); | ||
| 614 | static gate_string_t const mimetype_image_anymap = GATE_STRING_INIT_STATIC("image/x-portable-anymap"); | ||
| 615 | static gate_string_t const mimetype_image_graymap = GATE_STRING_INIT_STATIC("image/x-portable-graymap"); | ||
| 616 | static gate_string_t const mimetype_image_pixmap = GATE_STRING_INIT_STATIC("image/x-portable-pixmap"); | ||
| 617 | static gate_string_t const mimetype_image_rgb = GATE_STRING_INIT_STATIC("image/x-rgb"); | ||
| 618 | static gate_string_t const mimetype_image_windowdump = GATE_STRING_INIT_STATIC("image/x-windowdump"); | ||
| 619 | static gate_string_t const mimetype_image_wbmp = GATE_STRING_INIT_STATIC("image/vnd.wap.wbmp"); | ||
| 620 | |||
| 621 | |||
| 622 | static gate_string_t const mimetype_app_octet_stream = GATE_STRING_INIT_STATIC("application/octet-stream"); | ||
| 623 | static gate_string_t const mimetype_app_zip = GATE_STRING_INIT_STATIC("application/zip"); | ||
| 624 | static gate_string_t const mimetype_app_pdf = GATE_STRING_INIT_STATIC("application/pdf"); | ||
| 625 | static gate_string_t const mimetype_app_postscript = GATE_STRING_INIT_STATIC("application/postscript"); | ||
| 626 | static gate_string_t const mimetype_app_autoconfig = GATE_STRING_INIT_STATIC("application/x-ns-proxy-autoconfig"); | ||
| 627 | static gate_string_t const mimetype_app_acad = GATE_STRING_INIT_STATIC("application/acad"); | ||
| 628 | static gate_string_t const mimetype_app_dxf = GATE_STRING_INIT_STATIC("application/dxf"); | ||
| 629 | static gate_string_t const mimetype_app_mif = GATE_STRING_INIT_STATIC("application/mif"); | ||
| 630 | static gate_string_t const mimetype_app_msword = GATE_STRING_INIT_STATIC("application/msword"); | ||
| 631 | static gate_string_t const mimetype_app_mspowerpoint = GATE_STRING_INIT_STATIC("application/mspowerpoint"); | ||
| 632 | static gate_string_t const mimetype_app_msexcel = GATE_STRING_INIT_STATIC("application/msexcel"); | ||
| 633 | static gate_string_t const mimetype_app_mshelp = GATE_STRING_INIT_STATIC("application/mshelp"); | ||
| 634 | static gate_string_t const mimetype_app_rtf = GATE_STRING_INIT_STATIC("application/rtf"); | ||
| 635 | static gate_string_t const mimetype_app_sh = GATE_STRING_INIT_STATIC("application/x-sh"); | ||
| 636 | static gate_string_t const mimetype_app_csh = GATE_STRING_INIT_STATIC("application/x-csh"); | ||
| 637 | static gate_string_t const mimetype_app_latex = GATE_STRING_INIT_STATIC("application/x-latex"); | ||
| 638 | static gate_string_t const mimetype_app_tar = GATE_STRING_INIT_STATIC("application/x-tar"); | ||
| 639 | static gate_string_t const mimetype_app_bcpio = GATE_STRING_INIT_STATIC("application/x-bcpio"); | ||
| 640 | static gate_string_t const mimetype_app_cpio = GATE_STRING_INIT_STATIC("application/x-cpio"); | ||
| 641 | static gate_string_t const mimetype_app_sv4cpio = GATE_STRING_INIT_STATIC("application/x-sv4cpio"); | ||
| 642 | static gate_string_t const mimetype_app_sv4crc = GATE_STRING_INIT_STATIC("application/x-sv4crc"); | ||
| 643 | static gate_string_t const mimetype_app_hdf = GATE_STRING_INIT_STATIC("application/x-hdf"); | ||
| 644 | static gate_string_t const mimetype_app_ustar = GATE_STRING_INIT_STATIC("application/x-ustar"); | ||
| 645 | static gate_string_t const mimetype_app_shar = GATE_STRING_INIT_STATIC("application/x-shar"); | ||
| 646 | static gate_string_t const mimetype_app_tcl = GATE_STRING_INIT_STATIC("application/x-tcl"); | ||
| 647 | static gate_string_t const mimetype_app_dvi = GATE_STRING_INIT_STATIC("application/x-dvi"); | ||
| 648 | static gate_string_t const mimetype_app_texinfo = GATE_STRING_INIT_STATIC("application/x-texinfo"); | ||
| 649 | static gate_string_t const mimetype_app_troff = GATE_STRING_INIT_STATIC("application/x-troff"); | ||
| 650 | static gate_string_t const mimetype_app_troff_man = GATE_STRING_INIT_STATIC("application/x-troff-man"); | ||
| 651 | static gate_string_t const mimetype_app_troff_me = GATE_STRING_INIT_STATIC("application/x-troff-me"); | ||
| 652 | static gate_string_t const mimetype_app_troff_ms = GATE_STRING_INIT_STATIC("application/x-troff-ms"); | ||
| 653 | static gate_string_t const mimetype_app_netcdf = GATE_STRING_INIT_STATIC("application/x-netcdf"); | ||
| 654 | static gate_string_t const mimetype_app_wais_source = GATE_STRING_INIT_STATIC("application/x-wais-source"); | ||
| 655 | static gate_string_t const mimetype_app_jar = GATE_STRING_INIT_STATIC("application/x-jar"); | ||
| 656 | static gate_string_t const mimetype_app_jnlp = GATE_STRING_INIT_STATIC("application/x-java-jnlp-file"); | ||
| 657 | static gate_string_t const mimetype_app_wmlc = GATE_STRING_INIT_STATIC("application/vnd.wap.wmlc"); | ||
| 658 | static gate_string_t const mimetype_app_wrl = GATE_STRING_INIT_STATIC("application/x-wrl+xml"); | ||
| 659 | |||
| 660 | |||
| 661 | static gate_string_t const mimetype_audio_basic = GATE_STRING_INIT_STATIC("audio/basic"); | ||
| 662 | static gate_string_t const mimetype_audio_aiff = GATE_STRING_INIT_STATIC("audio/x-aiff"); | ||
| 663 | static gate_string_t const mimetype_audio_dspeeh = GATE_STRING_INIT_STATIC("audio/x-dspeeh"); | ||
| 664 | static gate_string_t const mimetype_audio_midi = GATE_STRING_INIT_STATIC("audio/x-midi"); | ||
| 665 | static gate_string_t const mimetype_audio_realaudio = GATE_STRING_INIT_STATIC("audio/x-pn-realaudio"); | ||
| 666 | static gate_string_t const mimetype_audio_realaudio_plugin = GATE_STRING_INIT_STATIC("audio/x-pn-realaudio-plugin"); | ||
| 667 | |||
| 668 | static gate_string_t const mimetype_video_mpeg = GATE_STRING_INIT_STATIC("video/mpeg"); | ||
| 669 | static gate_string_t const mimetype_video_quicktime = GATE_STRING_INIT_STATIC("video/quicktime"); | ||
| 670 | static gate_string_t const mimetype_video_msvideo = GATE_STRING_INIT_STATIC("video/x-msvideo"); | ||
| 671 | static gate_string_t const mimetype_video_sgi_movie = GATE_STRING_INIT_STATIC("video/x-sgi-movie"); | ||
| 672 | |||
| 673 | |||
| 674 | |||
| 675 | |||
| 676 | static gate_http_mime_mapping_t gate_http_default_mime_types[] = | ||
| 677 | { | ||
| 678 | { ".txt", &mimetype_text_plain }, | ||
| 679 | { ".c", &mimetype_text_plain }, | ||
| 680 | { ".cc", &mimetype_text_plain }, | ||
| 681 | { ".cpp", &mimetype_text_plain }, | ||
| 682 | { ".g", &mimetype_text_plain }, | ||
| 683 | { ".h", &mimetype_text_plain }, | ||
| 684 | { ".hh", &mimetype_text_plain }, | ||
| 685 | { ".hpp", &mimetype_text_plain }, | ||
| 686 | { ".m", &mimetype_text_plain }, | ||
| 687 | { ".f90", &mimetype_text_plain }, | ||
| 688 | { ".rtx", &mimetype_text_richtext }, | ||
| 689 | { ".css", &mimetype_text_css }, | ||
| 690 | { ".xml", &mimetype_text_xml }, | ||
| 691 | { ".htm", &mimetype_text_html }, | ||
| 692 | { ".html", &mimetype_text_html }, | ||
| 693 | { ".shtm", &mimetype_text_html }, | ||
| 694 | { ".shtml", &mimetype_text_html }, | ||
| 695 | { ".js", &mimetype_text_js }, | ||
| 696 | { ".tsv", &mimetype_text_tsv }, | ||
| 697 | { ".etx", &mimetype_text_setext }, | ||
| 698 | { ".sgm", &mimetype_text_sgml }, | ||
| 699 | { ".sgml", &mimetype_text_sgml }, | ||
| 700 | { ".jad", &mimetype_text_jad }, | ||
| 701 | { ".wml", &mimetype_text_wml }, | ||
| 702 | |||
| 703 | |||
| 704 | { ".gif", &mimetype_image_gif }, | ||
| 705 | { ".jpeg", &mimetype_image_jpeg }, | ||
| 706 | { ".jpg", &mimetype_image_jpeg }, | ||
| 707 | { ".jpe", &mimetype_image_jpeg }, | ||
| 708 | { ".tiff", &mimetype_image_tiff }, | ||
| 709 | { ".tif", &mimetype_image_tiff }, | ||
| 710 | { ".ras", &mimetype_image_cmu_raster }, | ||
| 711 | { ".fh4", &mimetype_image_freehand }, | ||
| 712 | { ".fh5", &mimetype_image_freehand }, | ||
| 713 | { ".fhc", &mimetype_image_freehand }, | ||
| 714 | { ".ief", &mimetype_image_ief }, | ||
| 715 | { ".pnm", &mimetype_image_anymap }, | ||
| 716 | { ".PBM", &mimetype_image_anymap }, | ||
| 717 | { ".pgm", &mimetype_image_graymap }, | ||
| 718 | { ".ppm", &mimetype_image_pixmap }, | ||
| 719 | { ".rgb", &mimetype_image_rgb }, | ||
| 720 | { ".xwd", &mimetype_image_windowdump }, | ||
| 721 | { ".wbmp", &mimetype_image_wbmp }, | ||
| 722 | |||
| 723 | |||
| 724 | { ".exe", &mimetype_app_octet_stream }, | ||
| 725 | { ".com", &mimetype_app_octet_stream }, | ||
| 726 | { ".dll", &mimetype_app_octet_stream }, | ||
| 727 | { ".bin", &mimetype_app_octet_stream }, | ||
| 728 | { ".class", &mimetype_app_octet_stream }, | ||
| 729 | { ".zip", &mimetype_app_zip }, | ||
| 730 | { ".pdf", &mimetype_app_pdf }, | ||
| 731 | { ".ps", &mimetype_app_postscript }, | ||
| 732 | { ".ai", &mimetype_app_postscript }, | ||
| 733 | { ".eps", &mimetype_app_postscript }, | ||
| 734 | { ".pac", &mimetype_app_autoconfig }, | ||
| 735 | { ".dwg", &mimetype_app_acad }, | ||
| 736 | { ".dxf", &mimetype_app_dxf }, | ||
| 737 | { ".mif", &mimetype_app_mif }, | ||
| 738 | { ".doc", &mimetype_app_msword }, | ||
| 739 | { ".dot", &mimetype_app_msword }, | ||
| 740 | { ".ppt", &mimetype_app_mspowerpoint }, | ||
| 741 | { ".ppz", &mimetype_app_mspowerpoint }, | ||
| 742 | { ".pps", &mimetype_app_mspowerpoint }, | ||
| 743 | { ".pot", &mimetype_app_mspowerpoint }, | ||
| 744 | { ".xls", &mimetype_app_msexcel }, | ||
| 745 | { ".xla", &mimetype_app_msexcel }, | ||
| 746 | { ".hlp", &mimetype_app_mshelp }, | ||
| 747 | { ".chm", &mimetype_app_mshelp }, | ||
| 748 | { ".rtf", &mimetype_app_rtf }, | ||
| 749 | { ".sh", &mimetype_app_sh }, | ||
| 750 | { ".csh", &mimetype_app_csh }, | ||
| 751 | { ".latex", &mimetype_app_latex }, | ||
| 752 | { ".tar", &mimetype_app_tar }, | ||
| 753 | { ".bcpio", &mimetype_app_bcpio }, | ||
| 754 | { ".cpio", &mimetype_app_cpio }, | ||
| 755 | { ".sv4cpio", &mimetype_app_sv4cpio }, | ||
| 756 | { ".sv4crc", &mimetype_app_sv4crc }, | ||
| 757 | { ".hdf", &mimetype_app_hdf }, | ||
| 758 | { ".ustar", &mimetype_app_ustar }, | ||
| 759 | { ".shar", &mimetype_app_shar }, | ||
| 760 | { ".tcl", &mimetype_app_tcl }, | ||
| 761 | { ".dvi", &mimetype_app_dvi }, | ||
| 762 | { ".texinfo", &mimetype_app_texinfo }, | ||
| 763 | { ".texi", &mimetype_app_texinfo }, | ||
| 764 | { ".t", &mimetype_app_troff }, | ||
| 765 | { ".tr", &mimetype_app_troff }, | ||
| 766 | { ".roff", &mimetype_app_troff }, | ||
| 767 | { ".man", &mimetype_app_troff_man }, | ||
| 768 | { ".me", &mimetype_app_troff_me }, | ||
| 769 | { ".ms", &mimetype_app_troff_ms }, | ||
| 770 | { ".nc", &mimetype_app_netcdf }, | ||
| 771 | { ".cdf", &mimetype_app_netcdf }, | ||
| 772 | { ".src", &mimetype_app_wais_source }, | ||
| 773 | { ".jar", &mimetype_app_jar }, | ||
| 774 | { ".jnlp", &mimetype_app_jnlp }, | ||
| 775 | { ".wmlc", &mimetype_app_wmlc }, | ||
| 776 | { ".wrl", &mimetype_app_wrl }, | ||
| 777 | |||
| 778 | |||
| 779 | { ".au", &mimetype_audio_basic }, | ||
| 780 | { ".snd", &mimetype_audio_basic }, | ||
| 781 | { ".aif", &mimetype_audio_aiff }, | ||
| 782 | { ".aiff", &mimetype_audio_aiff }, | ||
| 783 | { ".aifc", &mimetype_audio_aiff }, | ||
| 784 | { ".dus", &mimetype_audio_dspeeh }, | ||
| 785 | { ".cht", &mimetype_audio_dspeeh }, | ||
| 786 | { ".midi", &mimetype_audio_midi }, | ||
| 787 | { ".mid", &mimetype_audio_midi }, | ||
| 788 | { ".ram", &mimetype_audio_realaudio }, | ||
| 789 | { ".ra", &mimetype_audio_realaudio }, | ||
| 790 | { ".rpm", &mimetype_audio_realaudio_plugin }, | ||
| 791 | |||
| 792 | { ".mpeg", &mimetype_video_mpeg }, | ||
| 793 | { ".mpg", &mimetype_video_mpeg }, | ||
| 794 | { ".mpe", &mimetype_video_mpeg }, | ||
| 795 | { ".qt", &mimetype_video_quicktime }, | ||
| 796 | { ".mov", &mimetype_video_quicktime }, | ||
| 797 | { ".avi", &mimetype_video_msvideo }, | ||
| 798 | { ".movie", &mimetype_video_sgi_movie } | ||
| 799 | }; | ||
| 800 | |||
| 801 | static gate_size_t const gate_http_default_mime_types_count = sizeof(gate_http_default_mime_types) / sizeof(gate_http_default_mime_types[0]); | ||
| 802 | |||
| 803 | |||
| 804 | 2 | gate_result_t gate_http_resolve_mime_type(gate_string_t const* file_ext, gate_string_t* mine_type) | |
| 805 | { | ||
| 806 | gate_size_t ndx; | ||
| 807 | |||
| 808 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | for (ndx = 0; ndx != gate_http_default_mime_types_count; ++ndx) |
| 809 | { | ||
| 810 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 56 times.
|
58 | if (gate_string_ends_with_str_ic(file_ext, gate_http_default_mime_types[ndx].file_ext)) |
| 811 | { | ||
| 812 | 2 | gate_string_duplicate(mine_type, gate_http_default_mime_types[ndx].mime_type); | |
| 813 | 2 | return GATE_RESULT_OK; | |
| 814 | } | ||
| 815 | } | ||
| 816 | ✗ | gate_string_duplicate(mine_type, &mimetype_app_octet_stream); | |
| 817 | ✗ | return GATE_RESULT_OK; | |
| 818 | } | ||
| 819 | |||
| 820 | ✗ | char const* gate_http_resolve_mime_type_str(char const* file_ext) | |
| 821 | { | ||
| 822 | gate_result_t result; | ||
| 823 | gate_string_t ext; | ||
| 824 | ✗ | gate_string_t mime = GATE_STRING_INIT_EMPTY; | |
| 825 | ✗ | gate_string_create_static(&ext, file_ext); | |
| 826 | ✗ | result = gate_http_resolve_mime_type(&ext, &mime); | |
| 827 | ✗ | if (GATE_FAILED(result)) | |
| 828 | { | ||
| 829 | ✗ | return NULL; | |
| 830 | } | ||
| 831 | else | ||
| 832 | { | ||
| 833 | ✗ | return mime.str; | |
| 834 | } | ||
| 835 | } | ||
| 836 |