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
         |