iodine 0.7.33 → 0.7.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/ext/iodine/fio.c +21 -16
- data/ext/iodine/fio.h +15 -15
- data/ext/iodine/fio_cli.c +5 -5
- data/ext/iodine/fio_tls_missing.c +2 -1
- data/ext/iodine/fio_tls_openssl.c +1 -0
- data/ext/iodine/fiobj4fio.h +1 -1
- data/ext/iodine/fiobj_numbers.h +4 -2
- data/ext/iodine/http.c +19 -7
- data/ext/iodine/http.h +1 -1
- data/ext/iodine/http1.c +8 -9
- data/ext/iodine/iodine_mustache.c +1 -2
- data/iodine.gemspec +2 -1
- data/lib/iodine/mustache.rb +8 -6
- data/lib/iodine/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37df76fb8d575cf00bba0d36342aa6eabd5fba95a4d2940b61ce9b3026082dc1
|
4
|
+
data.tar.gz: 0a5f7fe186c7c824d15959cbabaa71edaffc8159780a7054a54bf959f36b465a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 304dda003c1272727bc279126cc008c27cff83233080ede66817dcb1a3849e149f4b64765642705020013e8d7817726dcbb7039eff8809cf63229cff861a3be7
|
7
|
+
data.tar.gz: 27cdeee27782a72ea42c931fb43f09660a8627fdb26c9afb4ce084047b0a10b4e8648adb660f796c1ac12db05fdf011306e2b0dfeaae57212b0f45a21503e39c
|
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.34
|
10
|
+
|
11
|
+
**Security**: (`facil.io`, `http`) updated to facil.io 0.7.3, incorporating it's bug fixes and security updates.
|
12
|
+
|
9
13
|
#### Change log v.0.7.33
|
10
14
|
|
11
15
|
**Fix**: (`iodine`) exception protection would fail and crash if the exception throws wasn't of type `Exception`. I'm not sure how this would happen, but on some Ruby versions it appeared to have occur, maybe where a custom `raise` would be called with a non-exception type. The issue was fixed by testing for the availability of the `message` and `backtrace` functions. Credit to Jan Biedermann (@janbiedermann) for exposing this issue (#76).
|
data/ext/iodine/fio.c
CHANGED
@@ -1178,12 +1178,13 @@ static inline void fio_mark_time(void) {
|
|
1178
1178
|
/** Calculates the due time for a task, given it's interval */
|
1179
1179
|
static struct timespec fio_timer_calc_due(size_t interval) {
|
1180
1180
|
struct timespec now = fio_last_tick();
|
1181
|
-
if (interval
|
1182
|
-
|
1183
|
-
|
1181
|
+
if (interval >= 1000) {
|
1182
|
+
unsigned long long secs = interval / 1000;
|
1183
|
+
now.tv_sec += secs;
|
1184
|
+
interval -= secs * 1000;
|
1184
1185
|
}
|
1185
1186
|
now.tv_nsec += (interval * 1000000UL);
|
1186
|
-
if (now.tv_nsec
|
1187
|
+
if (now.tv_nsec >= 1000000000L) {
|
1187
1188
|
now.tv_nsec -= 1000000000L;
|
1188
1189
|
now.tv_sec += 1;
|
1189
1190
|
}
|
@@ -1346,7 +1347,7 @@ Section Start Marker
|
|
1346
1347
|
***************************************************************************** */
|
1347
1348
|
|
1348
1349
|
volatile uint8_t fio_signal_children_flag = 0;
|
1349
|
-
|
1350
|
+
volatile fio_lock_i fio_signal_set_flag = 0;
|
1350
1351
|
/* store old signal handlers to propegate signal handling */
|
1351
1352
|
static struct sigaction fio_old_sig_chld;
|
1352
1353
|
static struct sigaction fio_old_sig_pipe;
|
@@ -1415,7 +1416,7 @@ static void sig_int_handler(int sig) {
|
|
1415
1416
|
break;
|
1416
1417
|
}
|
1417
1418
|
/* propagate signale handling to previous existing handler (if any) */
|
1418
|
-
if (old->sa_handler != SIG_IGN && old->sa_handler != SIG_DFL)
|
1419
|
+
if (old && old->sa_handler != SIG_IGN && old->sa_handler != SIG_DFL)
|
1419
1420
|
old->sa_handler(sig);
|
1420
1421
|
}
|
1421
1422
|
|
@@ -1423,7 +1424,7 @@ static void sig_int_handler(int sig) {
|
|
1423
1424
|
static void fio_signal_handler_setup(void) {
|
1424
1425
|
/* setup signal handling */
|
1425
1426
|
struct sigaction act;
|
1426
|
-
if (
|
1427
|
+
if (fio_trylock(&fio_signal_set_flag))
|
1427
1428
|
return;
|
1428
1429
|
|
1429
1430
|
memset(&act, 0, sizeof(act));
|
@@ -1457,8 +1458,9 @@ static void fio_signal_handler_setup(void) {
|
|
1457
1458
|
|
1458
1459
|
void fio_signal_handler_reset(void) {
|
1459
1460
|
struct sigaction old;
|
1460
|
-
if (
|
1461
|
+
if (fio_signal_set_flag)
|
1461
1462
|
return;
|
1463
|
+
fio_unlock(&fio_signal_set_flag);
|
1462
1464
|
memset(&old, 0, sizeof(old));
|
1463
1465
|
sigaction(SIGINT, &fio_old_sig_int, &old);
|
1464
1466
|
sigaction(SIGTERM, &fio_old_sig_term, &old);
|
@@ -2968,7 +2970,7 @@ ssize_t fio_flush(intptr_t uuid) {
|
|
2968
2970
|
goto test_errno;
|
2969
2971
|
}
|
2970
2972
|
|
2971
|
-
if (uuid_data(uuid).packet_count >=
|
2973
|
+
if (uuid_data(uuid).packet_count >= FIO_SLOWLORIS_LIMIT &&
|
2972
2974
|
uuid_data(uuid).packet == old_packet &&
|
2973
2975
|
uuid_data(uuid).sent >= old_sent &&
|
2974
2976
|
(uuid_data(uuid).sent - old_sent) < 32768) {
|
@@ -3533,11 +3535,12 @@ static void __attribute__((destructor)) fio_lib_destroy(void) {
|
|
3533
3535
|
fio_data->active = 0;
|
3534
3536
|
fio_on_fork();
|
3535
3537
|
fio_defer_perform();
|
3538
|
+
fio_timer_clear_all();
|
3539
|
+
fio_defer_perform();
|
3536
3540
|
fio_state_callback_force(FIO_CALL_AT_EXIT);
|
3537
3541
|
fio_state_callback_clear_all();
|
3538
3542
|
fio_defer_perform();
|
3539
3543
|
fio_poll_close();
|
3540
|
-
fio_timer_clear_all();
|
3541
3544
|
fio_free(fio_data);
|
3542
3545
|
/* memory library destruction must be last */
|
3543
3546
|
fio_mem_destroy();
|
@@ -3811,15 +3814,16 @@ static void fio_worker_cleanup(void) {
|
|
3811
3814
|
fio_force_close(fd2uuid(i));
|
3812
3815
|
}
|
3813
3816
|
}
|
3814
|
-
|
3815
|
-
fio_state_callback_force(FIO_CALL_ON_FINISH);
|
3817
|
+
fio_timer_clear_all();
|
3816
3818
|
fio_defer_perform();
|
3817
3819
|
if (!fio_data->is_worker) {
|
3818
|
-
|
3820
|
+
kill(0, SIGINT);
|
3819
3821
|
while (wait(NULL) != -1)
|
3820
3822
|
;
|
3821
3823
|
}
|
3822
3824
|
fio_defer_perform();
|
3825
|
+
fio_state_callback_force(FIO_CALL_ON_FINISH);
|
3826
|
+
fio_defer_perform();
|
3823
3827
|
fio_signal_handler_reset();
|
3824
3828
|
if (fio_data->parent == getpid()) {
|
3825
3829
|
FIO_LOG_INFO(" --- Shutdown Complete ---\n");
|
@@ -5125,7 +5129,7 @@ struct subscription_s {
|
|
5125
5129
|
void *udata1;
|
5126
5130
|
void *udata2;
|
5127
5131
|
/** reference counter. */
|
5128
|
-
uintptr_t ref;
|
5132
|
+
volatile uintptr_t ref;
|
5129
5133
|
/** prevents the callback from running concurrently for multiple messages. */
|
5130
5134
|
fio_lock_i lock;
|
5131
5135
|
fio_lock_i unsubscribed;
|
@@ -6202,7 +6206,7 @@ static void fio_cluster_listen_on_close(intptr_t uuid,
|
|
6202
6206
|
(int)getpid());
|
6203
6207
|
#endif
|
6204
6208
|
if (fio_data->active)
|
6205
|
-
|
6209
|
+
kill(0, SIGINT);
|
6206
6210
|
}
|
6207
6211
|
(void)uuid;
|
6208
6212
|
}
|
@@ -6244,6 +6248,7 @@ static void fio_cluster_client_handler(struct cluster_pr_s *pr) {
|
|
6244
6248
|
break;
|
6245
6249
|
case FIO_CLUSTER_MSG_SHUTDOWN:
|
6246
6250
|
fio_stop();
|
6251
|
+
kill(getpid(), SIGINT);
|
6247
6252
|
case FIO_CLUSTER_MSG_ERROR: /* fallthrough */
|
6248
6253
|
case FIO_CLUSTER_MSG_PING: /* fallthrough */
|
6249
6254
|
case FIO_CLUSTER_MSG_ROOT: /* fallthrough */
|
@@ -6498,7 +6503,7 @@ static void fio_pubsub_on_fork(void) {
|
|
6498
6503
|
/** Signals children (or self) to shutdown) - NOT signal safe. */
|
6499
6504
|
static void fio_cluster_signal_children(void) {
|
6500
6505
|
if (fio_parent_pid() != getpid()) {
|
6501
|
-
|
6506
|
+
kill(getpid(), SIGINT);
|
6502
6507
|
return;
|
6503
6508
|
}
|
6504
6509
|
fio_cluster_server_sender(fio_msg_internal_create(0, FIO_CLUSTER_MSG_SHUTDOWN,
|
data/ext/iodine/fio.h
CHANGED
@@ -109,8 +109,8 @@ Version and helper macros
|
|
109
109
|
|
110
110
|
#define FIO_VERSION_MAJOR 0
|
111
111
|
#define FIO_VERSION_MINOR 7
|
112
|
-
#define FIO_VERSION_PATCH
|
113
|
-
#define FIO_VERSION_BETA
|
112
|
+
#define FIO_VERSION_PATCH 3
|
113
|
+
#define FIO_VERSION_BETA 0
|
114
114
|
|
115
115
|
/* Automatically convert version data to a string constant - ignore these two */
|
116
116
|
#define FIO_MACRO2STR_STEP2(macro) #macro
|
@@ -1250,7 +1250,7 @@ inline FIO_FUNC ssize_t fio_write(const intptr_t uuid, const void *buffer,
|
|
1250
1250
|
inline FIO_FUNC ssize_t fio_sendfile(intptr_t uuid, intptr_t source_fd,
|
1251
1251
|
off_t offset, size_t length) {
|
1252
1252
|
return fio_write2(uuid, .data.fd = source_fd, .length = length, .is_fd = 1,
|
1253
|
-
.offset = offset);
|
1253
|
+
.offset = (uintptr_t)offset);
|
1254
1254
|
}
|
1255
1255
|
|
1256
1256
|
/**
|
@@ -2984,8 +2984,8 @@ FIO_FUNC inline void fio_reschedule_thread(void) {
|
|
2984
2984
|
|
2985
2985
|
/** Nanosleep the thread - a blocking throttle. */
|
2986
2986
|
FIO_FUNC inline void fio_throttle_thread(size_t nano_sec) {
|
2987
|
-
const struct timespec tm = {.tv_nsec = (nano_sec % 1000000000),
|
2988
|
-
.tv_sec = (nano_sec / 1000000000)};
|
2987
|
+
const struct timespec tm = {.tv_nsec = (long)(nano_sec % 1000000000),
|
2988
|
+
.tv_sec = (time_t)(nano_sec / 1000000000)};
|
2989
2989
|
nanosleep(&tm, NULL);
|
2990
2990
|
}
|
2991
2991
|
|
@@ -5494,10 +5494,10 @@ Done
|
|
5494
5494
|
* Note: FIO_SET_HASH_TYPE should, normaly be left alone (uintptr_t is
|
5495
5495
|
* enough). Also, the hash value 0 is reserved to indicate an empty slot.
|
5496
5496
|
*
|
5497
|
-
* Note: the FIO_SET_OBJ_COMPARE
|
5498
|
-
*
|
5499
|
-
*
|
5500
|
-
*
|
5497
|
+
* Note: the FIO_SET_OBJ_COMPARE or the FIO_SET_KEY_COMPARE will be used to
|
5498
|
+
* compare against invalid as well as valid objects. Invalid objects have
|
5499
|
+
* their bytes all zero. FIO_SET_*_DESTROY should somehow mark them as
|
5500
|
+
* invalid.
|
5501
5501
|
*
|
5502
5502
|
* Note: Before freeing the Set, FIO_SET_OBJ_DESTROY will be automatically
|
5503
5503
|
* called for every existing object.
|
@@ -5610,16 +5610,16 @@ typedef struct {
|
|
5610
5610
|
#endif
|
5611
5611
|
|
5612
5612
|
/* The default Hash Map-Set has will use straight euqality operators */
|
5613
|
-
#
|
5613
|
+
#ifndef FIO_SET_KEY_COMPARE
|
5614
5614
|
#define FIO_SET_KEY_COMPARE(o1, o2) ((o1) == (o2))
|
5615
5615
|
#endif
|
5616
5616
|
|
5617
5617
|
/** Internal macros for object actions in Hash mode */
|
5618
5618
|
#define FIO_SET_COMPARE(o1, o2) FIO_SET_KEY_COMPARE((o1).key, (o2).key)
|
5619
|
-
#define FIO_SET_COPY(dest,
|
5619
|
+
#define FIO_SET_COPY(dest, src) \
|
5620
5620
|
do { \
|
5621
|
-
FIO_SET_OBJ_COPY((dest).obj, (
|
5622
|
-
FIO_SET_KEY_COPY((dest).key, (
|
5621
|
+
FIO_SET_OBJ_COPY((dest).obj, (src).obj); \
|
5622
|
+
FIO_SET_KEY_COPY((dest).key, (src).key); \
|
5623
5623
|
} while (0);
|
5624
5624
|
#define FIO_SET_DESTROY(couplet) \
|
5625
5625
|
do { \
|
@@ -5871,7 +5871,7 @@ FIO_FUNC inline FIO_NAME(_map_s_) *
|
|
5871
5871
|
if (FIO_SET_HASH_COMPARE(FIO_SET_HASH_INVALID, pos->hash))
|
5872
5872
|
return pos;
|
5873
5873
|
if (FIO_SET_HASH_COMPARE(pos->hash, hash_value_i)) {
|
5874
|
-
if (!pos->pos || FIO_SET_COMPARE(pos->pos->obj, obj))
|
5874
|
+
if (!pos->pos || (FIO_SET_COMPARE(pos->pos->obj, obj)))
|
5875
5875
|
return pos;
|
5876
5876
|
/* full hash value collision detected */
|
5877
5877
|
set->has_collisions = 1;
|
@@ -5890,7 +5890,7 @@ FIO_FUNC inline FIO_NAME(_map_s_) *
|
|
5890
5890
|
if (FIO_SET_HASH_COMPARE(FIO_SET_HASH_INVALID, pos->hash))
|
5891
5891
|
return pos;
|
5892
5892
|
if (FIO_SET_HASH_COMPARE(pos->hash, hash_value_i)) {
|
5893
|
-
if (!pos->pos || FIO_SET_COMPARE(pos->pos->obj, obj))
|
5893
|
+
if (!pos->pos || (FIO_SET_COMPARE(pos->pos->obj, obj)))
|
5894
5894
|
return pos;
|
5895
5895
|
/* full hash value collision detected */
|
5896
5896
|
set->has_collisions = 1;
|
data/ext/iodine/fio_cli.c
CHANGED
@@ -272,19 +272,19 @@ print_help:
|
|
272
272
|
switch ((size_t)type) {
|
273
273
|
case FIO_CLI_STRING__TYPE_I:
|
274
274
|
fprintf(stderr,
|
275
|
-
" \x1B[1m%.*s\x1B[0m\x1B[2m <>\x1B[0m%*s\t
|
276
|
-
"%.*s\x1B[0m\n",
|
275
|
+
" \x1B[1m%.*s\x1B[0m\x1B[2m <>\x1B[0m%*s\t(same as "
|
276
|
+
"\x1B[1m%.*s\x1B[0m)\n",
|
277
277
|
(int)(tmp - start), p + start, padding, "", first_len, p);
|
278
278
|
break;
|
279
279
|
case FIO_CLI_BOOL__TYPE_I:
|
280
280
|
fprintf(stderr,
|
281
|
-
" \x1B[1m%.*s\x1B[0m %*s\t\x1B[
|
281
|
+
" \x1B[1m%.*s\x1B[0m %*s\t(same as \x1B[1m%.*s\x1B[0m)\n",
|
282
282
|
(int)(tmp - start), p + start, padding, "", first_len, p);
|
283
283
|
break;
|
284
284
|
case FIO_CLI_INT__TYPE_I:
|
285
285
|
fprintf(stderr,
|
286
|
-
" \x1B[1m%.*s\x1B[0m\x1B[2m ##\x1B[0m%*s\t
|
287
|
-
"%.*s\x1B[0m\n",
|
286
|
+
" \x1B[1m%.*s\x1B[0m\x1B[2m ##\x1B[0m%*s\t(same as "
|
287
|
+
"\x1B[1m%.*s\x1B[0m)\n",
|
288
288
|
(int)(tmp - start), p + start, padding, "", first_len, p);
|
289
289
|
break;
|
290
290
|
}
|
@@ -19,7 +19,7 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
19
19
|
*/
|
20
20
|
#include "fio_tls.h"
|
21
21
|
|
22
|
-
#if
|
22
|
+
#if !defined(FIO_TLS_FOUND) /* Library compiler flags */
|
23
23
|
|
24
24
|
#define REQUIRE_LIBRARY()
|
25
25
|
#define FIO_TLS_WEAK
|
@@ -628,6 +628,7 @@ void FIO_TLS_WEAK fio_tls_destroy(fio_tls_s *tls) {
|
|
628
628
|
fio_tls_destroy_context(tls);
|
629
629
|
alpn_list_free(&tls->alpn);
|
630
630
|
cert_ary_free(&tls->sni);
|
631
|
+
trust_ary_free(&tls->trust);
|
631
632
|
free(tls);
|
632
633
|
}
|
633
634
|
|
data/ext/iodine/fiobj4fio.h
CHANGED
@@ -14,7 +14,7 @@ static inline __attribute__((unused)) ssize_t fiobj_send_free(intptr_t uuid,
|
|
14
14
|
FIOBJ o) {
|
15
15
|
fio_str_info_s s = fiobj_obj2cstr(o);
|
16
16
|
return fio_write2(uuid, .data.buffer = (void *)(o),
|
17
|
-
.offset = (((intptr_t)s.data) - ((intptr_t)(o))),
|
17
|
+
.offset = (uintptr_t)(((intptr_t)s.data) - ((intptr_t)(o))),
|
18
18
|
.length = s.len, .after.dealloc = fiobj4sock_dealloc);
|
19
19
|
}
|
20
20
|
|
data/ext/iodine/fiobj_numbers.h
CHANGED
@@ -82,10 +82,12 @@ size_t fio_ltoa(char *dest, int64_t num, uint8_t base);
|
|
82
82
|
size_t fio_ftoa(char *dest, double num, uint8_t base);
|
83
83
|
|
84
84
|
/** Converts a number to a temporary, thread safe, C string object */
|
85
|
-
fio_str_info_s
|
85
|
+
fio_str_info_s __attribute__((deprecated("use local buffer with fio_ltoa")))
|
86
|
+
fio_ltocstr(long);
|
86
87
|
|
87
88
|
/** Converts a float to a temporary, thread safe, C string object */
|
88
|
-
fio_str_info_s
|
89
|
+
fio_str_info_s __attribute__((deprecated("use local buffer with fio_ftoa")))
|
90
|
+
fio_ftocstr(double);
|
89
91
|
|
90
92
|
/* *****************************************************************************
|
91
93
|
Pointer Wrapping Helper MACROs (uses integers)
|
data/ext/iodine/http.c
CHANGED
@@ -356,6 +356,21 @@ int http_sendfile(http_s *r, int fd, uintptr_t length, uintptr_t offset) {
|
|
356
356
|
return ((http_vtable_s *)r->private_data.vtbl)
|
357
357
|
->http_sendfile(r, fd, length, offset);
|
358
358
|
}
|
359
|
+
|
360
|
+
static inline int http_test_encoded_path(const char *mem, size_t len) {
|
361
|
+
const char *pos = NULL;
|
362
|
+
const char *end = mem + len;
|
363
|
+
while (mem < end && (pos = memchr(mem, '/', (size_t)len))) {
|
364
|
+
len = end - pos;
|
365
|
+
mem = pos + 1;
|
366
|
+
if (pos[1] == '/')
|
367
|
+
return -1;
|
368
|
+
if (len > 3 && pos[1] == '.' && pos[2] == '.' && pos[3] == '/')
|
369
|
+
return -1;
|
370
|
+
}
|
371
|
+
return 0;
|
372
|
+
}
|
373
|
+
|
359
374
|
/**
|
360
375
|
* Sends the response headers and the specified file (the response's body).
|
361
376
|
*
|
@@ -391,14 +406,8 @@ int http_sendfile2(http_s *h, const char *prefix, size_t prefix_len,
|
|
391
406
|
char *pos = (char *)encoded;
|
392
407
|
const char *end = encoded + encoded_len;
|
393
408
|
while (pos < end) {
|
394
|
-
/* test for path manipulations while decoding */
|
395
|
-
if (*pos == '/' && (pos[1] == '/' ||
|
396
|
-
(((uintptr_t)end - (uintptr_t)pos >= 4) &&
|
397
|
-
pos[1] == '.' && pos[2] == '.' && pos[3] == '/')))
|
398
|
-
return -1;
|
399
409
|
if (*pos == '%') {
|
400
|
-
// decode hex value
|
401
|
-
// this is a percent encoded value.
|
410
|
+
// decode hex value (this is a percent encoded value).
|
402
411
|
if (hex2byte((uint8_t *)tmp.data + tmp.len, (uint8_t *)pos + 1))
|
403
412
|
return -1;
|
404
413
|
tmp.len++;
|
@@ -408,6 +417,9 @@ int http_sendfile2(http_s *h, const char *prefix, size_t prefix_len,
|
|
408
417
|
}
|
409
418
|
tmp.data[tmp.len] = 0;
|
410
419
|
fiobj_str_resize(filename, tmp.len);
|
420
|
+
/* test for path manipulations after decoding */
|
421
|
+
if (http_test_encoded_path(tmp.data + prefix_len, tmp.len - prefix_len))
|
422
|
+
return -1;
|
411
423
|
}
|
412
424
|
if (tmp.data[tmp.len - 1] == '/')
|
413
425
|
fiobj_str_write(filename, "index.html", 10);
|
data/ext/iodine/http.h
CHANGED
@@ -370,7 +370,7 @@ struct http_settings_s {
|
|
370
370
|
* sockets count towards a server's limit.
|
371
371
|
*/
|
372
372
|
intptr_t max_clients;
|
373
|
-
/**
|
373
|
+
/** SSL/TLS support. */
|
374
374
|
void *tls;
|
375
375
|
/** reserved for future use. */
|
376
376
|
intptr_t reserved1;
|
data/ext/iodine/http1.c
CHANGED
@@ -554,7 +554,7 @@ static int http1_on_request(http1_parser_s *parser) {
|
|
554
554
|
if (p->request.method && !p->stop)
|
555
555
|
http_finish(&p->request);
|
556
556
|
h1_reset(p);
|
557
|
-
return
|
557
|
+
return fio_is_closed(p->p.uuid);
|
558
558
|
}
|
559
559
|
/** called when a response was received. */
|
560
560
|
static int http1_on_response(http1_parser_s *parser) {
|
@@ -563,7 +563,7 @@ static int http1_on_response(http1_parser_s *parser) {
|
|
563
563
|
if (p->request.status_str && !p->stop)
|
564
564
|
http_finish(&p->request);
|
565
565
|
h1_reset(p);
|
566
|
-
return
|
566
|
+
return fio_is_closed(p->p.uuid);
|
567
567
|
}
|
568
568
|
/** called when a request method is parsed. */
|
569
569
|
static int http1_on_method(http1_parser_s *parser, char *method,
|
@@ -666,9 +666,9 @@ static int http1_on_body_chunk(http1_parser_s *parser, char *data,
|
|
666
666
|
|
667
667
|
/** called when a protocol error occurred. */
|
668
668
|
static int http1_on_error(http1_parser_s *parser) {
|
669
|
-
|
670
|
-
|
671
|
-
|
669
|
+
if (parser2http(parser)->close)
|
670
|
+
return -1;
|
671
|
+
FIO_LOG_DEBUG("HTTP parser error.");
|
672
672
|
fio_close(parser2http(parser)->p.uuid);
|
673
673
|
return -1;
|
674
674
|
}
|
@@ -723,8 +723,8 @@ static inline void http1_consume_data(intptr_t uuid, http1pr_s *p) {
|
|
723
723
|
|
724
724
|
throttle:
|
725
725
|
/* throttle busy clients (slowloris) */
|
726
|
-
fio_suspend(uuid);
|
727
726
|
p->stop |= 4;
|
727
|
+
fio_suspend(uuid);
|
728
728
|
FIO_LOG_DEBUG("(HTTP/1,1) throttling client at %.*s",
|
729
729
|
(int)fio_peer_addr(uuid).len, fio_peer_addr(uuid).data);
|
730
730
|
}
|
@@ -756,8 +756,8 @@ static void http1_on_close(intptr_t uuid, fio_protocol_s *protocol) {
|
|
756
756
|
static void http1_on_ready(intptr_t uuid, fio_protocol_s *protocol) {
|
757
757
|
/* resume slow clients from suspension */
|
758
758
|
http1pr_s *p = (http1pr_s *)protocol;
|
759
|
-
if (
|
760
|
-
p->stop ^= 4;
|
759
|
+
if (p->stop & 4) {
|
760
|
+
p->stop ^= 4; /* flip back the bit, so it's zero */
|
761
761
|
fio_force_event(uuid, FIO_EVENT_ON_DATA);
|
762
762
|
}
|
763
763
|
(void)protocol;
|
@@ -776,7 +776,6 @@ static void http1_on_data_first_time(intptr_t uuid, fio_protocol_s *protocol) {
|
|
776
776
|
|
777
777
|
/* ensure future reads skip this first time HTTP/2.0 test */
|
778
778
|
p->p.protocol.on_data = http1_on_data;
|
779
|
-
/* Test fot HTTP/2.0 pre-knowledge */
|
780
779
|
if (i >= 24 && !memcmp(p->buf, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", 24)) {
|
781
780
|
FIO_LOG_WARNING("client claimed unsupported HTTP/2 prior knowledge.");
|
782
781
|
fio_close(uuid);
|
@@ -73,6 +73,7 @@ static inline VALUE fiobj_mustache_find_obj_absolute(VALUE udata,
|
|
73
73
|
/* search by String */
|
74
74
|
key = rb_sym2str(key);
|
75
75
|
tmp = rb_hash_lookup2(udata, key, Qundef);
|
76
|
+
rb_str_free(key);
|
76
77
|
if (tmp != Qundef)
|
77
78
|
return tmp;
|
78
79
|
/* search by method */
|
@@ -295,8 +296,6 @@ static VALUE iodine_mustache_new(int argc, VALUE *argv, VALUE self) {
|
|
295
296
|
if (filename != Qnil)
|
296
297
|
Check_Type(filename, T_STRING);
|
297
298
|
|
298
|
-
fio_str_s str = FIO_STR_INIT;
|
299
|
-
|
300
299
|
mustache_s **m = NULL;
|
301
300
|
TypedData_Get_Struct(self, mustache_s *, &iodine_mustache_data_type, m);
|
302
301
|
if (!m) {
|
data/iodine.gemspec
CHANGED
@@ -42,5 +42,6 @@ Gem::Specification.new do |spec|
|
|
42
42
|
spec.add_development_dependency 'minitest', '>=5', '< 6.0'
|
43
43
|
spec.add_development_dependency 'rake-compiler', '>= 1', '< 2.0'
|
44
44
|
|
45
|
-
spec.post_install_message = "Thank you for installing Iodine #{Iodine::VERSION}.\n"
|
45
|
+
spec.post_install_message = "Thank you for installing Iodine #{Iodine::VERSION}.\n" +
|
46
|
+
"Remember: if iodine supports your business, it's is only fair to give value back (code contributions / donations)."
|
46
47
|
end
|
data/lib/iodine/mustache.rb
CHANGED
@@ -9,21 +9,23 @@ module Iodine
|
|
9
9
|
#
|
10
10
|
# * HTML escaping is more agressive, increasing XSS protection. Read why at: https://wonko.com/post/html-escaping .
|
11
11
|
#
|
12
|
-
# * Partial template padding in Iodine
|
12
|
+
# * Partial template padding in Iodine adds padding to dynamic text as well as static text, unlike the official Ruby mustache engine. i.e., if an argument contains a new line marker, the new line will be padded to match the partial template padding.
|
13
13
|
#
|
14
|
-
# * Lambda support is significantly different. For example, the
|
14
|
+
# * Lambda support is significantly different. For example, the text returned from a lambda isn't parsed (no lambda interpolation).
|
15
15
|
#
|
16
16
|
# * Dot notation is tested in whole as well as in part (i.e. `user.name.first` will be tested as is, than the couplet `"user","name.first"` and than as each `"use","name","first"`), allowing for the Hash data to contain keys with dots while still supporting dot notation shortcuts.
|
17
17
|
#
|
18
|
-
# * Dot notation supports method names (even chained method names) as long as they don't have or require arguments. For example, `user.class.to_s` will behave differently on Iodine (returns `
|
18
|
+
# * Dot notation supports method names (even chained method names) as long as they don't have or require arguments. For example, `user.class.to_s` will behave differently on Iodine (returns call name as `String`) than on the official mustache engine (fails / returns empty string).
|
19
19
|
#
|
20
|
-
# Iodine Mustache's engine was designed to play best with basic data structures, such as results from the {Iodine::JSON} parser.
|
20
|
+
# Iodine Mustache's engine was designed to play best with basic data structures, such as results from the {Iodine::JSON} parser and doesn't require any special classes or types.
|
21
21
|
#
|
22
22
|
# Hash data is tested for Symbol keys before being tested for String keys and methods. This means that `:key` has precedence over `"key"`.
|
23
23
|
#
|
24
|
-
# Note: Although using methods as "keys" (or argument names) is supported, no Ruby code is evaluated.
|
24
|
+
# Note: Although using methods as "keys" (or argument names) is supported, no Ruby code is evaluated. This means that only trusted (pre-existing) code will execute.
|
25
25
|
#
|
26
|
-
#
|
26
|
+
# Iodine's {Iodine::Mustache} engine performes about 5-7 times faster(!) than the official Ruby mustache engine. Tests performed with Ruby 2.6.0, comparing iodine 0.7.33 against mustache 1.1.0 using a 2.9 GHz Intel Core i9 CPU.
|
27
|
+
#
|
28
|
+
# You can benchmark the Iodine Mustache performance and decide if you wish to switch from the official Ruby implementation.
|
27
29
|
#
|
28
30
|
# require 'benchmark/ips'
|
29
31
|
# require 'mustache'
|
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.34
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -202,9 +202,9 @@ licenses:
|
|
202
202
|
- MIT
|
203
203
|
metadata:
|
204
204
|
allowed_push_host: https://rubygems.org
|
205
|
-
post_install_message:
|
206
|
-
|
207
|
-
'
|
205
|
+
post_install_message: |-
|
206
|
+
Thank you for installing Iodine 0.7.34.
|
207
|
+
Remember: if iodine supports your business, it's is only fair to give value back (code contributions / donations).
|
208
208
|
rdoc_options: []
|
209
209
|
require_paths:
|
210
210
|
- lib
|