iodine 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/CHANGELOG.md +8 -0
- data/bin/mustache.rb +12 -40
- data/ext/iodine/fio.c +343 -236
- data/ext/iodine/fio.h +419 -183
- data/ext/iodine/fio_cli.c +4 -5
- data/ext/iodine/fiobj_ary.c +2 -3
- data/ext/iodine/fiobj_data.c +1 -1
- data/ext/iodine/fiobj_hash.c +88 -105
- data/ext/iodine/fiobj_json.c +4 -3
- data/ext/iodine/fiobj_numbers.c +1 -1
- data/ext/iodine/fiobj_str.c +5 -5
- data/ext/iodine/fiobject.c +14 -3
- data/ext/iodine/fiobject.h +4 -0
- data/ext/iodine/http.c +62 -77
- data/ext/iodine/http1.c +9 -12
- data/ext/iodine/http_internal.c +15 -6
- data/ext/iodine/http_internal.h +0 -8
- data/ext/iodine/iodine.c +12 -25
- data/ext/iodine/iodine_defer.c +59 -54
- data/ext/iodine/iodine_http.c +4 -32
- data/ext/iodine/iodine_mustache.c +138 -16
- data/ext/iodine/iodine_mustache.h +3 -3
- data/ext/iodine/iodine_store.c +16 -21
- data/ext/iodine/mustache_parser.h +49 -5
- data/ext/iodine/redis_engine.c +31 -31
- data/ext/iodine/websockets.c +11 -5
- data/lib/iodine.rb +13 -1
- data/lib/iodine/mustache.rb +13 -41
- data/lib/iodine/version.rb +1 -1
- metadata +2 -4
- data/ext/iodine/fio_hashmap.h +0 -813
- data/ext/iodine/fio_str.h +0 -1218
data/ext/iodine/fiobject.h
CHANGED
data/ext/iodine/http.c
CHANGED
@@ -173,7 +173,7 @@ int http_set_header2(http_s *r, fio_str_info_s n, fio_str_info_s v) {
|
|
173
173
|
#undef http_set_cookie
|
174
174
|
int http_set_cookie(http_s *h, http_cookie_args_s cookie) {
|
175
175
|
#if DEBUG
|
176
|
-
|
176
|
+
FIO_ASSERT(h, "Can't set cookie for NULL HTTP handler!");
|
177
177
|
#endif
|
178
178
|
if (HTTP_INVALID_HANDLE(h) || cookie.name_len >= 32768 ||
|
179
179
|
cookie.value_len >= 131072) {
|
@@ -194,10 +194,9 @@ int http_set_cookie(http_s *h, http_cookie_args_s cookie) {
|
|
194
194
|
if (invalid_cookie_name_char[(uint8_t)cookie.name[tmp]]) {
|
195
195
|
if (!warn_illegal) {
|
196
196
|
++warn_illegal;
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
cookie.name[tmp], cookie.name);
|
197
|
+
FIO_LOG_WARNING("illegal char 0x%.2x in cookie name (in %s)\n"
|
198
|
+
" automatic %% encoding applied",
|
199
|
+
cookie.name[tmp], cookie.name);
|
201
200
|
}
|
202
201
|
t.data[len++] = '%';
|
203
202
|
t.data[len++] = hex_chars[(cookie.name[tmp] >> 4) & 0x0F];
|
@@ -218,10 +217,9 @@ int http_set_cookie(http_s *h, http_cookie_args_s cookie) {
|
|
218
217
|
if (invalid_cookie_name_char[(uint8_t)cookie.name[tmp]]) {
|
219
218
|
if (!warn_illegal) {
|
220
219
|
++warn_illegal;
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
cookie.name[tmp], cookie.name);
|
220
|
+
FIO_LOG_WARNING("illegal char 0x%.2x in cookie name (in %s)\n"
|
221
|
+
" automatic %% encoding applied",
|
222
|
+
cookie.name[tmp], cookie.name);
|
225
223
|
}
|
226
224
|
t.data[len++] = '%';
|
227
225
|
t.data[len++] = hex_chars[(cookie.name[tmp] >> 4) & 0x0F];
|
@@ -246,10 +244,9 @@ int http_set_cookie(http_s *h, http_cookie_args_s cookie) {
|
|
246
244
|
if (invalid_cookie_value_char[(uint8_t)cookie.value[tmp]]) {
|
247
245
|
if (!warn_illegal) {
|
248
246
|
++warn_illegal;
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
cookie.value[tmp], cookie.name);
|
247
|
+
FIO_LOG_WARNING("illegal char 0x%.2x in cookie value (in %s)\n"
|
248
|
+
" automatic %% encoding applied",
|
249
|
+
cookie.value[tmp], cookie.name);
|
253
250
|
}
|
254
251
|
t.data[len++] = '%';
|
255
252
|
t.data[len++] = hex_chars[(cookie.value[tmp] >> 4) & 0x0F];
|
@@ -270,10 +267,9 @@ int http_set_cookie(http_s *h, http_cookie_args_s cookie) {
|
|
270
267
|
if (invalid_cookie_value_char[(uint8_t)cookie.value[tmp]]) {
|
271
268
|
if (!warn_illegal) {
|
272
269
|
++warn_illegal;
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
cookie.value[tmp], cookie.name);
|
270
|
+
FIO_LOG_WARNING("illegal char 0x%.2x in cookie value (in %s)\n"
|
271
|
+
" automatic %% encoding applied",
|
272
|
+
cookie.value[tmp], cookie.name);
|
277
273
|
}
|
278
274
|
t.data[len++] = '%';
|
279
275
|
t.data[len++] = hex_chars[(cookie.value[tmp] >> 4) & 0x0F];
|
@@ -591,7 +587,7 @@ open_file:
|
|
591
587
|
s = fiobj_obj2cstr(filename);
|
592
588
|
file = open(s.data, O_RDONLY);
|
593
589
|
if (file == -1) {
|
594
|
-
|
590
|
+
FIO_LOG_ERROR("(HTTP) couldn't open file %s!\n", s.data);
|
595
591
|
perror(" ");
|
596
592
|
http_send_error(h, 500);
|
597
593
|
return 0;
|
@@ -704,8 +700,7 @@ int http_push_file(http_s *h, FIOBJ filename, FIOBJ mime_type) {
|
|
704
700
|
#undef http_upgrade2ws
|
705
701
|
int http_upgrade2ws(http_s *h, websocket_settings_s args) {
|
706
702
|
if (!h) {
|
707
|
-
|
708
|
-
"ERROR: `http_upgrade2ws` requires a valid `http_s` handle.");
|
703
|
+
FIO_LOG_ERROR("`http_upgrade2ws` requires a valid `http_s` handle.");
|
709
704
|
goto error;
|
710
705
|
}
|
711
706
|
if (HTTP_INVALID_HANDLE(h))
|
@@ -824,7 +819,7 @@ static void http_on_upgrade_fallback(http_s *h, char *p, size_t i) {
|
|
824
819
|
}
|
825
820
|
static void http_on_response_fallback(http_s *h) { http_send_error(h, 400); }
|
826
821
|
|
827
|
-
http_settings_s *http_settings_new(http_settings_s arg_settings) {
|
822
|
+
static http_settings_s *http_settings_new(http_settings_s arg_settings) {
|
828
823
|
/* TODO: improve locality by unifying malloc to a single call */
|
829
824
|
if (!arg_settings.on_request)
|
830
825
|
arg_settings.on_request = http_on_request_fallback;
|
@@ -891,7 +886,7 @@ static void http_on_open(intptr_t uuid, void *set) {
|
|
891
886
|
fio_timeout_set(uuid, ((http_settings_s *)set)->timeout);
|
892
887
|
if (fio_uuid2fd(uuid) >= ((http_settings_s *)set)->max_clients) {
|
893
888
|
if (!at_capa)
|
894
|
-
|
889
|
+
FIO_LOG_WARNING("HTTP server at capacity");
|
895
890
|
at_capa = 1;
|
896
891
|
http_send_error2(uuid, 503, set);
|
897
892
|
fio_close(uuid);
|
@@ -923,10 +918,9 @@ static void http_on_finish(intptr_t uuid, void *set) {
|
|
923
918
|
#undef http_listen
|
924
919
|
intptr_t http_listen(const char *port, const char *binding,
|
925
920
|
struct http_settings_s arg_settings) {
|
926
|
-
http_lib_init();
|
927
921
|
if (arg_settings.on_request == NULL) {
|
928
|
-
|
929
|
-
|
922
|
+
FIO_LOG_ERROR("http_listen requires the .on_request parameter "
|
923
|
+
"to be set\n");
|
930
924
|
kill(0, SIGINT);
|
931
925
|
exit(11);
|
932
926
|
}
|
@@ -1025,19 +1019,18 @@ static void http_on_client_failed(intptr_t uuid, void *set_) {
|
|
1025
1019
|
intptr_t http_connect(const char *address,
|
1026
1020
|
struct http_settings_s arg_settings) {
|
1027
1021
|
if (!arg_settings.on_response && !arg_settings.on_upgrade) {
|
1028
|
-
|
1029
|
-
|
1022
|
+
FIO_LOG_ERROR("http_connect requires either an on_response "
|
1023
|
+
" or an on_upgrade callback.\n");
|
1030
1024
|
errno = EINVAL;
|
1031
1025
|
goto on_error;
|
1032
1026
|
}
|
1033
|
-
http_lib_init();
|
1034
1027
|
size_t len;
|
1035
1028
|
char *a, *p;
|
1036
1029
|
uint8_t is_websocket = 0;
|
1037
1030
|
uint8_t is_secure = 0;
|
1038
1031
|
FIOBJ path = FIOBJ_INVALID;
|
1039
1032
|
if (!address || (len = strlen(address)) <= 5) {
|
1040
|
-
|
1033
|
+
FIO_LOG_ERROR("http_connect requires a valid address.");
|
1041
1034
|
errno = EINVAL;
|
1042
1035
|
goto on_error;
|
1043
1036
|
}
|
@@ -1050,7 +1043,7 @@ intptr_t http_connect(const char *address,
|
|
1050
1043
|
address += 4;
|
1051
1044
|
len -= 4;
|
1052
1045
|
} else {
|
1053
|
-
|
1046
|
+
FIO_LOG_ERROR("http_connect requires a valid address.");
|
1054
1047
|
errno = EINVAL;
|
1055
1048
|
goto on_error;
|
1056
1049
|
}
|
@@ -1058,22 +1051,18 @@ intptr_t http_connect(const char *address,
|
|
1058
1051
|
if (address[0] == 's') {
|
1059
1052
|
/* TODO: SSL/TLS */
|
1060
1053
|
is_secure = 1;
|
1061
|
-
|
1062
|
-
"just yet.\n");
|
1054
|
+
FIO_LOG_ERROR("http_connect doesn't support TLS/SSL just yet.");
|
1063
1055
|
errno = EINVAL;
|
1064
1056
|
goto on_error;
|
1065
1057
|
} else if (len <= 3 || strncmp(address, "://", 3)) {
|
1066
|
-
|
1058
|
+
FIO_LOG_ERROR("http_connect requires a valid address.");
|
1067
1059
|
errno = EINVAL;
|
1068
1060
|
goto on_error;
|
1069
1061
|
} else {
|
1070
1062
|
len -= 3;
|
1071
1063
|
address += 3;
|
1072
1064
|
a = fio_malloc(len + 1);
|
1073
|
-
|
1074
|
-
perror("FATAL ERROR: http_connect couldn't allocate memory "
|
1075
|
-
"for address parsing");
|
1076
|
-
}
|
1065
|
+
FIO_ASSERT_ALLOC(a);
|
1077
1066
|
memcpy(a, address, len + 1);
|
1078
1067
|
}
|
1079
1068
|
p = memchr(a, '/', len);
|
@@ -1113,7 +1102,7 @@ intptr_t http_connect(const char *address,
|
|
1113
1102
|
if (!arg_settings.timeout)
|
1114
1103
|
settings->timeout = 0; /* allow server to dictate timeout */
|
1115
1104
|
http_s *h = fio_malloc(sizeof(*h));
|
1116
|
-
|
1105
|
+
FIO_ASSERT(h, "HTTP Client handler allocation failed");
|
1117
1106
|
http_s_new(h, 0, http1_vtable());
|
1118
1107
|
h->udata = arg_settings.udata;
|
1119
1108
|
h->status = 0;
|
@@ -1152,8 +1141,8 @@ static void on_websocket_http_connected(http_s *h) {
|
|
1152
1141
|
websocket_settings_s *s = h->udata;
|
1153
1142
|
h->udata = http_settings(h)->udata = NULL;
|
1154
1143
|
if (!h->path) {
|
1155
|
-
|
1156
|
-
"address, assuming root
|
1144
|
+
FIO_LOG_WARNING("(websocket client) path not specified in "
|
1145
|
+
"address, assuming root!");
|
1157
1146
|
h->path = fiobj_str_new("/", 1);
|
1158
1147
|
}
|
1159
1148
|
http_upgrade2ws(h, *s);
|
@@ -1520,8 +1509,7 @@ void http_parse_cookies(http_s *h, uint8_t is_url_encoded) {
|
|
1520
1509
|
if (!h->headers)
|
1521
1510
|
return;
|
1522
1511
|
if (h->cookies && fiobj_hash_count(h->cookies)) {
|
1523
|
-
|
1524
|
-
"WARNING: (http) attempting to parse cookies more than once.\n");
|
1512
|
+
FIO_LOG_WARNING("(http) attempting to parse cookies more than once.");
|
1525
1513
|
return;
|
1526
1514
|
}
|
1527
1515
|
static uint64_t setcookie_header_hash;
|
@@ -1813,7 +1801,6 @@ static void http_mime_parser_on_data(http_mime_parser_s *parser, void *name,
|
|
1813
1801
|
fiobj_str_resize(n, name_len);
|
1814
1802
|
fiobj_str_write(n, "[name]", 6);
|
1815
1803
|
tmp = fiobj_obj2cstr(n);
|
1816
|
-
fprintf(stderr, "filename length %zu\n", filename_len);
|
1817
1804
|
http_add2hash(http_mime_parser2fio(parser)->h->params, tmp.data, tmp.len,
|
1818
1805
|
filename, filename_len, 0);
|
1819
1806
|
fiobj_free(n);
|
@@ -2634,29 +2621,37 @@ parse_path:
|
|
2634
2621
|
/* *****************************************************************************
|
2635
2622
|
Lookup Tables / functions
|
2636
2623
|
***************************************************************************** */
|
2637
|
-
#include <fio_hashmap.h>
|
2638
2624
|
|
2639
|
-
static
|
2625
|
+
static FIOBJ tmp_cpy_obj(FIOBJ o) { return fiobj_dup(o); }
|
2640
2626
|
|
2641
|
-
#define
|
2627
|
+
#define FIO_SET_NAME fio_mime_set
|
2628
|
+
#define FIO_SET_OBJ_TYPE FIOBJ
|
2629
|
+
#define FIO_SET_OBJ_COMPARE(o1, o2) (1)
|
2630
|
+
#define FIO_SET_OBJ_COPY(dest, o) (dest) = tmp_cpy_obj((o))
|
2631
|
+
#define FIO_SET_OBJ_DESTROY(o) fiobj_free((o))
|
2632
|
+
|
2633
|
+
#include <fio.h>
|
2642
2634
|
|
2643
|
-
|
2635
|
+
static fio_mime_set_s mime_types = FIO_SET_INIT;
|
2636
|
+
|
2637
|
+
#define LONGEST_FILE_EXTENSION_LENGTH 15
|
2644
2638
|
|
2645
2639
|
/** Registers a Mime-Type to be associated with the file extension. */
|
2646
2640
|
void http_mimetype_register(char *file_ext, size_t file_ext_len,
|
2647
2641
|
FIOBJ mime_type_str) {
|
2648
|
-
if (!mime_types.map)
|
2649
|
-
fio_hash_new(&mime_types);
|
2650
2642
|
uintptr_t hash = fio_siphash(file_ext, file_ext_len);
|
2651
|
-
|
2652
|
-
|
2653
|
-
|
2654
|
-
|
2655
|
-
|
2656
|
-
|
2643
|
+
if (mime_type_str == FIOBJ_INVALID) {
|
2644
|
+
fio_mime_set_remove(&mime_types, hash, FIOBJ_INVALID);
|
2645
|
+
} else {
|
2646
|
+
FIOBJ old = FIOBJ_INVALID;
|
2647
|
+
fio_mime_set_replace(&mime_types, hash, mime_type_str, &old);
|
2648
|
+
if (old != FIOBJ_INVALID) {
|
2649
|
+
FIO_LOG_WARNING("mime-type collision: %.*s was %s, now %s",
|
2650
|
+
(int)file_ext_len, file_ext, fiobj_obj2cstr(old).data,
|
2651
|
+
fiobj_obj2cstr(mime_type_str).data);
|
2652
|
+
fiobj_free(old);
|
2653
|
+
}
|
2657
2654
|
}
|
2658
|
-
#endif
|
2659
|
-
fiobj_free(old);
|
2660
2655
|
}
|
2661
2656
|
|
2662
2657
|
/**
|
@@ -2664,11 +2659,11 @@ void http_mimetype_register(char *file_ext, size_t file_ext_len,
|
|
2664
2659
|
* Remember to call `fiobj_free`.
|
2665
2660
|
*/
|
2666
2661
|
FIOBJ http_mimetype_find(char *file_ext, size_t file_ext_len) {
|
2667
|
-
if (!mime_types.map) {
|
2668
|
-
http_lib_init();
|
2669
|
-
}
|
2670
2662
|
uintptr_t hash = fio_siphash(file_ext, file_ext_len);
|
2671
|
-
|
2663
|
+
FIOBJ *result = fio_mime_set_find(&mime_types, hash, FIOBJ_INVALID);
|
2664
|
+
if (result)
|
2665
|
+
return fiobj_dup(*result);
|
2666
|
+
return FIOBJ_INVALID;
|
2672
2667
|
}
|
2673
2668
|
|
2674
2669
|
/**
|
@@ -2709,19 +2704,12 @@ finish:
|
|
2709
2704
|
return mimetype;
|
2710
2705
|
}
|
2711
2706
|
|
2712
|
-
/** Clears the Mime-Type registry (it will be
|
2707
|
+
/** Clears the Mime-Type registry (it will be empty afterthis call). */
|
2713
2708
|
void http_mimetype_clear(void) {
|
2714
|
-
|
2715
|
-
|
2716
|
-
/* rotate data and reinitialize state */
|
2717
|
-
fio_hash_s old = mime_types;
|
2718
|
-
mime_types = (fio_hash_s)FIO_HASH_INIT;
|
2719
|
-
FIOBJ old_date = current_date;
|
2709
|
+
fio_mime_set_free(&mime_types);
|
2710
|
+
fiobj_free(current_date);
|
2720
2711
|
current_date = FIOBJ_INVALID;
|
2721
2712
|
last_date_added = 0;
|
2722
|
-
/* free ols memory / objects */
|
2723
|
-
FIO_HASH_FOR_FREE(&old, obj) { fiobj_free((FIOBJ)obj->obj); }
|
2724
|
-
fiobj_free(old_date);
|
2725
2713
|
}
|
2726
2714
|
|
2727
2715
|
/**
|
@@ -2849,11 +2837,8 @@ fio_str_info_s http_status2str(uintptr_t status) {
|
|
2849
2837
|
#if DEBUG
|
2850
2838
|
void http_tests(void) {
|
2851
2839
|
fprintf(stderr, "=== Testing HTTP helpers\n");
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
fprintf(stderr, "Testing failed.\n"); \
|
2856
|
-
exit(-1); \
|
2857
|
-
}
|
2840
|
+
FIOBJ html_mime = http_mimetype_find("html", 4);
|
2841
|
+
FIO_ASSERT(html_mime,
|
2842
|
+
"HTML mime-type not found! Mime-Type registry invalid!\n");
|
2858
2843
|
}
|
2859
2844
|
#endif
|
data/ext/iodine/http1.c
CHANGED
@@ -248,7 +248,7 @@ static int http1_push_file(http_s *h, FIOBJ filename, FIOBJ mime_type) {
|
|
248
248
|
/**
|
249
249
|
* Called befor a pause task,
|
250
250
|
*/
|
251
|
-
void http1_on_pause(http_s *h, http_fio_protocol_s *pr) {
|
251
|
+
static void http1_on_pause(http_s *h, http_fio_protocol_s *pr) {
|
252
252
|
((http1pr_s *)pr)->stop = 1;
|
253
253
|
fio_suspend(pr->uuid);
|
254
254
|
(void)h;
|
@@ -257,14 +257,14 @@ void http1_on_pause(http_s *h, http_fio_protocol_s *pr) {
|
|
257
257
|
/**
|
258
258
|
* called after the resume task had completed.
|
259
259
|
*/
|
260
|
-
void http1_on_resume(http_s *h, http_fio_protocol_s *pr) {
|
260
|
+
static void http1_on_resume(http_s *h, http_fio_protocol_s *pr) {
|
261
261
|
if (!((http1pr_s *)pr)->stop) {
|
262
262
|
fio_force_event(pr->uuid, FIO_EVENT_ON_DATA);
|
263
263
|
}
|
264
264
|
(void)h;
|
265
265
|
}
|
266
266
|
|
267
|
-
intptr_t http1_hijack(http_s *h, fio_str_info_s *leftover) {
|
267
|
+
static intptr_t http1_hijack(http_s *h, fio_str_info_s *leftover) {
|
268
268
|
if (leftover) {
|
269
269
|
intptr_t len =
|
270
270
|
handle2pr(h)->buf_len -
|
@@ -610,10 +610,9 @@ static int http1_on_header(http1_parser_s *parser, char *name, size_t name_len,
|
|
610
610
|
FIOBJ sym;
|
611
611
|
FIOBJ obj;
|
612
612
|
if (!http1_pr2handle(parser2http(parser)).headers) {
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
name, data);
|
613
|
+
FIO_LOG_ERROR("(http1 parse ordering error) missing HashMap for header "
|
614
|
+
"%s: %s",
|
615
|
+
name, data);
|
617
616
|
http_send_error2(500, parser2http(parser)->p.uuid,
|
618
617
|
parser2http(parser)->p.settings);
|
619
618
|
return -1;
|
@@ -624,8 +623,7 @@ static int http1_on_header(http1_parser_s *parser, char *name, size_t name_len,
|
|
624
623
|
fiobj_hash_count(http1_pr2handle(parser2http(parser)).headers) >
|
625
624
|
HTTP_MAX_HEADER_COUNT) {
|
626
625
|
if (parser2http(parser)->p.settings->log) {
|
627
|
-
|
628
|
-
"WARNING: (http security alert) header flood detected.\n");
|
626
|
+
FIO_LOG_WARNING("(HTTP) security alert - header flood detected.");
|
629
627
|
}
|
630
628
|
http_send_error(&http1_pr2handle(parser2http(parser)), 413);
|
631
629
|
return -1;
|
@@ -745,8 +743,7 @@ static void http1_on_data_first_time(intptr_t uuid, fio_protocol_s *protocol) {
|
|
745
743
|
/* ensure future reads skip this first time HTTP/2.0 test */
|
746
744
|
p->p.protocol.on_data = http1_on_data;
|
747
745
|
if (i >= 24 && !memcmp(p->buf, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", 24)) {
|
748
|
-
|
749
|
-
"ERROR: unsupported HTTP/2 attempeted using prior knowledge.\n");
|
746
|
+
FIO_LOG_ERROR("unsupported HTTP/2 attempeted using prior knowledge.");
|
750
747
|
fio_close(uuid);
|
751
748
|
return;
|
752
749
|
}
|
@@ -767,7 +764,7 @@ fio_protocol_s *http1_new(uintptr_t uuid, http_settings_s *settings,
|
|
767
764
|
if (unread_data && unread_length > HTTP_MAX_HEADER_LENGTH)
|
768
765
|
return NULL;
|
769
766
|
http1pr_s *p = malloc(sizeof(*p) + HTTP_MAX_HEADER_LENGTH);
|
770
|
-
|
767
|
+
FIO_ASSERT_ALLOC(p);
|
771
768
|
*p = (http1pr_s){
|
772
769
|
.p.protocol =
|
773
770
|
{
|
data/ext/iodine/http_internal.c
CHANGED
@@ -27,8 +27,10 @@ void http_on_request_handler______internal(http_s *h,
|
|
27
27
|
if (1) {
|
28
28
|
/* test for Host header and avoid duplicates */
|
29
29
|
FIOBJ tmp = fiobj_hash_get2(h->headers, host_hash);
|
30
|
-
if (!tmp)
|
30
|
+
if (!tmp) {
|
31
31
|
http_send_error(h, 400);
|
32
|
+
return;
|
33
|
+
}
|
32
34
|
if (FIOBJ_TYPE_IS(tmp, FIOBJ_T_ARRAY)) {
|
33
35
|
fiobj_hash_set(h->headers, HTTP_HEADER_HOST, fiobj_ary_pop(tmp));
|
34
36
|
}
|
@@ -94,7 +96,7 @@ int http_send_error2(size_t error, intptr_t uuid, http_settings_s *settings) {
|
|
94
96
|
return -1;
|
95
97
|
fio_protocol_s *pr = http1_new(uuid, settings, NULL, 0);
|
96
98
|
http_s *r = fio_malloc(sizeof(*r));
|
97
|
-
|
99
|
+
FIO_ASSERT(pr, "Couldn't allocate response object for error report.")
|
98
100
|
http_s_new(r, (http_fio_protocol_s *)pr, http1_vtable());
|
99
101
|
int ret = http_send_error(r, error);
|
100
102
|
fio_close(uuid);
|
@@ -136,8 +138,15 @@ FIOBJ HTTP_HVALUE_WS_UPGRADE;
|
|
136
138
|
FIOBJ HTTP_HVALUE_WS_VERSION;
|
137
139
|
FIOBJ HTTP_HVALUE_SSE_MIME;
|
138
140
|
|
139
|
-
static void
|
140
|
-
|
141
|
+
static void http_lib_init(void *ignr_);
|
142
|
+
static void http_lib_cleanup(void *ignr_);
|
143
|
+
static __attribute__((constructor)) void http_lib_constructor(void) {
|
144
|
+
fio_state_callback_add(FIO_CALL_ON_INITIALIZE, http_lib_init, NULL);
|
145
|
+
fio_state_callback_add(FIO_CALL_AT_EXIT, http_lib_cleanup, NULL);
|
146
|
+
}
|
147
|
+
|
148
|
+
static void http_lib_cleanup(void *ignr_) {
|
149
|
+
(void)ignr_;
|
141
150
|
http_mimetype_clear();
|
142
151
|
#define HTTPLIB_RESET(x) \
|
143
152
|
fiobj_free(x); \
|
@@ -176,10 +185,10 @@ static void http_lib_cleanup(void *ignr) {
|
|
176
185
|
#undef HTTPLIB_RESET
|
177
186
|
}
|
178
187
|
|
179
|
-
void http_lib_init(void) {
|
188
|
+
static void http_lib_init(void *ignr_) {
|
189
|
+
(void)ignr_;
|
180
190
|
if (HTTP_HEADER_ACCEPT_RANGES)
|
181
191
|
return;
|
182
|
-
fio_state_callback_add(FIO_CALL_AT_EXIT, http_lib_cleanup, NULL);
|
183
192
|
HTTP_HEADER_ACCEPT = fiobj_str_new("accept", 6);
|
184
193
|
HTTP_HEADER_ACCEPT_RANGES = fiobj_str_new("accept-ranges", 13);
|
185
194
|
HTTP_HEADER_CACHE_CONTROL = fiobj_str_new("cache-control", 13);
|
data/ext/iodine/http_internal.h
CHANGED
@@ -17,10 +17,6 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
17
17
|
#include <arpa/inet.h>
|
18
18
|
#include <errno.h>
|
19
19
|
|
20
|
-
/* *****************************************************************************
|
21
|
-
Library initialization
|
22
|
-
***************************************************************************** */
|
23
|
-
void http_lib_init(void);
|
24
20
|
/* *****************************************************************************
|
25
21
|
Types
|
26
22
|
***************************************************************************** */
|
@@ -197,10 +193,6 @@ static inline void http_sse_destroy(http_sse_internal_s *sse) {
|
|
197
193
|
Helpers
|
198
194
|
***************************************************************************** */
|
199
195
|
|
200
|
-
#define HTTP_ASSERT(x, m) \
|
201
|
-
if (!x) \
|
202
|
-
perror("FATAL ERROR: (http)" m), exit(errno);
|
203
|
-
|
204
196
|
/** sets an outgoing header only if it doesn't exist */
|
205
197
|
static inline void set_header_if_missing(FIOBJ hash, FIOBJ name, FIOBJ value) {
|
206
198
|
FIOBJ old = fiobj_hash_replace(hash, name, value);
|