iodine 0.7.18 → 0.7.19
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.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/exe/iodine +4 -4
- data/ext/iodine/fio.c +83 -32
- data/ext/iodine/fio.h +68 -61
- data/ext/iodine/http.c +58 -92
- data/ext/iodine/http_internal.c +6 -0
- data/ext/iodine/iodine.c +24 -5
- data/ext/iodine/iodine_defer.c +20 -15
- data/ext/iodine/websockets.c +1 -2
- data/lib/iodine/version.rb +1 -1
- metadata +4 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: a17af3bcb580a2154bb0114bf9a0e5d8bb7b361a58c217dc4b9aa471cc328401
         | 
| 4 | 
            +
              data.tar.gz: 55498d33417433697f9deeb3d864f12af3cccdeb7c7f1a0cec6eb7a83ccc4a84
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 3ed48224b228669f024c592708b805a0057ce53e11113693515ba953f6780bf1d8f6aeb448291b9e1c01a7495aa44a4d36fea90303996ff72aa9850a7bead669
         | 
| 7 | 
            +
              data.tar.gz: bee740562fe189778db55c83c616db4509a16196abf44a8bf1d135432c0e4b99277fe4c91472a76f265d3d68c70f3ad680c6b54dd0254bd5d455f8f219560d93
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -6,6 +6,18 @@ 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.19
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            **Deprecation**: (`iodine`) deprecated the CLI option `-tls-password`, use `-tls-pass` instead.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            **Security**: (`fio`) Slowloris mitigation is now part of the core library, where `FIO_SLOWLORIS_LIMIT` pending calls to `write` (currently 4,096 backlogged calls) will flag the connection as an attacker and close the connection. This protocol independent approach improves security.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            **Fix**: (`iodine`) log open file / socket limit per worker on startup.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            **Fix**: (`iodine`) application warm-up error was fixed. Deprecation warnings will still print for deprecated symbols loaded due to the warm-up sequence.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            **Update**: (`iodine`, `cli`) Support the environment variables `"WORKERS"` and `"THREADS"` out of the box (jury is out regarding `"PORT"` and `"ADDRESS"`, just use CLI for now).
         | 
| 20 | 
            +
             | 
| 9 21 | 
             
            #### Change log v.0.7.18
         | 
| 10 22 |  | 
| 11 23 | 
             
            **Fix** (`pubsub`) fixed pub/sub for longer WebSocket messages. Issue where network byte ordering wasn't always respected and integer bit size was wrong for larger payloads. Credit to Marouane Elmidaoui (@moxgeek) for exposing the issue.
         | 
    
        data/exe/iodine
    CHANGED
    
    | @@ -47,13 +47,13 @@ module Iodine | |
| 47 47 | 
             
                    return app, opt
         | 
| 48 48 | 
             
                  end
         | 
| 49 49 |  | 
| 50 | 
            -
                  def self.perform_warmup
         | 
| 50 | 
            +
                  def self.perform_warmup(app)
         | 
| 51 51 | 
             
                    # load anything marked with `autoload`, since autoload isn't thread safe nor fork friendly.
         | 
| 52 | 
            -
                    Iodine. | 
| 52 | 
            +
                    Iodine.on_state(:on_start) do
         | 
| 53 53 | 
             
                      Module.constants.each do |n|
         | 
| 54 54 | 
             
                        begin
         | 
| 55 55 | 
             
                          Object.const_get(n)
         | 
| 56 | 
            -
                        rescue  | 
| 56 | 
            +
                        rescue StandardError => _e
         | 
| 57 57 | 
             
                        end
         | 
| 58 58 | 
             
                      end
         | 
| 59 59 | 
             
                      ::Rack::Builder.new(app) do |r|
         | 
| @@ -67,7 +67,7 @@ module Iodine | |
| 67 67 |  | 
| 68 68 | 
             
                  def self.call
         | 
| 69 69 | 
             
                    app, opt = get_app_opts
         | 
| 70 | 
            -
                    perform_warmup if Iodine::DEFAULT_SETTINGS[:warmup_]
         | 
| 70 | 
            +
                    perform_warmup(app) if Iodine::DEFAULT_SETTINGS[:warmup_]
         | 
| 71 71 | 
             
                    Iodine::Rack.run(app, opt)
         | 
| 72 72 | 
             
                  end
         | 
| 73 73 | 
             
                end
         | 
    
        data/ext/iodine/fio.c
    CHANGED
    
    | @@ -76,6 +76,11 @@ Feel free to copy, use and enjoy according to the license provided. | |
| 76 76 | 
             
            #define DEBUG_SPINLOCK 0
         | 
| 77 77 | 
             
            #endif
         | 
| 78 78 |  | 
| 79 | 
            +
            /* Slowloris mitigation  (must be less than 1<<16) */
         | 
| 80 | 
            +
            #ifndef FIO_SLOWLORIS_LIMIT
         | 
| 81 | 
            +
            #define FIO_SLOWLORIS_LIMIT (1 << 12)
         | 
| 82 | 
            +
            #endif
         | 
| 83 | 
            +
             | 
| 79 84 | 
             
            #if !defined(__clang__) && !defined(__GNUC__)
         | 
| 80 85 | 
             
            #define __thread _Thread_value
         | 
| 81 86 | 
             
            #endif
         | 
