iodine 0.7.6 → 0.7.7
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/CHANGELOG.md +4 -0
- data/ext/iodine/fio.c +30 -11
- data/ext/iodine/fio.h +83 -7
- data/ext/iodine/fiobj_hash.c +5 -2
- data/ext/iodine/http.c +56 -15
- data/ext/iodine/http.h +1 -2
- data/ext/iodine/http_internal.h +2 -2
- data/ext/iodine/iodine_http.c +10 -8
- data/lib/iodine/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f1e30dc08b1f6e19e59689fc251f50d1fe2de15377c36d9d6c0244a3a569352
|
4
|
+
data.tar.gz: 3ea55ee5a0c809ba5f3bbde618beef72a2dd151242f5aadbf2b68c0d3a403d68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0a8c45de3d93f4e7304a172b8111ea8cd0c5e727431fccb06982b930d596c571c3319819d72221dffe82cde14211bdefc1795ffc275fc8a5ba5255036bb81da
|
7
|
+
data.tar.gz: 537d0c329cf43df25ca7318b99d049cc590103e2b65bb90058dc246b6d0442404ec70eda473f6d97d6020f4b7f4163a270f0dcc2e8a9285298fd07ca4c712808
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,10 @@ Please notice that this change log contains changes for upcoming releases as wel
|
|
6
6
|
|
7
7
|
## Changes:
|
8
8
|
|
9
|
+
#### Change log v.0.7.7
|
10
|
+
|
11
|
+
**Fix**: (facil.io) fixed critical issue with cookies, where no more than a single cookie could be set (duplicate headers would be zeroed out before being set). Credit to @ojab for exposing the issue.
|
12
|
+
|
9
13
|
#### Change log v.0.7.6
|
10
14
|
|
11
15
|
**Fix**: (facil.io edge) timeout review was experiencing some errors that could cause timeouts to be ignored. This was fixed in the facil.io edge branch.
|
data/ext/iodine/fio.c
CHANGED
@@ -1264,7 +1264,7 @@ void fio_expected_concurrency(int16_t *threads, int16_t *processes) {
|
|
1264
1264
|
}
|
1265
1265
|
#endif
|
1266
1266
|
*threads = *processes = (int16_t)cpu_count;
|
1267
|
-
if (cpu_count >
|
1267
|
+
if (cpu_count > 3) {
|
1268
1268
|
/* leave a core available for the kernel */
|
1269
1269
|
--(*processes);
|
1270
1270
|
}
|
@@ -1288,7 +1288,7 @@ void fio_expected_concurrency(int16_t *threads, int16_t *processes) {
|
|
1288
1288
|
*processes = -1 * *threads;
|
1289
1289
|
*threads = tmp_threads;
|
1290
1290
|
if (cpu_adjust && (*processes * tmp_threads) >= cpu_count &&
|
1291
|
-
cpu_count >
|
1291
|
+
cpu_count > 3) {
|
1292
1292
|
/* leave a core available for the kernel */
|
1293
1293
|
--*processes;
|
1294
1294
|
}
|
@@ -2734,7 +2734,7 @@ const fio_rw_hook_s FIO_DEFAULT_RW_HOOKS = {
|
|
2734
2734
|
/** Sets a socket hook state (a pointer to the struct). */
|
2735
2735
|
int fio_rw_hook_set(intptr_t uuid, fio_rw_hook_s *rw_hooks, void *udata) {
|
2736
2736
|
if (fio_is_closed(uuid))
|
2737
|
-
|
2737
|
+
goto invalid_uuid;
|
2738
2738
|
if (!rw_hooks->read)
|
2739
2739
|
rw_hooks->read = fio_hooks_default_read;
|
2740
2740
|
if (!rw_hooks->write)
|
@@ -2745,18 +2745,26 @@ int fio_rw_hook_set(intptr_t uuid, fio_rw_hook_s *rw_hooks, void *udata) {
|
|
2745
2745
|
rw_hooks->before_close = fio_hooks_default_before_close;
|
2746
2746
|
if (!rw_hooks->cleanup)
|
2747
2747
|
rw_hooks->cleanup = fio_hooks_default_cleanup;
|
2748
|
-
|
2748
|
+
intptr_t fd = fio_uuid2fd(uuid);
|
2749
2749
|
fio_rw_hook_s *old_rw_hooks;
|
2750
2750
|
void *old_udata;
|
2751
|
-
fio_lock(&fd_data(
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2751
|
+
fio_lock(&fd_data(fd).sock_lock);
|
2752
|
+
if (fd2uuid(fd) != uuid) {
|
2753
|
+
fio_unlock(&fd_data(fd).sock_lock);
|
2754
|
+
goto invalid_uuid;
|
2755
|
+
}
|
2756
|
+
old_rw_hooks = fd_data(fd).rw_hooks;
|
2757
|
+
old_udata = fd_data(fd).rw_udata;
|
2758
|
+
fd_data(fd).rw_hooks = rw_hooks;
|
2759
|
+
fd_data(fd).rw_udata = udata;
|
2760
|
+
fio_unlock(&fd_data(fd).sock_lock);
|
2757
2761
|
if (old_rw_hooks && old_rw_hooks->cleanup)
|
2758
2762
|
old_rw_hooks->cleanup(old_udata);
|
2759
2763
|
return 0;
|
2764
|
+
invalid_uuid:
|
2765
|
+
if (!rw_hooks->cleanup)
|
2766
|
+
rw_hooks->cleanup(udata);
|
2767
|
+
return -1;
|
2760
2768
|
}
|
2761
2769
|
|
2762
2770
|
/* *****************************************************************************
|
@@ -7975,6 +7983,7 @@ FIO_FUNC inline void fio_str_test(void) {
|
|
7975
7983
|
}
|
7976
7984
|
fprintf(stderr, "* reviewing reference counting `fio_str_free2` (2/2).\n");
|
7977
7985
|
fio_str_free2(s);
|
7986
|
+
fprintf(stderr, "* finished reference counting test.\n");
|
7978
7987
|
}
|
7979
7988
|
fio_str_free(&str);
|
7980
7989
|
if (1) {
|
@@ -8032,7 +8041,17 @@ FIO_FUNC inline void fio_str_test(void) {
|
|
8032
8041
|
str = FIO_STR_INIT_STATIC("Welcome");
|
8033
8042
|
fio_str_info_s state = fio_str_write(&str, " Home", 5);
|
8034
8043
|
FIO_ASSERT(state.capa > 0, "Static string not converted to non-static.");
|
8035
|
-
|
8044
|
+
FIO_ASSERT(str.dealloc, "MIssing static string deallocation function"
|
8045
|
+
" after `fio_str_write`.");
|
8046
|
+
|
8047
|
+
fprintf(stderr, "* reviewing `fio_str_detach`.\n");
|
8048
|
+
char *cstr = fio_str_detach(&str);
|
8049
|
+
FIO_ASSERT(cstr, "`fio_str_detach` returned NULL");
|
8050
|
+
FIO_ASSERT(!memcmp(cstr, "Welcome Home\0", 13),
|
8051
|
+
"`fio_str_detach` string error");
|
8052
|
+
fio_free(cstr);
|
8053
|
+
FIO_ASSERT(fio_str_len(&str) == 0, "`fio_str_detach` data wasn't cleared.");
|
8054
|
+
// fio_str_free(&str);
|
8036
8055
|
}
|
8037
8056
|
fprintf(stderr, "* passed.\n");
|
8038
8057
|
}
|
data/ext/iodine/fio.h
CHANGED
@@ -1226,7 +1226,10 @@ typedef struct fio_rw_hook_s {
|
|
1226
1226
|
*/
|
1227
1227
|
ssize_t (*flush)(intptr_t uuid, void *udata);
|
1228
1228
|
/**
|
1229
|
-
* Called to perform cleanup after the socket was closed
|
1229
|
+
* Called to perform cleanup after the socket was closed or a new read/write
|
1230
|
+
* hook was set using `fio_rw_hook_set`.
|
1231
|
+
*
|
1232
|
+
* This callback is always called, even if `fio_rw_hook_set` fails.
|
1230
1233
|
* */
|
1231
1234
|
void (*cleanup)(void *udata);
|
1232
1235
|
} fio_rw_hook_s;
|
@@ -3023,7 +3026,8 @@ typedef struct {
|
|
3023
3026
|
* The `capacity` value should exclude the NUL character (if exists).
|
3024
3027
|
*/
|
3025
3028
|
#define FIO_STR_INIT_STATIC(buffer) \
|
3026
|
-
((fio_str_s){
|
3029
|
+
((fio_str_s){ \
|
3030
|
+
.data = (char *)(buffer), .len = strlen((buffer)), .dealloc = NULL})
|
3027
3031
|
|
3028
3032
|
/**
|
3029
3033
|
* Allocates a new fio_str_s object on the heap and initializes it.
|
@@ -3086,6 +3090,20 @@ FIO_FUNC void fio_str_free2(fio_str_s *s);
|
|
3086
3090
|
inline FIO_FUNC ssize_t fio_str_send_free2(const intptr_t uuid,
|
3087
3091
|
const fio_str_s *str);
|
3088
3092
|
|
3093
|
+
/**
|
3094
|
+
* Returns a C string with the existing data, clearing the `fio_str_s` object's
|
3095
|
+
* String.
|
3096
|
+
*
|
3097
|
+
* Note: the String data is removed from the container, but the container isn't
|
3098
|
+
* freed.
|
3099
|
+
*
|
3100
|
+
* Returns NULL if there's no String data.
|
3101
|
+
*
|
3102
|
+
* Remember to `fio_free` the returned data and - if required - `fio_str_free2`
|
3103
|
+
* the container.
|
3104
|
+
*/
|
3105
|
+
FIO_FUNC char *fio_str_detach(fio_str_s *s);
|
3106
|
+
|
3089
3107
|
/* *****************************************************************************
|
3090
3108
|
String API - String state (data pointers, length, capacity, etc')
|
3091
3109
|
***************************************************************************** */
|
@@ -3394,6 +3412,58 @@ FIO_FUNC void fio_str_free2(fio_str_s *s) {
|
|
3394
3412
|
FIO_FREE(s);
|
3395
3413
|
}
|
3396
3414
|
|
3415
|
+
/**
|
3416
|
+
* Returns a C string with the existing data, clearing the `fio_str_s` object's
|
3417
|
+
* String.
|
3418
|
+
*
|
3419
|
+
* Note: the String data is removed from the container, but the container isn't
|
3420
|
+
* freed.
|
3421
|
+
*
|
3422
|
+
* Returns NULL if there's no String data.
|
3423
|
+
*
|
3424
|
+
* Remember to `fio_free` the returned data and - if required - `fio_str_free2`
|
3425
|
+
* the container.
|
3426
|
+
*/
|
3427
|
+
FIO_FUNC char *fio_str_detach(fio_str_s *s) {
|
3428
|
+
if (!s)
|
3429
|
+
return NULL;
|
3430
|
+
fio_str_info_s i = fio_str_info(s);
|
3431
|
+
if (s->small || !s->data) {
|
3432
|
+
if (!i.len) {
|
3433
|
+
i.data = NULL;
|
3434
|
+
goto finish;
|
3435
|
+
}
|
3436
|
+
/* make a copy */
|
3437
|
+
void *tmp = FIO_MALLOC(i.len + 1);
|
3438
|
+
memcpy(tmp, i.data, i.len + 1);
|
3439
|
+
i.data = tmp;
|
3440
|
+
} else {
|
3441
|
+
if (!i.len && s->data) {
|
3442
|
+
if (s->dealloc)
|
3443
|
+
s->dealloc(s->data);
|
3444
|
+
i.data = NULL;
|
3445
|
+
} else if (s->dealloc != FIO_FREE) {
|
3446
|
+
/* make a copy */
|
3447
|
+
void *tmp = FIO_MALLOC(i.len + 1);
|
3448
|
+
memcpy(tmp, i.data, i.len + 1);
|
3449
|
+
i.data = tmp;
|
3450
|
+
if (s->dealloc)
|
3451
|
+
s->dealloc(s->data);
|
3452
|
+
}
|
3453
|
+
}
|
3454
|
+
finish:
|
3455
|
+
#ifdef FIO_STR_NO_REF
|
3456
|
+
*s = (fio_str_s){.small = 1};
|
3457
|
+
|
3458
|
+
#else
|
3459
|
+
*s = (fio_str_s){
|
3460
|
+
.small = s->small,
|
3461
|
+
.ref = s->ref,
|
3462
|
+
};
|
3463
|
+
#endif
|
3464
|
+
return i.data;
|
3465
|
+
}
|
3466
|
+
|
3397
3467
|
/** Returns the String's length in bytes. */
|
3398
3468
|
inline FIO_FUNC size_t fio_str_len(fio_str_s *s) {
|
3399
3469
|
return (s->small || !s->data) ? (s->small >> 1) : s->len;
|
@@ -3474,8 +3544,8 @@ String Implementation - Memory management
|
|
3474
3544
|
* directly to `mmap` (due to their size, usually over 12KB).
|
3475
3545
|
*/
|
3476
3546
|
#define ROUND_UP_CAPA2WORDS(num) \
|
3477
|
-
(((num + 1) & (sizeof(long double) - 1))
|
3478
|
-
? ((num + 1) | (sizeof(long double) - 1))
|
3547
|
+
((((num) + 1) & (sizeof(long double) - 1)) \
|
3548
|
+
? (((num) + 1) | (sizeof(long double) - 1)) \
|
3479
3549
|
: (num))
|
3480
3550
|
/**
|
3481
3551
|
* Requires the String to have at least `needed` capacity. Returns the current
|
@@ -3499,6 +3569,7 @@ FIO_FUNC fio_str_info_s fio_str_capa_assert(fio_str_s *s, size_t needed) {
|
|
3499
3569
|
memcpy(tmp, s->data, s->len);
|
3500
3570
|
if (s->dealloc)
|
3501
3571
|
s->dealloc(s->data);
|
3572
|
+
s->dealloc = FIO_FREE;
|
3502
3573
|
}
|
3503
3574
|
s->capa = needed;
|
3504
3575
|
s->data = tmp;
|
@@ -4184,9 +4255,14 @@ static FIO_ARY_TYPE const FIO_NAME(s___const_invalid_object);
|
|
4184
4255
|
/* minimizes allocation "dead space" by alligning allocated length to 16bytes */
|
4185
4256
|
#undef FIO_ARY_SIZE2WORDS
|
4186
4257
|
#define FIO_ARY_SIZE2WORDS(size) \
|
4187
|
-
((sizeof(FIO_ARY_TYPE) &
|
4188
|
-
|
4189
|
-
|
4258
|
+
((sizeof(FIO_ARY_TYPE) & 1) \
|
4259
|
+
? (((size) & (~15)) + 16) \
|
4260
|
+
: (sizeof(FIO_ARY_TYPE) & 2) \
|
4261
|
+
? (((size) & (~7)) + 8) \
|
4262
|
+
: (sizeof(FIO_ARY_TYPE) & 4) \
|
4263
|
+
? (((size) & (~3)) + 4) \
|
4264
|
+
: (sizeof(FIO_ARY_TYPE) & 8) ? (((size) & (~1)) + 2) \
|
4265
|
+
: (size))
|
4190
4266
|
|
4191
4267
|
/* *****************************************************************************
|
4192
4268
|
Array API
|
data/ext/iodine/fiobj_hash.c
CHANGED
@@ -25,7 +25,7 @@ License: MIT
|
|
25
25
|
} while (0)
|
26
26
|
#define FIO_SET_OBJ_TYPE FIOBJ
|
27
27
|
#define FIO_SET_OBJ_COMPARE(o1, o2) fiobj_iseq((o1), (o2))
|
28
|
-
#define FIO_SET_OBJ_COPY(dest, obj) ((dest) = (obj))
|
28
|
+
#define FIO_SET_OBJ_COPY(dest, obj) ((dest) = fiobj_dup(obj))
|
29
29
|
#define FIO_SET_OBJ_DESTROY(obj) \
|
30
30
|
do { \
|
31
31
|
fiobj_free((obj)); \
|
@@ -201,6 +201,7 @@ int fiobj_hash_set(FIOBJ hash, FIOBJ key, FIOBJ obj) {
|
|
201
201
|
if (FIOBJ_TYPE_IS(key, FIOBJ_T_STRING))
|
202
202
|
fiobj_str_freeze(key);
|
203
203
|
fio_hash___insert(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, obj, NULL);
|
204
|
+
fiobj_free(obj); /* take ownership - free the user's reference. */
|
204
205
|
return 0;
|
205
206
|
}
|
206
207
|
|
@@ -239,6 +240,7 @@ FIOBJ fiobj_hash_replace(FIOBJ hash, FIOBJ key, FIOBJ obj) {
|
|
239
240
|
assert(hash && FIOBJ_TYPE_IS(hash, FIOBJ_T_HASH));
|
240
241
|
FIOBJ old = FIOBJ_INVALID;
|
241
242
|
fio_hash___insert(&obj2hash(hash)->hash, fiobj_obj2hash(key), key, obj, &old);
|
243
|
+
fiobj_free(obj); /* take ownership - free the user's reference. */
|
242
244
|
return old;
|
243
245
|
}
|
244
246
|
|
@@ -270,7 +272,8 @@ FIOBJ fiobj_hash_remove2(FIOBJ hash, uint64_t hash_value) {
|
|
270
272
|
* Returns -1 on type error or if the object never existed.
|
271
273
|
*/
|
272
274
|
int fiobj_hash_delete(FIOBJ hash, FIOBJ key) {
|
273
|
-
return
|
275
|
+
return fio_hash___remove(&obj2hash(hash)->hash, fiobj_obj2hash(key), key,
|
276
|
+
NULL);
|
274
277
|
}
|
275
278
|
|
276
279
|
/**
|
data/ext/iodine/http.c
CHANGED
@@ -42,11 +42,30 @@ static inline int patch_clock_gettime(int clk_id, struct timespec *t) {
|
|
42
42
|
/* *****************************************************************************
|
43
43
|
SSL/TLS patch
|
44
44
|
***************************************************************************** */
|
45
|
-
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Adds an ALPN protocol callback to the SSL/TLS context.
|
48
|
+
*
|
49
|
+
* The first protocol added will act as the default protocol to be selected.
|
50
|
+
*/
|
51
|
+
void __attribute__((weak))
|
52
|
+
fio_tls_proto_add(void *tls, const char *protocol_name,
|
53
|
+
void (*callback)(intptr_t uuid, void *udata)) {
|
54
|
+
FIO_LOG_FATAL("HTTP SSL/TLS required but unavailable!");
|
55
|
+
exit(-1);
|
56
|
+
(void)tls;
|
57
|
+
(void)protocol_name;
|
58
|
+
(void)callback;
|
59
|
+
}
|
60
|
+
#pragma weak fio_tls_proto_add
|
61
|
+
|
62
|
+
void __attribute__((weak))
|
63
|
+
fio_tls_accept(intptr_t uuid, void *tls, void *udata) {
|
46
64
|
FIO_LOG_FATAL("HTTP SSL/TLS required but unavailable!");
|
47
65
|
exit(-1);
|
48
66
|
(void)uuid;
|
49
67
|
(void)tls;
|
68
|
+
(void)udata;
|
50
69
|
}
|
51
70
|
#pragma weak fio_tls_accept
|
52
71
|
|
@@ -57,11 +76,13 @@ void __attribute__((weak)) fio_tls_accept(intptr_t uuid, void *tls) {
|
|
57
76
|
* The `uuid` should be a socket UUID that is already connected to a peer (i.e.,
|
58
77
|
* the result of `fio_accept`).
|
59
78
|
*/
|
60
|
-
void __attribute__((weak))
|
79
|
+
void __attribute__((weak))
|
80
|
+
fio_tls_connect(intptr_t uuid, void *tls, void *udata) {
|
61
81
|
FIO_LOG_FATAL("HTTP SSL/TLS required but unavailable!");
|
62
82
|
exit(-1);
|
63
83
|
(void)uuid;
|
64
84
|
(void)tls;
|
85
|
+
(void)udata;
|
65
86
|
}
|
66
87
|
#pragma weak fio_tls_connect
|
67
88
|
|
@@ -177,8 +198,7 @@ int http_set_header(http_s *r, FIOBJ name, FIOBJ value) {
|
|
177
198
|
return 0;
|
178
199
|
}
|
179
200
|
/**
|
180
|
-
* Sets a response header
|
181
|
-
* name object (so name objects could be reused in future responses).
|
201
|
+
* Sets a response header.
|
182
202
|
*
|
183
203
|
* Returns -1 on error and 0 on success.
|
184
204
|
*/
|
@@ -907,10 +927,14 @@ static void http_settings_free(http_settings_s *s) {
|
|
907
927
|
Listening to HTTP connections
|
908
928
|
***************************************************************************** */
|
909
929
|
|
930
|
+
static void http_on_server_protocol_http1(intptr_t uuid, void *set) {
|
931
|
+
fio_protocol_s *pr = http1_new(uuid, set, NULL, 0);
|
932
|
+
if (!pr)
|
933
|
+
fio_close(uuid);
|
934
|
+
}
|
935
|
+
|
910
936
|
static void http_on_open(intptr_t uuid, void *set) {
|
911
937
|
static uint8_t at_capa;
|
912
|
-
if (((http_settings_s *)set)->tls)
|
913
|
-
fio_tls_accept(uuid, ((http_settings_s *)set)->tls);
|
914
938
|
fio_timeout_set(uuid, ((http_settings_s *)set)->timeout);
|
915
939
|
if (fio_uuid2fd(uuid) >= ((http_settings_s *)set)->max_clients) {
|
916
940
|
if (!at_capa)
|
@@ -921,9 +945,10 @@ static void http_on_open(intptr_t uuid, void *set) {
|
|
921
945
|
return;
|
922
946
|
}
|
923
947
|
at_capa = 0;
|
924
|
-
|
925
|
-
|
926
|
-
|
948
|
+
if (((http_settings_s *)set)->tls)
|
949
|
+
fio_tls_accept(uuid, ((http_settings_s *)set)->tls, set);
|
950
|
+
else
|
951
|
+
http_on_server_protocol_http1(uuid, set);
|
927
952
|
}
|
928
953
|
|
929
954
|
static void http_on_finish(intptr_t uuid, void *set) {
|
@@ -955,6 +980,9 @@ intptr_t http_listen(const char *port, const char *binding,
|
|
955
980
|
|
956
981
|
http_settings_s *settings = http_settings_new(arg_settings);
|
957
982
|
settings->is_client = 0;
|
983
|
+
if (settings->tls) {
|
984
|
+
fio_tls_proto_add(settings->tls, "http/1.1", http_on_server_protocol_http1);
|
985
|
+
}
|
958
986
|
|
959
987
|
return fio_listen(.port = port, .address = binding,
|
960
988
|
.on_finish = http_on_finish, .on_open = http_on_open,
|
@@ -996,13 +1024,13 @@ static void http_on_close_client(intptr_t uuid, fio_protocol_s *protocol) {
|
|
996
1024
|
http_settings_free(set);
|
997
1025
|
}
|
998
1026
|
|
999
|
-
static void
|
1027
|
+
static void http_on_open_client_perform(http_settings_s *set) {
|
1028
|
+
http_s *h = set->udata;
|
1029
|
+
set->on_response(h);
|
1030
|
+
}
|
1031
|
+
static void http_on_open_client_http1(intptr_t uuid, void *set_) {
|
1000
1032
|
http_settings_s *set = set_;
|
1001
1033
|
http_s *h = set->udata;
|
1002
|
-
set->udata = h->udata;
|
1003
|
-
if (set->tls)
|
1004
|
-
fio_tls_connect(uuid, set->tls);
|
1005
|
-
fio_timeout_set(uuid, set->timeout);
|
1006
1034
|
fio_protocol_s *pr = http1_new(uuid, set, NULL, 0);
|
1007
1035
|
if (!pr) {
|
1008
1036
|
fio_close(uuid);
|
@@ -1016,7 +1044,16 @@ static void http_on_open_client(intptr_t uuid, void *set_) {
|
|
1016
1044
|
}
|
1017
1045
|
h->private_data.flag = (uintptr_t)pr;
|
1018
1046
|
h->private_data.vtbl = http1_vtable();
|
1019
|
-
set
|
1047
|
+
http_on_open_client_perform(set);
|
1048
|
+
}
|
1049
|
+
|
1050
|
+
static void http_on_open_client(intptr_t uuid, void *set_) {
|
1051
|
+
http_settings_s *set = set_;
|
1052
|
+
fio_timeout_set(uuid, set->timeout);
|
1053
|
+
if (set->tls)
|
1054
|
+
fio_tls_connect(uuid, set->tls, set_);
|
1055
|
+
else
|
1056
|
+
http_on_open_client_http1(uuid, set);
|
1020
1057
|
}
|
1021
1058
|
|
1022
1059
|
static void http_on_client_failed(intptr_t uuid, void *set_) {
|
@@ -1127,6 +1164,10 @@ intptr_t http_connect(const char *address,
|
|
1127
1164
|
arg_settings.timeout = 30;
|
1128
1165
|
http_settings_s *settings = http_settings_new(arg_settings);
|
1129
1166
|
settings->is_client = 1;
|
1167
|
+
if (settings->tls) {
|
1168
|
+
fio_tls_proto_add(settings->tls, "http/1.1", http_on_open_client_http1);
|
1169
|
+
}
|
1170
|
+
|
1130
1171
|
if (!arg_settings.ws_timeout)
|
1131
1172
|
settings->ws_timeout = 0; /* allow server to dictate timeout */
|
1132
1173
|
if (!arg_settings.timeout)
|
data/ext/iodine/http.h
CHANGED
@@ -148,8 +148,7 @@ typedef struct {
|
|
148
148
|
int http_set_header(http_s *h, FIOBJ name, FIOBJ value);
|
149
149
|
|
150
150
|
/**
|
151
|
-
* Sets a response header
|
152
|
-
* name object (so name objects could be reused in future responses).
|
151
|
+
* Sets a response header.
|
153
152
|
*
|
154
153
|
* Returns -1 on error and 0 on success.
|
155
154
|
*/
|
data/ext/iodine/http_internal.h
CHANGED
@@ -217,8 +217,8 @@ static inline void set_header_add(FIOBJ hash, FIOBJ name, FIOBJ value) {
|
|
217
217
|
fiobj_ary_push(tmp, old);
|
218
218
|
old = tmp;
|
219
219
|
}
|
220
|
-
fiobj_ary_push(old, value);
|
221
|
-
fiobj_hash_replace(hash, name, old);
|
220
|
+
fiobj_ary_push(old, value); /* value is owned by both hash and array */
|
221
|
+
fiobj_hash_replace(hash, name, old); /* don't free `value` (leave in array) */
|
222
222
|
}
|
223
223
|
|
224
224
|
#endif /* H_HTTP_INTERNAL_H */
|
data/ext/iodine/iodine_http.c
CHANGED
@@ -467,6 +467,7 @@ static int for_each_header_data(VALUE key, VALUE val, VALUE h_) {
|
|
467
467
|
char *val_s = RSTRING_PTR(val);
|
468
468
|
int val_len = RSTRING_LEN(val);
|
469
469
|
// make the headers lowercase
|
470
|
+
|
470
471
|
FIOBJ name = fiobj_str_new(key_s, key_len);
|
471
472
|
{
|
472
473
|
fio_str_info_s tmp = fiobj_obj2cstr(name);
|
@@ -475,16 +476,17 @@ static int for_each_header_data(VALUE key, VALUE val, VALUE h_) {
|
|
475
476
|
}
|
476
477
|
}
|
477
478
|
// scan the value for newline (\n) delimiters
|
478
|
-
|
479
|
-
|
479
|
+
char *pos_s = val_s;
|
480
|
+
char *pos_e = val_s + val_len;
|
481
|
+
while (pos_s < pos_e) {
|
480
482
|
// scanning for newline (\n) delimiters
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
483
|
+
char *const start = pos_s;
|
484
|
+
pos_s = memchr(pos_s, '\n', pos_e - pos_s);
|
485
|
+
if (!pos_s)
|
486
|
+
pos_s = pos_e;
|
487
|
+
http_set_header(h, name, fiobj_str_new(start, (pos_s - start)));
|
485
488
|
// move forward (skip the '\n' if exists)
|
486
|
-
++
|
487
|
-
pos_s = pos_e;
|
489
|
+
++pos_s;
|
488
490
|
}
|
489
491
|
fiobj_free(name);
|
490
492
|
// no errors, return 0
|
data/lib/iodine/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iodine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -244,7 +244,7 @@ licenses:
|
|
244
244
|
- MIT
|
245
245
|
metadata:
|
246
246
|
allowed_push_host: https://rubygems.org
|
247
|
-
post_install_message: 'Thank you for installing Iodine 0.7.
|
247
|
+
post_install_message: 'Thank you for installing Iodine 0.7.7.
|
248
248
|
|
249
249
|
'
|
250
250
|
rdoc_options: []
|