| @@ -148,14 +153,14 @@ typedef struct { | |
| 148 153 | 
             
              fio_packet_s *packet;
         | 
| 149 154 | 
             
              /** the last packet in the queue. */
         | 
| 150 155 | 
             
              fio_packet_s **packet_last;
         | 
| 151 | 
            -
              /** The number of pending packets that are in the queue. */
         | 
| 152 | 
            -
              size_t packet_count;
         | 
| 153 156 | 
             
              /* Data sent so far */
         | 
| 154 157 | 
             
              size_t sent;
         | 
| 155 158 | 
             
              /* fd protocol */
         | 
| 156 159 | 
             
              fio_protocol_s *protocol;
         | 
| 157 160 | 
             
              /* timer handler */
         | 
| 158 161 | 
             
              time_t active;
         | 
| 162 | 
            +
              /** The number of pending packets that are in the queue. */
         | 
| 163 | 
            +
              uint16_t packet_count;
         | 
| 159 164 | 
             
              /* timeout settings */
         | 
| 160 165 | 
             
              uint8_t timeout;
         | 
| 161 166 | 
             
              /* indicates that the fd should be considered scheduled (added to poll) */
         | 
| @@ -2919,6 +2924,12 @@ ssize_t fio_flush(intptr_t uuid) { | |
| 2919 2924 | 
             
              if (fio_trylock(&uuid_data(uuid).sock_lock))
         | 
| 2920 2925 | 
             
                goto would_block;
         | 
| 2921 2926 |  | 
| 2927 | 
            +
              if (uuid_data(uuid).packet_count >= FIO_SLOWLORIS_LIMIT) {
         | 
| 2928 | 
            +
                /* Slowloris attack assumed */
         | 
| 2929 | 
            +
                fio_unlock(&uuid_data(uuid).sock_lock);
         | 
| 2930 | 
            +
                uuid_data(uuid).close = 1;
         | 
| 2931 | 
            +
                goto closed;
         | 
| 2932 | 
            +
              }
         | 
| 2922 2933 | 
             
              if (uuid_data(uuid).packet) {
         | 
| 2923 2934 | 
             
                tmp = uuid_data(uuid).packet->write_func(fio_uuid2fd(uuid),
         | 
| 2924 2935 | 
             
                                                         uuid_data(uuid).packet);
         | 
| @@ -6785,6 +6796,7 @@ void fio_mem_init(void) {} | |
| 6785 6796 | 
             
            Memory Copying by 16 byte units
         | 
| 6786 6797 | 
             
            ***************************************************************************** */
         | 
| 6787 6798 |  | 
| 6799 | 
            +
            /** used internally, only when memory addresses are known to be aligned */
         | 
| 6788 6800 | 
             
            static inline void fio_memcpy(void *__restrict dest_, void *__restrict src_,
         | 
| 6789 6801 | 
             
                                          size_t units) {
         | 
| 6790 6802 | 
             
            #if __SIZEOF_INT128__ == 9 /* a 128bit type exists... but tests favor 64bit */
         | 
| @@ -7432,42 +7444,81 @@ void *realloc(void *ptr, size_t new_size) { return fio_realloc(ptr, new_size); } | |
| 7432 7444 |  | 
| 7433 7445 | 
             
            ***************************************************************************** */
         | 
| 7434 7446 |  | 
| 7435 | 
            -
             | 
| 7436 | 
            -
             | 
| 7447 | 
            +
            /* tested for randomness using code from: http://xoshiro.di.unimi.it/hwd.php */
         | 
| 7448 | 
            +
            uint64_t fio_rand64(void) {
         | 
| 7449 | 
            +
              /* modeled after xoroshiro128+, by David Blackman and Sebastiano Vigna */
         | 
| 7450 | 
            +
              static __thread uint64_t s[2]; /* random state */
         | 
| 7451 | 
            +
              static __thread uint16_t c;    /* seed counter */
         | 
| 7452 | 
            +
              const uint64_t P[] = {0x37701261ED6C16C7ULL, 0x764DBBB75F3B3E0DULL};
         | 
| 7453 | 
            +
              if (c++ == 0) {
         | 
| 7454 | 
            +
                /* re-seed state every 65,536 requests */
         | 
| 7437 7455 | 
             
            #ifdef RUSAGE_SELF
         | 
| 7438 7456 | 
             
                struct rusage rusage;
         | 
| 7439 | 
            -
             | 
| 7457 | 
            +
                getrusage(RUSAGE_SELF, &rusage);
         | 
| 7458 | 
            +
                s[0] = fio_risky_hash(&rusage, sizeof(rusage), s[0]);
         | 
| 7459 | 
            +
                s[1] = fio_risky_hash(&rusage, sizeof(rusage), s[0]);
         | 
| 7460 | 
            +
            #else
         | 
| 7440 7461 | 
             
                struct timespec clk;
         | 
| 7441 | 
            -
                 | 
| 7442 | 
            -
                 | 
| 7443 | 
            -
             | 
| 7444 | 
            -
            #ifdef RUSAGE_SELF
         | 
| 7445 | 
            -
              getrusage(RUSAGE_SELF, &junk_data.rusage);
         | 
| 7462 | 
            +
                clock_gettime(CLOCK_REALTIME, &clk);
         | 
| 7463 | 
            +
                s[0] = fio_risky_hash(&clk, sizeof(clk), s[0]);
         | 
| 7464 | 
            +
                s[1] = fio_risky_hash(&clk, sizeof(clk), s[0]);
         | 
| 7446 7465 | 
             
            #endif
         | 
| 7447 | 
            -
               | 
| 7448 | 
            -
               | 
| 7449 | 
            -
               | 
| 7450 | 
            -
               | 
| 7451 | 
            -
            }
         | 
| 7452 | 
            -
             | 
| 7453 | 
            -
            uint64_t fio_rand64(void) {
         | 
| 7454 | 
            -
              fio_sha2_s sha2 = fio_sha2_init(SHA_512);
         | 
| 7455 | 
            -
              fio_random_data(&sha2);
         | 
| 7456 | 
            -
              return sha2.digest.i64[0];
         | 
| 7466 | 
            +
              }
         | 
| 7467 | 
            +
              s[0] += fio_lrot64(s[0], 33) * P[0];
         | 
| 7468 | 
            +
              s[1] += fio_lrot64(s[1], 33) * P[1];
         | 
| 7469 | 
            +
              return fio_lrot64(s[0], 31) + fio_lrot64(s[1], 29);
         | 
| 7457 7470 | 
             
            }
         | 
| 7458 7471 |  | 
| 7459 | 
            -
             | 
| 7460 | 
            -
             | 
| 7461 | 
            -
               | 
| 7462 | 
            -
             | 
| 7463 | 
            -
               | 
| 7464 | 
            -
             | 
| 7465 | 
            -
             | 
| 7466 | 
            -
                 | 
| 7467 | 
            -
                 | 
| 7468 | 
            -
             | 
| 7469 | 
            -
             | 
| 7470 | 
            -
                 | 
| 7472 | 
            +
            /* copies 64 bits of randomness (8 bytes) repeatedly... */
         | 
| 7473 | 
            +
            void fio_rand_bytes(void *data_, size_t len) {
         | 
| 7474 | 
            +
              if (!data_ || !len)
         | 
| 7475 | 
            +
                return;
         | 
| 7476 | 
            +
              uint8_t *data = data_;
         | 
| 7477 | 
            +
              /* unroll 32 bytes / 256 bit writes */
         | 
| 7478 | 
            +
              for (size_t i = (len >> 5); i; --i) {
         | 
| 7479 | 
            +
                const uint64_t t0 = fio_rand64();
         | 
| 7480 | 
            +
                const uint64_t t1 = fio_rand64();
         | 
| 7481 | 
            +
                const uint64_t t2 = fio_rand64();
         | 
| 7482 | 
            +
                const uint64_t t3 = fio_rand64();
         | 
| 7483 | 
            +
                fio_u2str64(data, t0);
         | 
| 7484 | 
            +
                fio_u2str64(data + 8, t1);
         | 
| 7485 | 
            +
                fio_u2str64(data + 16, t2);
         | 
| 7486 | 
            +
                fio_u2str64(data + 24, t3);
         | 
| 7487 | 
            +
                data += 32;
         | 
| 7488 | 
            +
              }
         | 
| 7489 | 
            +
              uint64_t tmp;
         | 
| 7490 | 
            +
              /* 64 bit steps  */
         | 
| 7491 | 
            +
              switch (len & 24) {
         | 
| 7492 | 
            +
              case 24:
         | 
| 7493 | 
            +
                tmp = fio_rand64();
         | 
| 7494 | 
            +
                fio_u2str64(data + 16, tmp);
         | 
| 7495 | 
            +
              case 16: /* overflow */
         | 
| 7496 | 
            +
                tmp = fio_rand64();
         | 
| 7497 | 
            +
                fio_u2str64(data + 8, tmp);
         | 
| 7498 | 
            +
              case 8: /* overflow */
         | 
| 7499 | 
            +
                tmp = fio_rand64();
         | 
| 7500 | 
            +
                fio_u2str64(data, tmp);
         | 
| 7501 | 
            +
                data += len & 24;
         | 
| 7502 | 
            +
              }
         | 
| 7503 | 
            +
              if ((len & 7)) {
         | 
| 7504 | 
            +
                tmp = fio_rand64();
         | 
| 7505 | 
            +
                /* leftover bytes */
         | 
| 7506 | 
            +
                switch ((len & 7)) {
         | 
| 7507 | 
            +
                case 7: /* overflow */
         | 
| 7508 | 
            +
                  data[6] = (tmp >> 8) & 0xFF;
         | 
| 7509 | 
            +
                case 6: /* overflow */
         | 
| 7510 | 
            +
                  data[5] = (tmp >> 16) & 0xFF;
         | 
| 7511 | 
            +
                case 5: /* overflow */
         | 
| 7512 | 
            +
                  data[4] = (tmp >> 24) & 0xFF;
         | 
| 7513 | 
            +
                case 4: /* overflow */
         | 
| 7514 | 
            +
                  data[3] = (tmp >> 32) & 0xFF;
         | 
| 7515 | 
            +
                case 3: /* overflow */
         | 
| 7516 | 
            +
                  data[2] = (tmp >> 40) & 0xFF;
         | 
| 7517 | 
            +
                case 2: /* overflow */
         | 
| 7518 | 
            +
                  data[1] = (tmp >> 48) & 0xFF;
         | 
| 7519 | 
            +
                case 1: /* overflow */
         | 
| 7520 | 
            +
                  data[0] = (tmp >> 56) & 0xFF;
         | 
| 7521 | 
            +
                }
         | 
| 7471 7522 | 
             
              }
         | 
| 7472 7523 | 
             
            }
         | 
| 7473 7524 |  | 
    
        data/ext/iodine/fio.h
    CHANGED
    
    | @@ -110,7 +110,7 @@ Version and helper macros | |
| 110 110 | 
             
            #define FIO_VERSION_MAJOR 0
         | 
| 111 111 | 
             
            #define FIO_VERSION_MINOR 7
         | 
| 112 112 | 
             
            #define FIO_VERSION_PATCH 0
         | 
| 113 | 
            -
            #define FIO_VERSION_BETA  | 
| 113 | 
            +
            #define FIO_VERSION_BETA 8
         | 
| 114 114 |  | 
| 115 115 | 
             
            /* Automatically convert version data to a string constant - ignore these two */
         | 
| 116 116 | 
             
            #define FIO_MACRO2STR_STEP2(macro) #macro
         | 
| @@ -264,6 +264,8 @@ C++ extern start | |
| 264 264 | 
             
            /* support C++ */
         | 
| 265 265 | 
             
            #ifdef __cplusplus
         | 
| 266 266 | 
             
            extern "C" {
         | 
| 267 | 
            +
            /* C++ keyword was deprecated */
         | 
| 268 | 
            +
            #define register
         | 
| 267 269 | 
             
            #endif
         | 
| 268 270 |  | 
| 269 271 | 
             
            /* *****************************************************************************
         | 
| @@ -2206,7 +2208,8 @@ FIO_FUNC inline uintptr_t fio_ct_if2(uintptr_t cond, uintptr_t a, uintptr_t b) { | |
| 2206 2208 | 
             
               ((i) >> ((-(bits)) & ((sizeof((i)) << 3) - 1))))
         | 
| 2207 2209 | 
             
            /** unknown size element - right rotation, inlined. */
         | 
| 2208 2210 | 
             
            #define fio_rrot(i, bits)                                                      \
         | 
| 2209 | 
            -
              (((i) >> ( | 
| 2211 | 
            +
              (((i) >> ((bits) & ((sizeof((i)) << 3) - 1))) |                              \
         | 
| 2212 | 
            +
               ((i) << ((-(bits)) & ((sizeof((i)) << 3) - 1))))
         | 
| 2210 2213 |  | 
| 2211 2214 | 
             
            /** Converts an unaligned network ordered byte stream to a 16 bit number. */
         | 
| 2212 2215 | 
             
            #define fio_str2u16(c)                                                         \
         | 
| @@ -2401,104 +2404,108 @@ uint8_t __attribute__((weak)) fio_hash_secret_marker2; | |
| 2401 2404 | 
             
            Risky Hash (always available, even if using only the fio.h header)
         | 
| 2402 2405 | 
             
            ***************************************************************************** */
         | 
| 2403 2406 |  | 
| 2404 | 
            -
             | 
| 2405 | 
            -
              | 
| 2406 | 
            -
              | 
| 2407 | 
            -
             * and named "Risky Hash" because writing your own hashing function is a risky
         | 
| 2408 | 
            -
             * business, full of pitfalls, hours of testing and security risks...
         | 
| 2409 | 
            -
             *
         | 
| 2410 | 
            -
             * Risky Hash isn't as battle tested as SipHash, but it did pass the
         | 
| 2411 | 
            -
             * [SMHasher](https://github.com/rurban/smhasher) tests with wonderful results,
         | 
| 2412 | 
            -
             * can be used for processing safe data and is easy (and short) to implement.
         | 
| 2413 | 
            -
             */
         | 
| 2414 | 
            -
            inline FIO_FUNC uintptr_t fio_risky_hash(const void *data_, size_t len,
         | 
| 2415 | 
            -
                                                     uint64_t seed) {
         | 
| 2416 | 
            -
              /* The primes used by Risky Hash */
         | 
| 2417 | 
            -
              const uint64_t primes[] = {
         | 
| 2418 | 
            -
                  0xFBBA3FA15B22113B, // 1111101110111010001111111010000101011011001000100001000100111011
         | 
| 2419 | 
            -
                  0xAB137439982B86C9, // 1010101100010011011101000011100110011000001010111000011011001001
         | 
| 2420 | 
            -
              };
         | 
| 2421 | 
            -
              /* The consumption vectors initialized state */
         | 
| 2422 | 
            -
              uint64_t v[4] = {
         | 
| 2423 | 
            -
                  seed ^ primes[1],
         | 
| 2424 | 
            -
                  ~seed + primes[1],
         | 
| 2425 | 
            -
                  fio_lrot64(seed, 17) ^ primes[1],
         | 
| 2426 | 
            -
                  fio_lrot64(seed, 33) + primes[1],
         | 
| 2427 | 
            -
              };
         | 
| 2407 | 
            +
            /* Risky Hash primes */
         | 
| 2408 | 
            +
            #define RISKY_PRIME_0 0xFBBA3FA15B22113B
         | 
| 2409 | 
            +
            #define RISKY_PRIME_1 0xAB137439982B86C9
         | 
| 2428 2410 |  | 
| 2429 | 
            -
            /* Risky Hash consumption round */
         | 
| 2430 | 
            -
            #define fio_risky_consume( | 
| 2431 | 
            -
              v | 
| 2432 | 
            -
              v | 
| 2433 | 
            -
              v | 
| 2434 | 
            -
             | 
| 2435 | 
            -
            /* compilers could, hopefully, optimize this code for SIMD */
         | 
| 2436 | 
            -
            #define fio_risky_consume256(w0, w1, w2, w3)                                   \
         | 
| 2437 | 
            -
              fio_risky_consume(w0, 0);                                                    \
         | 
| 2438 | 
            -
              fio_risky_consume(w1, 1);                                                    \
         | 
| 2439 | 
            -
              fio_risky_consume(w2, 2);                                                    \
         | 
| 2440 | 
            -
              fio_risky_consume(w3, 3);
         | 
| 2411 | 
            +
            /* Risky Hash consumption round, accepts a state word s and an input word w */
         | 
| 2412 | 
            +
            #define fio_risky_consume(v, w)                                                \
         | 
| 2413 | 
            +
              (v) += (w);                                                                  \
         | 
| 2414 | 
            +
              (v) = fio_lrot64((v), 33);                                                   \
         | 
| 2415 | 
            +
              (v) += (w);                                                                  \
         | 
| 2416 | 
            +
              (v) *= RISKY_PRIME_0;
         | 
| 2441 2417 |  | 
| 2418 | 
            +
            /*  Computes a facil.io Risky Hash. */
         | 
| 2419 | 
            +
            FIO_FUNC inline uint64_t fio_risky_hash(const void *data_, size_t len,
         | 
| 2420 | 
            +
                                                    uint64_t seed) {
         | 
| 2442 2421 | 
             
              /* reading position */
         | 
| 2443 2422 | 
             
              const uint8_t *data = (uint8_t *)data_;
         | 
| 2444 2423 |  | 
| 2445 | 
            -
              /*  | 
| 2424 | 
            +
              /* The consumption vectors initialized state */
         | 
| 2425 | 
            +
              register uint64_t v0 = seed ^ RISKY_PRIME_1;
         | 
| 2426 | 
            +
              register uint64_t v1 = ~seed + RISKY_PRIME_1;
         | 
| 2427 | 
            +
              register uint64_t v2 =
         | 
| 2428 | 
            +
                  fio_lrot64(seed, 17) ^ ((~RISKY_PRIME_1) + RISKY_PRIME_0);
         | 
| 2429 | 
            +
              register uint64_t v3 = fio_lrot64(seed, 33) + (~RISKY_PRIME_1);
         | 
| 2430 | 
            +
             | 
| 2431 | 
            +
              /* consume 256 bit blocks */
         | 
| 2446 2432 | 
             
              for (size_t i = len >> 5; i; --i) {
         | 
| 2447 | 
            -
                 | 
| 2448 | 
            -
             | 
| 2433 | 
            +
                fio_risky_consume(v0, fio_str2u64(data));
         | 
| 2434 | 
            +
                fio_risky_consume(v1, fio_str2u64(data + 8));
         | 
| 2435 | 
            +
                fio_risky_consume(v2, fio_str2u64(data + 16));
         | 
| 2436 | 
            +
                fio_risky_consume(v3, fio_str2u64(data + 24));
         | 
| 2449 2437 | 
             
                data += 32;
         | 
| 2450 2438 | 
             
              }
         | 
| 2439 | 
            +
             | 
| 2451 2440 | 
             
              /* Consume any remaining 64 bit words. */
         | 
| 2452 2441 | 
             
              switch (len & 24) {
         | 
| 2453 2442 | 
             
              case 24:
         | 
| 2454 | 
            -
                fio_risky_consume(fio_str2u64(data + 16) | 
| 2443 | 
            +
                fio_risky_consume(v2, fio_str2u64(data + 16));
         | 
| 2455 2444 | 
             
              case 16: /* overflow */
         | 
| 2456 | 
            -
                fio_risky_consume(fio_str2u64(data + 8) | 
| 2445 | 
            +
                fio_risky_consume(v1, fio_str2u64(data + 8));
         | 
| 2457 2446 | 
             
              case 8: /* overflow */
         | 
| 2458 | 
            -
                fio_risky_consume(fio_str2u64(data) | 
| 2447 | 
            +
                fio_risky_consume(v0, fio_str2u64(data));
         | 
| 2459 2448 | 
             
                data += len & 24;
         | 
| 2460 2449 | 
             
              }
         | 
| 2461 2450 |  | 
| 2462 | 
            -
               | 
| 2451 | 
            +
              uint64_t tmp = 0;
         | 
| 2463 2452 | 
             
              /* consume leftover bytes, if any */
         | 
| 2464 2453 | 
             
              switch ((len & 7)) {
         | 
| 2465 2454 | 
             
              case 7: /* overflow */
         | 
| 2466 | 
            -
                tmp |= ((uint64_t)data[6]) <<  | 
| 2455 | 
            +
                tmp |= ((uint64_t)data[6]) << 8;
         | 
| 2467 2456 | 
             
              case 6: /* overflow */
         | 
| 2468 | 
            -
                tmp |= ((uint64_t)data[5]) <<  | 
| 2457 | 
            +
                tmp |= ((uint64_t)data[5]) << 16;
         | 
| 2469 2458 | 
             
              case 5: /* overflow */
         | 
| 2470 | 
            -
                tmp |= ((uint64_t)data[4]) <<  | 
| 2459 | 
            +
                tmp |= ((uint64_t)data[4]) << 24;
         | 
| 2471 2460 | 
             
              case 4: /* overflow */
         | 
| 2472 2461 | 
             
                tmp |= ((uint64_t)data[3]) << 32;
         | 
| 2473 2462 | 
             
              case 3: /* overflow */
         | 
| 2474 | 
            -
                tmp |= ((uint64_t)data[2]) <<  | 
| 2463 | 
            +
                tmp |= ((uint64_t)data[2]) << 40;
         | 
| 2475 2464 | 
             
              case 2: /* overflow */
         | 
| 2476 | 
            -
                tmp |= ((uint64_t)data[1]) <<  | 
| 2465 | 
            +
                tmp |= ((uint64_t)data[1]) << 48;
         | 
| 2477 2466 | 
             
              case 1: /* overflow */
         | 
| 2478 | 
            -
                tmp |= ((uint64_t)data[0]) <<  | 
| 2479 | 
            -
                 | 
| 2467 | 
            +
                tmp |= ((uint64_t)data[0]) << 56;
         | 
| 2468 | 
            +
                /* ((len >> 3) & 3) is a 0...3 value indicating consumption vector */
         | 
| 2469 | 
            +
                switch ((len >> 3) & 3) {
         | 
| 2470 | 
            +
                case 3:
         | 
| 2471 | 
            +
                  fio_risky_consume(v3, tmp);
         | 
| 2472 | 
            +
                  break;
         | 
| 2473 | 
            +
                case 2:
         | 
| 2474 | 
            +
                  fio_risky_consume(v2, tmp);
         | 
| 2475 | 
            +
                  break;
         | 
| 2476 | 
            +
                case 1:
         | 
| 2477 | 
            +
                  fio_risky_consume(v1, tmp);
         | 
| 2478 | 
            +
                  break;
         | 
| 2479 | 
            +
                case 0:
         | 
| 2480 | 
            +
                  fio_risky_consume(v0, tmp);
         | 
| 2481 | 
            +
                  break;
         | 
| 2482 | 
            +
                }
         | 
| 2480 2483 | 
             
              }
         | 
| 2481 2484 |  | 
| 2482 2485 | 
             
              /* merge and mix */
         | 
| 2483 | 
            -
              uint64_t result = fio_lrot64( | 
| 2484 | 
            -
                                fio_lrot64( | 
| 2486 | 
            +
              uint64_t result = fio_lrot64(v0, 17) + fio_lrot64(v1, 13) +
         | 
| 2487 | 
            +
                                fio_lrot64(v2, 47) + fio_lrot64(v3, 57);
         | 
| 2488 | 
            +
             | 
| 2489 | 
            +
              len ^= (len << 33);
         | 
| 2485 2490 | 
             
              result += len;
         | 
| 2486 | 
            -
             | 
| 2491 | 
            +
             | 
| 2492 | 
            +
              result += v0 * RISKY_PRIME_1;
         | 
| 2487 2493 | 
             
              result ^= fio_lrot64(result, 13);
         | 
| 2488 | 
            -
              result +=  | 
| 2494 | 
            +
              result += v1 * RISKY_PRIME_1;
         | 
| 2489 2495 | 
             
              result ^= fio_lrot64(result, 29);
         | 
| 2490 | 
            -
              result +=  | 
| 2496 | 
            +
              result += v2 * RISKY_PRIME_1;
         | 
| 2491 2497 | 
             
              result ^= fio_lrot64(result, 33);
         | 
| 2492 | 
            -
              result +=  | 
| 2498 | 
            +
              result += v3 * RISKY_PRIME_1;
         | 
| 2493 2499 | 
             
              result ^= fio_lrot64(result, 51);
         | 
| 2494 2500 |  | 
| 2495 2501 | 
             
              /* irreversible avalanche... I think */
         | 
| 2496 | 
            -
              result ^= (result >> 29) *  | 
| 2502 | 
            +
              result ^= (result >> 29) * RISKY_PRIME_0;
         | 
| 2497 2503 | 
             
              return result;
         | 
| 2504 | 
            +
            }
         | 
| 2498 2505 |  | 
| 2499 | 
            -
            #undef fio_risky_consume256
         | 
| 2500 2506 | 
             
            #undef fio_risky_consume
         | 
| 2501 | 
            -
             | 
| 2507 | 
            +
            #undef FIO_RISKY_PRIME_0
         | 
| 2508 | 
            +
            #undef FIO_RISKY_PRIME_1
         | 
| 2502 2509 |  | 
| 2503 2510 | 
             
            /* *****************************************************************************
         | 
| 2504 2511 | 
             
            SipHash
         | 
    
        data/ext/iodine/http.c
    CHANGED
    
    | @@ -166,6 +166,7 @@ int http_set_header2(http_s *r, fio_str_info_s n, fio_str_info_s v) { | |
| 166 166 | 
             
              fiobj_free(tmp);
         | 
| 167 167 | 
             
              return ret;
         | 
| 168 168 | 
             
            }
         | 
| 169 | 
            +
             | 
| 169 170 | 
             
            /**
         | 
| 170 171 | 
             
             * Sets a response cookie, taking ownership of the value object, but NOT the
         | 
| 171 172 | 
             
             * name object (so name objects could be reused in future responses).
         | 
| @@ -189,102 +190,50 @@ int http_set_cookie(http_s *h, http_cookie_args_s cookie) { | |
| 189 190 | 
             
              size_t len = 0;
         | 
| 190 191 | 
             
              FIOBJ c = fiobj_str_buf(capa);
         | 
| 191 192 | 
             
              fio_str_info_s t = fiobj_obj2cstr(c);
         | 
| 193 | 
            +
             | 
| 194 | 
            +
            #define copy_cookie_ch(ch_var)                                                 \
         | 
| 195 | 
            +
              if (invalid_cookie_##ch_var##_char[(uint8_t)cookie.ch_var[tmp]]) {           \
         | 
| 196 | 
            +
                if (!warn_illegal) {                                                       \
         | 
| 197 | 
            +
                  ++warn_illegal;                                                          \
         | 
| 198 | 
            +
                  FIO_LOG_WARNING("illegal char 0x%.2x in cookie " #ch_var " (in %s)\n"    \
         | 
| 199 | 
            +
                                  "         automatic %% encoding applied",                \
         | 
| 200 | 
            +
                                  cookie.ch_var[tmp], cookie.ch_var);                      \
         | 
| 201 | 
            +
                }                                                                          \
         | 
| 202 | 
            +
                t.data[len++] = '%';                                                       \
         | 
| 203 | 
            +
                t.data[len++] = hex_chars[((uint8_t)cookie.ch_var[tmp] >> 4) & 0x0F];      \
         | 
| 204 | 
            +
                t.data[len++] = hex_chars[(uint8_t)cookie.ch_var[tmp] & 0x0F];             \
         | 
| 205 | 
            +
              } else {                                                                     \
         | 
| 206 | 
            +
                t.data[len++] = cookie.ch_var[tmp];                                        \
         | 
| 207 | 
            +
              }                                                                            \
         | 
| 208 | 
            +
              tmp += 1;                                                                    \
         | 
| 209 | 
            +
              if (capa <= len + 3) {                                                       \
         | 
| 210 | 
            +
                capa += 32;                                                                \
         | 
| 211 | 
            +
                fiobj_str_capa_assert(c, capa);                                            \
         | 
| 212 | 
            +
                t = fiobj_obj2cstr(c);                                                     \
         | 
| 213 | 
            +
              }
         | 
| 214 | 
            +
             | 
| 192 215 | 
             
              if (cookie.name) {
         | 
| 216 | 
            +
                size_t tmp = 0;
         | 
| 193 217 | 
             
                if (cookie.name_len) {
         | 
| 194 | 
            -
                  size_t tmp = 0;
         | 
| 195 218 | 
             
                  while (tmp < cookie.name_len) {
         | 
| 196 | 
            -
                     | 
| 197 | 
            -
                      if (!warn_illegal) {
         | 
| 198 | 
            -
                        ++warn_illegal;
         | 
| 199 | 
            -
                        FIO_LOG_WARNING("illegal char 0x%.2x in cookie name (in %s)\n"
         | 
| 200 | 
            -
                                        "         automatic %% encoding applied",
         | 
| 201 | 
            -
                                        cookie.name[tmp], cookie.name);
         | 
| 202 | 
            -
                      }
         | 
| 203 | 
            -
                      t.data[len++] = '%';
         | 
| 204 | 
            -
                      t.data[len++] = hex_chars[(cookie.name[tmp] >> 4) & 0x0F];
         | 
| 205 | 
            -
                      t.data[len++] = hex_chars[cookie.name[tmp] & 0x0F];
         | 
| 206 | 
            -
                    } else {
         | 
| 207 | 
            -
                      t.data[len++] = cookie.name[tmp];
         | 
| 208 | 
            -
                    }
         | 
| 209 | 
            -
                    tmp += 1;
         | 
| 210 | 
            -
                    if (capa <= len + 3) {
         | 
| 211 | 
            -
                      capa += 32;
         | 
| 212 | 
            -
                      fiobj_str_capa_assert(c, capa);
         | 
| 213 | 
            -
                      t = fiobj_obj2cstr(c);
         | 
| 214 | 
            -
                    }
         | 
| 219 | 
            +
                    copy_cookie_ch(name);
         | 
| 215 220 | 
             
                  }
         | 
| 216 221 | 
             
                } else {
         | 
| 217 | 
            -
                  size_t tmp = 0;
         | 
| 218 222 | 
             
                  while (cookie.name[tmp]) {
         | 
| 219 | 
            -
                     | 
| 220 | 
            -
                      if (!warn_illegal) {
         | 
| 221 | 
            -
                        ++warn_illegal;
         | 
| 222 | 
            -
                        FIO_LOG_WARNING("illegal char 0x%.2x in cookie name (in %s)\n"
         | 
| 223 | 
            -
                                        "         automatic %% encoding applied",
         | 
| 224 | 
            -
                                        cookie.name[tmp], cookie.name);
         | 
| 225 | 
            -
                      }
         | 
| 226 | 
            -
                      t.data[len++] = '%';
         | 
| 227 | 
            -
                      t.data[len++] = hex_chars[(cookie.name[tmp] >> 4) & 0x0F];
         | 
| 228 | 
            -
                      t.data[len++] = hex_chars[cookie.name[tmp] & 0x0F];
         | 
| 229 | 
            -
                    } else {
         | 
| 230 | 
            -
                      t.data[len++] = cookie.name[tmp];
         | 
| 231 | 
            -
                    }
         | 
| 232 | 
            -
                    tmp += 1;
         | 
| 233 | 
            -
                    if (capa <= len + 4) {
         | 
| 234 | 
            -
                      capa += 32;
         | 
| 235 | 
            -
                      fiobj_str_capa_assert(c, capa);
         | 
| 236 | 
            -
                      t = fiobj_obj2cstr(c);
         | 
| 237 | 
            -
                    }
         | 
| 223 | 
            +
                    copy_cookie_ch(name);
         | 
| 238 224 | 
             
                  }
         | 
| 239 225 | 
             
                }
         | 
| 240 226 | 
             
              }
         | 
| 241 227 | 
             
              t.data[len++] = '=';
         | 
| 242 228 | 
             
              if (cookie.value) {
         | 
| 229 | 
            +
                size_t tmp = 0;
         | 
| 243 230 | 
             
                if (cookie.value_len) {
         | 
| 244 | 
            -
                  size_t tmp = 0;
         | 
| 245 231 | 
             
                  while (tmp < cookie.value_len) {
         | 
| 246 | 
            -
                     | 
| 247 | 
            -
                      if (!warn_illegal) {
         | 
| 248 | 
            -
                        ++warn_illegal;
         | 
| 249 | 
            -
                        FIO_LOG_WARNING("illegal char 0x%.2x in cookie value (in %s)\n"
         | 
| 250 | 
            -
                                        "         automatic %% encoding applied",
         | 
| 251 | 
            -
                                        cookie.value[tmp], cookie.name);
         | 
| 252 | 
            -
                      }
         | 
| 253 | 
            -
                      t.data[len++] = '%';
         | 
| 254 | 
            -
                      t.data[len++] = hex_chars[(cookie.value[tmp] >> 4) & 0x0F];
         | 
| 255 | 
            -
                      t.data[len++] = hex_chars[cookie.value[tmp] & 0x0F];
         | 
| 256 | 
            -
                    } else {
         | 
| 257 | 
            -
                      t.data[len++] = cookie.value[tmp];
         | 
| 258 | 
            -
                    }
         | 
| 259 | 
            -
                    tmp += 1;
         | 
| 260 | 
            -
                    if (capa <= len + 3) {
         | 
| 261 | 
            -
                      capa += 32;
         | 
| 262 | 
            -
                      fiobj_str_capa_assert(c, capa);
         | 
| 263 | 
            -
                      t = fiobj_obj2cstr(c);
         | 
| 264 | 
            -
                    }
         | 
| 232 | 
            +
                    copy_cookie_ch(value);
         | 
| 265 233 | 
             
                  }
         | 
| 266 234 | 
             
                } else {
         | 
| 267 | 
            -
                  size_t tmp = 0;
         | 
| 268 235 | 
             
                  while (cookie.value[tmp]) {
         | 
| 269 | 
            -
                     | 
| 270 | 
            -
                      if (!warn_illegal) {
         | 
| 271 | 
            -
                        ++warn_illegal;
         | 
| 272 | 
            -
                        FIO_LOG_WARNING("illegal char 0x%.2x in cookie value (in %s)\n"
         | 
| 273 | 
            -
                                        "         automatic %% encoding applied",
         | 
| 274 | 
            -
                                        cookie.value[tmp], cookie.name);
         | 
| 275 | 
            -
                      }
         | 
| 276 | 
            -
                      t.data[len++] = '%';
         | 
| 277 | 
            -
                      t.data[len++] = hex_chars[(cookie.value[tmp] >> 4) & 0x0F];
         | 
| 278 | 
            -
                      t.data[len++] = hex_chars[cookie.value[tmp] & 0x0F];
         | 
| 279 | 
            -
                    } else {
         | 
| 280 | 
            -
                      t.data[len++] = cookie.value[tmp];
         | 
| 281 | 
            -
                    }
         | 
| 282 | 
            -
                    tmp += 1;
         | 
| 283 | 
            -
                    if (capa <= len + 3) {
         | 
| 284 | 
            -
                      capa += 32;
         | 
| 285 | 
            -
                      fiobj_str_capa_assert(c, capa);
         | 
| 286 | 
            -
                      t = fiobj_obj2cstr(c);
         | 
| 287 | 
            -
                    }
         | 
| 236 | 
            +
                    copy_cookie_ch(value);
         | 
| 288 237 | 
             
                  }
         | 
| 289 238 | 
             
                }
         | 
| 290 239 | 
             
              } else
         | 
| @@ -1058,8 +1007,8 @@ intptr_t http_connect FIO_IGNORE_MACRO(const char *url, | |
| 1058 1007 | 
             
                errno = EINVAL;
         | 
| 1059 1008 | 
             
                goto on_error;
         | 
| 1060 1009 | 
             
              }
         | 
| 1061 | 
            -
              size_t len;
         | 
| 1062 | 
            -
              char *a = NULL, *p = NULL;
         | 
| 1010 | 
            +
              size_t len = 0, h_len = 0;
         | 
| 1011 | 
            +
              char *a = NULL, *p = NULL, *host = NULL;
         | 
| 1063 1012 | 
             
              uint8_t is_websocket = 0;
         | 
| 1064 1013 | 
             
              uint8_t is_secure = 0;
         | 
| 1065 1014 | 
             
              FIOBJ path = FIOBJ_INVALID;
         | 
| @@ -1094,7 +1043,8 @@ intptr_t http_connect FIO_IGNORE_MACRO(const char *url, | |
| 1094 1043 | 
             
                }
         | 
| 1095 1044 | 
             
                if (unix_address) {
         | 
| 1096 1045 | 
             
                  a = (char *)unix_address;
         | 
| 1097 | 
            -
                  len = strlen(a);
         | 
| 1046 | 
            +
                  h_len = len = strlen(a);
         | 
| 1047 | 
            +
                  host = a;
         | 
| 1098 1048 | 
             
                } else {
         | 
| 1099 1049 | 
             
                  if (!u.host.data) {
         | 
| 1100 1050 | 
             
                    FIO_LOG_ERROR("http_connect requires a valid address.");
         | 
| @@ -1122,6 +1072,10 @@ intptr_t http_connect FIO_IGNORE_MACRO(const char *url, | |
| 1122 1072 | 
             
                    p[2] = 0;
         | 
| 1123 1073 | 
             
                  }
         | 
| 1124 1074 | 
             
                }
         | 
| 1075 | 
            +
                if (u.host.data) {
         | 
| 1076 | 
            +
                  host = u.host.data;
         | 
| 1077 | 
            +
                  h_len = u.host.len;
         | 
| 1078 | 
            +
                }
         | 
| 1125 1079 | 
             
              }
         | 
| 1126 1080 |  | 
| 1127 1081 | 
             
              /* set settings */
         | 
| @@ -1146,8 +1100,9 @@ intptr_t http_connect FIO_IGNORE_MACRO(const char *url, | |
| 1146 1100 | 
             
              h->path = path;
         | 
| 1147 1101 | 
             
              settings->udata = h;
         | 
| 1148 1102 | 
             
              settings->tls = arg_settings.tls;
         | 
| 1149 | 
            -
               | 
| 1150 | 
            -
             | 
| 1103 | 
            +
              if (host)
         | 
| 1104 | 
            +
                http_set_header2(h, (fio_str_info_s){.data = (char *)"host", .len = 4},
         | 
| 1105 | 
            +
                                 (fio_str_info_s){.data = host, .len = h_len});
         | 
| 1151 1106 | 
             
              intptr_t ret;
         | 
| 1152 1107 | 
             
              if (is_websocket) {
         | 
| 1153 1108 | 
             
                /* force HTTP/1.1 */
         | 
| @@ -2496,42 +2451,53 @@ ssize_t http_decode_path_unsafe(char *dest, const char *url_data) { | |
| 2496 2451 | 
             
            Lookup Tables / functions
         | 
| 2497 2452 | 
             
            ***************************************************************************** */
         | 
| 2498 2453 |  | 
| 2454 | 
            +
            #define FIO_FORCE_MALLOC_TMP 1 /* use malloc for the mime registry */
         | 
| 2499 2455 | 
             
            #define FIO_SET_NAME fio_mime_set
         | 
| 2500 2456 | 
             
            #define FIO_SET_OBJ_TYPE FIOBJ
         | 
| 2501 2457 | 
             
            #define FIO_SET_OBJ_COMPARE(o1, o2) (1)
         | 
| 2458 | 
            +
            #define FIO_SET_OBJ_COPY(dest, o) (dest) = fiobj_dup((o))
         | 
| 2502 2459 | 
             
            #define FIO_SET_OBJ_DESTROY(o) fiobj_free((o))
         | 
| 2503 2460 |  | 
| 2504 2461 | 
             
            #include <fio.h>
         | 
| 2505 2462 |  | 
| 2506 | 
            -
            static fio_mime_set_s  | 
| 2463 | 
            +
            static fio_mime_set_s fio_http_mime_types = FIO_SET_INIT;
         | 
| 2507 2464 |  | 
| 2508 2465 | 
             
            #define LONGEST_FILE_EXTENSION_LENGTH 15
         | 
| 2509 2466 |  | 
| 2510 2467 | 
             
            /** Registers a Mime-Type to be associated with the file extension. */
         | 
| 2511 2468 | 
             
            void http_mimetype_register(char *file_ext, size_t file_ext_len,
         | 
| 2512 2469 | 
             
                                        FIOBJ mime_type_str) {
         | 
| 2513 | 
            -
              uintptr_t hash =  | 
| 2470 | 
            +
              uintptr_t hash = FIO_HASH_FN(file_ext, file_ext_len, 0, 0);
         | 
| 2514 2471 | 
             
              if (mime_type_str == FIOBJ_INVALID) {
         | 
| 2515 | 
            -
                fio_mime_set_remove(& | 
| 2472 | 
            +
                fio_mime_set_remove(&fio_http_mime_types, hash, FIOBJ_INVALID, NULL);
         | 
| 2516 2473 | 
             
              } else {
         | 
| 2517 2474 | 
             
                FIOBJ old = FIOBJ_INVALID;
         | 
| 2518 | 
            -
                fio_mime_set_overwrite(& | 
| 2475 | 
            +
                fio_mime_set_overwrite(&fio_http_mime_types, hash, mime_type_str, &old);
         | 
| 2519 2476 | 
             
                if (old != FIOBJ_INVALID) {
         | 
| 2520 2477 | 
             
                  FIO_LOG_WARNING("mime-type collision: %.*s was %s, now %s",
         | 
| 2521 2478 | 
             
                                  (int)file_ext_len, file_ext, fiobj_obj2cstr(old).data,
         | 
| 2522 2479 | 
             
                                  fiobj_obj2cstr(mime_type_str).data);
         | 
| 2523 2480 | 
             
                  fiobj_free(old);
         | 
| 2524 2481 | 
             
                }
         | 
| 2482 | 
            +
                fiobj_free(mime_type_str); /* move ownership to the registry */
         | 
| 2525 2483 | 
             
              }
         | 
| 2526 2484 | 
             
            }
         | 
| 2527 2485 |  | 
| 2486 | 
            +
            /** Registers a Mime-Type to be associated with the file extension. */
         | 
| 2487 | 
            +
            void http_mimetype_stats(void) {
         | 
| 2488 | 
            +
              FIO_LOG_DEBUG("HTTP MIME hash storage count/capa: %zu / %zu",
         | 
| 2489 | 
            +
                            fio_mime_set_count(&fio_http_mime_types),
         | 
| 2490 | 
            +
                            fio_mime_set_capa(&fio_http_mime_types));
         | 
| 2491 | 
            +
            }
         | 
| 2492 | 
            +
             | 
| 2528 2493 | 
             
            /**
         | 
| 2529 2494 | 
             
             * Finds the mime-type associated with the file extension.
         | 
| 2530 2495 | 
             
             *  Remember to call `fiobj_free`.
         | 
| 2531 2496 | 
             
             */
         | 
| 2532 2497 | 
             
            FIOBJ http_mimetype_find(char *file_ext, size_t file_ext_len) {
         | 
| 2533 | 
            -
              uintptr_t hash =  | 
| 2534 | 
            -
              return fiobj_dup( | 
| 2498 | 
            +
              uintptr_t hash = FIO_HASH_FN(file_ext, file_ext_len, 0, 0);
         | 
| 2499 | 
            +
              return fiobj_dup(
         | 
| 2500 | 
            +
                  fio_mime_set_find(&fio_http_mime_types, hash, FIOBJ_INVALID));
         | 
| 2535 2501 | 
             
            }
         | 
| 2536 2502 |  | 
| 2537 2503 | 
             
            /**
         | 
| @@ -2574,7 +2540,7 @@ finish: | |
| 2574 2540 |  | 
| 2575 2541 | 
             
            /** Clears the Mime-Type registry (it will be empty afterthis call). */
         | 
| 2576 2542 | 
             
            void http_mimetype_clear(void) {
         | 
| 2577 | 
            -
              fio_mime_set_free(& | 
| 2543 | 
            +
              fio_mime_set_free(&fio_http_mime_types);
         | 
| 2578 2544 | 
             
              fiobj_free(current_date);
         | 
| 2579 2545 | 
             
              current_date = FIOBJ_INVALID;
         | 
| 2580 2546 | 
             
              last_date_added = 0;
         | 
    
        data/ext/iodine/http_internal.c
    CHANGED
    
    | @@ -147,6 +147,8 @@ static __attribute__((constructor)) void http_lib_constructor(void) { | |
| 147 147 | 
             
              fio_state_callback_add(FIO_CALL_AT_EXIT, http_lib_cleanup, NULL);
         | 
| 148 148 | 
             
            }
         | 
| 149 149 |  | 
| 150 | 
            +
            void http_mimetype_stats(void);
         | 
| 151 | 
            +
             | 
| 150 152 | 
             
            static void http_lib_cleanup(void *ignr_) {
         | 
| 151 153 | 
             
              (void)ignr_;
         | 
| 152 154 | 
             
              http_mimetype_clear();
         | 
| @@ -185,8 +187,11 @@ static void http_lib_cleanup(void *ignr_) { | |
| 185 187 | 
             
              HTTPLIB_RESET(HTTP_HVALUE_WS_VERSION);
         | 
| 186 188 |  | 
| 187 189 | 
             
            #undef HTTPLIB_RESET
         | 
| 190 | 
            +
              http_mimetype_stats();
         | 
| 188 191 | 
             
            }
         | 
| 189 192 |  | 
| 193 | 
            +
            void http_mimetype_stats(void);
         | 
| 194 | 
            +
             | 
| 190 195 | 
             
            static void http_lib_init(void *ignr_) {
         | 
| 191 196 | 
             
              (void)ignr_;
         | 
| 192 197 | 
             
              if (HTTP_HEADER_ACCEPT_RANGES)
         | 
| @@ -1268,4 +1273,5 @@ static void http_lib_init(void *ignr_) { | |
| 1268 1273 | 
             
              REGISTER_MIME("zirz", "application/vnd.zul");
         | 
| 1269 1274 | 
             
              REGISTER_MIME("zmm", "application/vnd.handheld-entertainment+xml");
         | 
| 1270 1275 | 
             
            #undef REGISTER_MIME
         | 
| 1276 | 
            +
              http_mimetype_stats();
         | 
| 1271 1277 | 
             
            }
         | 
    
        data/ext/iodine/iodine.c
    CHANGED
    
    | @@ -233,9 +233,11 @@ static void iodine_print_startup_message(iodine_start_params_s params) { | |
| 233 233 | 
             
                           " * Iodine %s\n * Ruby %s\n"
         | 
| 234 234 | 
             
                           " * facil.io " FIO_VERSION_STRING " (%s)\n"
         | 
| 235 235 | 
             
                           " * %d Workers X %d Threads per worker.\n"
         | 
| 236 | 
            +
                           " * Maximum %zu open files / sockets per worker.\n"
         | 
| 236 237 | 
             
                           " * Master (root) process: %d.\n",
         | 
| 237 238 | 
             
                           StringValueCStr(iodine_version), StringValueCStr(ruby_version),
         | 
| 238 | 
            -
                           fio_engine(), params.workers, params.threads,  | 
| 239 | 
            +
                           fio_engine(), params.workers, params.threads, fio_capa(),
         | 
| 240 | 
            +
                           fio_parent_pid());
         | 
| 239 241 | 
             
              (void)params;
         | 
| 240 242 | 
             
            }
         | 
| 241 243 |  | 
| @@ -391,8 +393,10 @@ static VALUE iodine_cli_parse(VALUE self) { | |
| 391 393 | 
             
                  FIO_CLI_STRING(
         | 
| 392 394 | 
             
                      "-tls-cert -cert the SSL/TLS public certificate file name."),
         | 
| 393 395 | 
             
                  FIO_CLI_STRING("-tls-key -key the SSL/TLS private key file name."),
         | 
| 394 | 
            -
                  FIO_CLI_STRING( | 
| 395 | 
            -
             | 
| 396 | 
            +
                  FIO_CLI_STRING(
         | 
| 397 | 
            +
                      "-tls-pass -tls-password the password (if any) protecting the "
         | 
| 398 | 
            +
                      "private key file."),
         | 
| 399 | 
            +
                  FIO_CLI_PRINT("\t\t-tls-password is deprecated, use -tls-pass"),
         | 
| 396 400 | 
             
                  FIO_CLI_PRINT_HEADER("Connecting Iodine to Redis:"),
         | 
| 397 401 | 
             
                  FIO_CLI_STRING(
         | 
| 398 402 | 
             
                      "-redis -r an optional Redis URL server address. Default: none."),
         | 
| @@ -409,10 +413,18 @@ static VALUE iodine_cli_parse(VALUE self) { | |
| 409 413 | 
             
                if (level > 0 && level < 100)
         | 
| 410 414 | 
             
                  FIO_LOG_LEVEL = level;
         | 
| 411 415 | 
             
              }
         | 
| 412 | 
            -
             | 
| 416 | 
            +
              if (!fio_cli_get("-w") && getenv("WEB_CONCURRENCY")) {
         | 
| 417 | 
            +
                fio_cli_set("-w", getenv("WEB_CONCURRENCY"));
         | 
| 418 | 
            +
              }
         | 
| 419 | 
            +
              if (!fio_cli_get("-w") && getenv("WORKERS")) {
         | 
| 420 | 
            +
                fio_cli_set("-w", getenv("WORKERS"));
         | 
| 421 | 
            +
              }
         | 
| 413 422 | 
             
              if (fio_cli_get("-w")) {
         | 
| 414 423 | 
             
                iodine_workers_set(IodineModule, INT2NUM(fio_cli_get_i("-w")));
         | 
| 415 424 | 
             
              }
         | 
| 425 | 
            +
              if (!fio_cli_get("-t") && getenv("THREADS")) {
         | 
| 426 | 
            +
                fio_cli_set("-t", getenv("THREADS"));
         | 
| 427 | 
            +
              }
         | 
| 416 428 | 
             
              if (fio_cli_get("-t")) {
         | 
| 417 429 | 
             
                iodine_threads_set(IodineModule, INT2NUM(fio_cli_get_i("-t")));
         | 
| 418 430 | 
             
              }
         | 
| @@ -422,6 +434,9 @@ static VALUE iodine_cli_parse(VALUE self) { | |
| 422 434 | 
             
              if (fio_cli_get_bool("-warmup")) {
         | 
| 423 435 | 
             
                rb_hash_aset(defaults, ID2SYM(rb_intern("warmup_")), Qtrue);
         | 
| 424 436 | 
             
              }
         | 
| 437 | 
            +
              // if (!fio_cli_get("-b") && getenv("ADDRESS")) {
         | 
| 438 | 
            +
              //   fio_cli_set("-b", getenv("ADDRESS"));
         | 
| 439 | 
            +
              // }
         | 
| 425 440 | 
             
              if (fio_cli_get("-b")) {
         | 
| 426 441 | 
             
                if (fio_cli_get("-b")[0] == '/' ||
         | 
| 427 442 | 
             
                    (fio_cli_get("-b")[0] == '.' && fio_cli_get("-b")[1] == '/')) {
         | 
| @@ -433,6 +448,10 @@ static VALUE iodine_cli_parse(VALUE self) { | |
| 433 448 | 
             
                        fio_cli_get("-p"));
         | 
| 434 449 | 
             
                  }
         | 
| 435 450 | 
             
                  fio_cli_set("-p", "0");
         | 
| 451 | 
            +
                } else {
         | 
| 452 | 
            +
                  // if (!fio_cli_get("-p") && getenv("PORT")) {
         | 
| 453 | 
            +
                  //   fio_cli_set("-p", getenv("PORT"));
         | 
| 454 | 
            +
                  // }
         | 
| 436 455 | 
             
                }
         | 
| 437 456 | 
             
                rb_hash_aset(defaults, address_sym, rb_str_new_cstr(fio_cli_get("-b")));
         | 
| 438 457 | 
             
              }
         | 
| @@ -484,7 +503,7 @@ static VALUE iodine_cli_parse(VALUE self) { | |
| 484 503 | 
             
                }
         | 
| 485 504 | 
             
                if (fio_cli_get("-tls-key") && fio_cli_get("-tls-cert")) {
         | 
| 486 505 | 
             
                  fio_tls_cert_add(tls, NULL, fio_cli_get("-tls-cert"),
         | 
| 487 | 
            -
                                   fio_cli_get("-tls-key"), fio_cli_get("-tls- | 
| 506 | 
            +
                                   fio_cli_get("-tls-key"), fio_cli_get("-tls-pass"));
         | 
| 488 507 | 
             
                } else {
         | 
| 489 508 | 
             
                  if (!fio_cli_get_bool("-tls"))
         | 
| 490 509 | 
             
                    FIO_LOG_ERROR("TLS support requires both key and certificate."
         | 
    
        data/ext/iodine/iodine_defer.c
    CHANGED
    
    | @@ -240,17 +240,19 @@ static VALUE iodine_defer_run_after(VALUE self, VALUE milliseconds) { | |
| 240 240 | 
             
              }
         | 
| 241 241 | 
             
              return block;
         | 
| 242 242 | 
             
            }
         | 
| 243 | 
            +
             | 
| 244 | 
            +
            // clang-format off
         | 
| 243 245 | 
             
            /**
         | 
| 244 246 | 
             
            Runs the required block after the specified number of milliseconds have passed.
         | 
| 245 247 | 
             
            Time is counted only once Iodine started running (using {Iodine.start}).
         | 
| 246 248 |  | 
| 247 249 | 
             
            Accepts:
         | 
| 248 250 |  | 
| 249 | 
            -
             | 
| 250 | 
            -
             | 
| 251 | 
            -
             | 
| 252 | 
            -
             | 
| 253 | 
            -
            block | 
| 251 | 
            +
            |   |   |
         | 
| 252 | 
            +
            |---|---|
         | 
| 253 | 
            +
            | `:milliseconds` | the number of milliseconds between event repetitions.|
         | 
| 254 | 
            +
            | `:repetitions` | the number of event repetitions. Defaults to 0 (never ending).|
         | 
| 255 | 
            +
            | `:block` | (required) a block is required, as otherwise there is nothing to|
         | 
| 254 256 | 
             
            perform.
         | 
| 255 257 |  | 
| 256 258 | 
             
            The event will repeat itself until the number of repetitions had been delpeted.
         | 
| @@ -258,6 +260,7 @@ The event will repeat itself until the number of repetitions had been delpeted. | |
| 258 260 | 
             
            Always returns a copy of the block object.
         | 
| 259 261 | 
             
            */
         | 
| 260 262 | 
             
            static VALUE iodine_defer_run_every(int argc, VALUE *argv, VALUE self) {
         | 
| 263 | 
            +
              // clang-format on
         | 
| 261 264 | 
             
              (void)(self);
         | 
| 262 265 | 
             
              VALUE milliseconds, repetitions, block;
         | 
| 263 266 |  | 
| @@ -304,16 +307,18 @@ Sets a block of code to run when Iodine's core state is updated. | |
| 304 307 |  | 
| 305 308 | 
             
            The state event Symbol can be any of the following:
         | 
| 306 309 |  | 
| 307 | 
            -
             | 
| 308 | 
            -
             | 
| 309 | 
            -
             | 
| 310 | 
            -
             | 
| 311 | 
            -
             | 
| 312 | 
            -
             | 
| 313 | 
            -
             | 
| 314 | 
            -
             | 
| 315 | 
            -
             | 
| 316 | 
            -
             | 
| 310 | 
            +
            |  |  |
         | 
| 311 | 
            +
            |---|---|
         | 
| 312 | 
            +
            | `:pre_start` | the block will be called once before starting up the IO reactor. |
         | 
| 313 | 
            +
            | `:before_fork` | the block will be called before each time the IO reactor forks a new worker. |
         | 
| 314 | 
            +
            | `:after_fork` | the block will be called after each fork (both in parent and workers). |
         | 
| 315 | 
            +
            | `:enter_child` | the block will be called by a worker process right after forking. |
         | 
| 316 | 
            +
            | `:enter_master` | the block will be called by the master process after spawning a worker (after forking). |
         | 
| 317 | 
            +
            | `:on_start` | the block will be called every time a *worker* proceess starts. In single process mode, the master process is also a worker. |
         | 
| 318 | 
            +
            | `:on_parent_crush` | the block will be called by each worker the moment it detects the master process crashed. |
         | 
| 319 | 
            +
            | `:on_child_crush` | the block will be called by the parent (master) after a worker process crashed. |
         | 
| 320 | 
            +
            | `:start_shutdown` | the block will be called before starting the shutdown sequence. |
         | 
| 321 | 
            +
            | `:on_finish` | the block will be called just before finishing up (both on chlid and parent processes). |
         | 
| 317 322 |  | 
| 318 323 | 
             
            Code runs in both the parent and the child.
         | 
| 319 324 | 
             
            */
         | 
    
        data/ext/iodine/websockets.c
    CHANGED
    
    
    
        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.19
         | 
| 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-01- | 
| 11 | 
            +
            date: 2019-01-27 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -220,7 +220,7 @@ licenses: | |
| 220 220 | 
             
            - MIT
         | 
| 221 221 | 
             
            metadata:
         | 
| 222 222 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 223 | 
            -
            post_install_message: 'Thank you for installing Iodine 0.7. | 
| 223 | 
            +
            post_install_message: 'Thank you for installing Iodine 0.7.19.
         | 
| 224 224 |  | 
| 225 225 | 
             
            '
         | 
| 226 226 | 
             
            rdoc_options: []
         | 
| @@ -243,8 +243,7 @@ requirements: | |
| 243 243 | 
             
            - Ruby >= 2.2.2 required for Rack 2.
         | 
| 244 244 | 
             
            - Ruby >= 2.5.0 recommended.
         | 
| 245 245 | 
             
            - TLS requires OpenSSL >= 1.1.0
         | 
| 246 | 
            -
             | 
| 247 | 
            -
            rubygems_version: 2.7.7
         | 
| 246 | 
            +
            rubygems_version: 3.0.1
         | 
| 248 247 | 
             
            signing_key: 
         | 
| 249 248 | 
             
            specification_version: 4
         | 
| 250 249 | 
             
            summary: iodine - a fast HTTP / Websocket Server with Pub/Sub support, optimized for
         |