iodine 0.7.46 → 0.7.49
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 +12 -0
- data/examples/config.ru +3 -0
- data/ext/iodine/fio.c +4 -2
- data/ext/iodine/iodine_connection.c +8 -5
- data/ext/iodine/iodine_http.c +0 -2
- data/ext/iodine/websocket_parser.h +1 -0
- data/ext/iodine/websockets.c +28 -11
- data/lib/iodine/version.rb +1 -1
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 1dad2816193abeda90adf195c3c9cfcaa53eb9a1c5f1e4ad8364be45cd10bc2f
         | 
| 4 | 
            +
              data.tar.gz: 02e35b8bbdf6516d210bd8cfc012035a1de2ec3a783e4346152bead0186ba668
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: bca7fb5be56837c4a729cef3f755ee4fa8a5a289d448961e01f9449a6e3d76865b03956d7525802a2a1c3768da61b4b8cf8a6088ca63ed57e3b966575e95fb51
         | 
| 7 | 
            +
              data.tar.gz: f2fcb35e2cd7452dbeb7fb20bbe5deb3f661e8a3f3ec387d878a858732a414d3d383320164a8a3164be0cdebf900a14360e60d87488c5d61e5b8105ada6270d8
         | 
    
        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.49
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            **Fix**: Fixes an issue where named arguments for `subscribe` might not be properly recognized.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            #### Change log v.0.7.48 (2022-06-28)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            **Fix**: Fixes an issue with `pong` WebSocket frames when a client sends a WebSocket `ping`. Credit to Lucas Kuan (@lucaskuan) for finding this issue and for PR #124.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            #### Change log v.0.7.47 (2022-05-11)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            **Fix**: Fixes an issue that causes `Rack::Lint` to complain about `SERVER_PORT` being an empty string. Credit to @adam12 (Adam Daniels) for PR #108 and issue #107.
         | 
| 20 | 
            +
             | 
| 9 21 | 
             
            #### Change log v.0.7.46 (2022-05-06)
         | 
| 10 22 |  | 
| 11 23 | 
             
            **Fix**: Fixes the (erroneous) default insertion of the `last-modified` header in order to both better express the intent of RFC 2616 and prevent conflict with the `Rack::ETag` middleware. Credit to @raxoft (Patrik Rak) for opening issue #122.
         | 
    
        data/examples/config.ru
    CHANGED
    
    | @@ -12,6 +12,9 @@ | |
| 12 12 | 
             
            #
         | 
| 13 13 | 
             
            #      ab -c 2000 -t 5 -n 1000000 -k http://127.0.0.1:3000/
         | 
| 14 14 | 
             
            #      wrk -c2000 -d5 -t12 http://localhost:3000/
         | 
| 15 | 
            +
            #
         | 
| 16 | 
            +
            # Test websocket echo using the browser. For example:
         | 
| 17 | 
            +
            #      ws = new WebSocket("ws://localhost:3000"); ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data);}; ws.onclose = function(e) {console.log("closed")}; ws.onopen = function(e) {ws.send("hi");};
         | 
| 15 18 |  | 
| 16 19 |  | 
| 17 20 | 
             
            # A simple router - Checks for Websocket Upgrade and answers HTTP.
         | 
    
        data/ext/iodine/fio.c
    CHANGED
    
    | @@ -3689,7 +3689,8 @@ closed: | |
| 3689 3689 | 
             
              return -1;
         | 
| 3690 3690 |  | 
| 3691 3691 | 
             
            flush_rw_hook:
         | 
| 3692 | 
            -
               | 
| 3692 | 
            +
              if(uuid_data(uuid).rw_hooks)
         | 
| 3693 | 
            +
                flushed = uuid_data(uuid).rw_hooks->flush(uuid, uuid_data(uuid).rw_udata);
         | 
| 3693 3694 | 
             
              fio_unlock(&uuid_data(uuid).sock_lock);
         | 
| 3694 3695 | 
             
              if (!flushed)
         | 
| 3695 3696 | 
             
                return 0;
         | 
| @@ -3749,7 +3750,8 @@ size_t fio_flush_all(void) { | |
| 3749 3750 | 
             
                return 0;
         | 
| 3750 3751 | 
             
              size_t count = 0;
         | 
| 3751 3752 | 
             
              for (uintptr_t i = 0; i <= fio_data->max_protocol_fd; ++i) {
         | 
| 3752 | 
            -
                if ((fd_data(i).open || fd_data(i).packet) && | 
| 3753 | 
            +
                if ((fd_data(i).open || fd_data(i).packet) &&
         | 
| 3754 | 
            +
                    fd_data(i).rw_hooks && fio_flush(fd2uuid(i)) > 0)
         | 
| 3753 3755 | 
             
                  ++count;
         | 
| 3754 3756 | 
             
              }
         | 
| 3755 3757 | 
             
              return count;
         | 
| @@ -518,10 +518,10 @@ static iodine_sub_args_s iodine_subscribe_args(int argc, VALUE *argv) { | |
| 518 518 | 
             
                /* single argument must be a Hash / channel name */
         | 
| 519 519 | 
             
                if (TYPE(argv[0]) == T_HASH) {
         | 
| 520 520 | 
             
                  rb_opt = argv[0];
         | 
| 521 | 
            -
                  ret.channel = rb_hash_aref(argv[0], to_id);
         | 
| 521 | 
            +
                  ret.channel = rb_hash_aref(argv[0], ID2SYM(to_id));
         | 
| 522 522 | 
             
                  if (ret.channel == Qnil || ret.channel == Qfalse) {
         | 
| 523 523 | 
             
                    /* temporary backport support */
         | 
| 524 | 
            -
                    ret.channel = rb_hash_aref(argv[0], channel_id);
         | 
| 524 | 
            +
                    ret.channel = rb_hash_aref(argv[0], ID2SYM(channel_id));
         | 
| 525 525 | 
             
                    if (ret.channel != Qnil) {
         | 
| 526 526 | 
             
                      FIO_LOG_WARNING("use of :channel in subscribe is deprecated.");
         | 
| 527 527 | 
             
                    }
         | 
| @@ -546,13 +546,16 @@ static iodine_sub_args_s iodine_subscribe_args(int argc, VALUE *argv) { | |
| 546 546 | 
             
              Check_Type(ret.channel, T_STRING);
         | 
| 547 547 |  | 
| 548 548 | 
             
              if (rb_opt) {
         | 
| 549 | 
            -
                 | 
| 549 | 
            +
                VALUE tmp = Qnil;
         | 
| 550 | 
            +
                if ((tmp = rb_hash_aref(rb_opt, ID2SYM(as_id))) != Qnil &&
         | 
| 551 | 
            +
                    TYPE(tmp) == T_SYMBOL && rb_sym2id(tmp) == binary_id) {
         | 
| 550 552 | 
             
                  ret.binary = 1;
         | 
| 551 553 | 
             
                }
         | 
| 552 | 
            -
                if (rb_hash_aref(rb_opt, match_id)  | 
| 554 | 
            +
                if ((tmp = rb_hash_aref(rb_opt, ID2SYM(match_id))) != Qnil &&
         | 
| 555 | 
            +
                    TYPE(tmp) == T_SYMBOL && rb_sym2id(tmp) == redis_id) {
         | 
| 553 556 | 
             
                  ret.pattern = FIO_MATCH_GLOB;
         | 
| 554 557 | 
             
                }
         | 
| 555 | 
            -
                ret.block = rb_hash_aref(rb_opt, handler_id);
         | 
| 558 | 
            +
                ret.block = rb_hash_aref(rb_opt, ID2SYM(handler_id));
         | 
| 556 559 | 
             
                if (ret.block != Qnil) {
         | 
| 557 560 | 
             
                  IodineStore.add(ret.block);
         | 
| 558 561 | 
             
                }
         | 
    
        data/ext/iodine/iodine_http.c
    CHANGED
    
    | @@ -369,7 +369,6 @@ static inline VALUE copy2env(iodine_http_request_handle_s *handle) { | |
| 369 369 | 
             
              if (*pos == 0) {
         | 
| 370 370 | 
             
                rb_hash_aset(env, SERVER_NAME,
         | 
| 371 371 | 
             
                             rb_enc_str_new(tmp.data, tmp.len, IodineBinaryEncoding));
         | 
| 372 | 
            -
                rb_hash_aset(env, SERVER_PORT, QUERY_ESTRING);
         | 
| 373 372 | 
             
              } else {
         | 
| 374 373 | 
             
                rb_hash_aset(
         | 
| 375 374 | 
             
                    env, SERVER_NAME,
         | 
| @@ -869,7 +868,6 @@ static void initialize_env_template(void) { | |
| 869 868 | 
             
              rb_hash_aset(env_template_no_upgrade, REMOTE_ADDR, QUERY_STRING);
         | 
| 870 869 | 
             
              rb_hash_aset(env_template_no_upgrade, REQUEST_METHOD, QUERY_STRING);
         | 
| 871 870 | 
             
              rb_hash_aset(env_template_no_upgrade, SERVER_NAME, QUERY_STRING);
         | 
| 872 | 
            -
              rb_hash_aset(env_template_no_upgrade, SERVER_PORT, QUERY_ESTRING);
         | 
| 873 871 | 
             
              rb_hash_aset(env_template_no_upgrade, SERVER_PROTOCOL, QUERY_STRING);
         | 
| 874 872 |  | 
| 875 873 | 
             
              /* WebSocket upgrade support */
         | 
| @@ -453,6 +453,7 @@ static uint64_t websocket_consume(void *buffer, uint64_t len, void *udata, | |
| 453 453 | 
             
                  fprintf(stderr, "ERROR: WebSocket protocol error - unmasked data.\n");
         | 
| 454 454 | 
             
            #endif
         | 
| 455 455 | 
             
                  websocket_on_protocol_error(udata);
         | 
| 456 | 
            +
                  return 0;
         | 
| 456 457 | 
             
                }
         | 
| 457 458 | 
             
                /* call callback */
         | 
| 458 459 | 
             
                switch (pos[0] & 15) {
         | 
    
        data/ext/iodine/websockets.c
    CHANGED
    
    | @@ -28,7 +28,8 @@ Feel free to copy, use and enjoy according to the license provided. | |
| 28 28 |  | 
| 29 29 | 
             
            #include <websocket_parser.h>
         | 
| 30 30 |  | 
| 31 | 
            -
            #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) && | 
| 31 | 
            +
            #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) &&                 \
         | 
| 32 | 
            +
                !defined(__MINGW32__)
         | 
| 32 33 | 
             
            #include <endian.h>
         | 
| 33 34 | 
             
            #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) &&                 \
         | 
| 34 35 | 
             
                __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
         | 
| @@ -126,6 +127,8 @@ struct ws_s { | |
| 126 127 | 
             
              struct buffer_s buffer;
         | 
| 127 128 | 
             
              /** data length (how much of the buffer actually used). */
         | 
| 128 129 | 
             
              size_t length;
         | 
| 130 | 
            +
              /** total data length (including continuation frames). */
         | 
| 131 | 
            +
              size_t total_length;
         | 
| 129 132 | 
             
              /** message buffer. */
         | 
| 130 133 | 
             
              FIOBJ msg;
         | 
| 131 134 | 
             
              /** latest text state. */
         | 
| @@ -154,20 +157,24 @@ static void websocket_on_unwrapped(void *ws_p, void *msg, uint64_t len, | |
| 154 157 | 
             
                                               char first, char last, char text,
         | 
| 155 158 | 
             
                                               unsigned char rsv) {
         | 
| 156 159 | 
             
              ws_s *ws = ws_p;
         | 
| 160 | 
            +
              if (!ws)
         | 
| 161 | 
            +
                return;
         | 
| 157 162 | 
             
              if (last && first) {
         | 
| 158 163 | 
             
                ws->on_message(ws, (fio_str_info_s){.data = msg, .len = len},
         | 
| 159 164 | 
             
                               (uint8_t)text);
         | 
| 160 165 | 
             
                return;
         | 
| 161 166 | 
             
              }
         | 
| 167 | 
            +
              if (ws->msg == FIOBJ_INVALID)
         | 
| 168 | 
            +
                ws->msg = fiobj_str_buf(len);
         | 
| 169 | 
            +
              ws->total_length += len;
         | 
| 162 170 | 
             
              if (first) {
         | 
| 163 171 | 
             
                ws->is_text = (uint8_t)text;
         | 
| 164 | 
            -
                if (ws->msg == FIOBJ_INVALID)
         | 
| 165 | 
            -
                  ws->msg = fiobj_str_buf(len);
         | 
| 166 | 
            -
                fiobj_str_resize(ws->msg, 0);
         | 
| 167 172 | 
             
              }
         | 
| 168 173 | 
             
              fiobj_str_write(ws->msg, msg, len);
         | 
| 169 174 | 
             
              if (last) {
         | 
| 170 175 | 
             
                ws->on_message(ws, fiobj_obj2cstr(ws->msg), ws->is_text);
         | 
| 176 | 
            +
                fiobj_str_resize(ws->msg, 0);
         | 
| 177 | 
            +
                ws->total_length = 0;
         | 
| 171 178 | 
             
              }
         | 
| 172 179 |  | 
| 173 180 | 
             
              (void)rsv;
         | 
| @@ -183,15 +190,19 @@ static void websocket_on_protocol_ping(void *ws_p, void *msg_, uint64_t len) { | |
| 183 190 | 
             
                fio_write2(ws->fd, .data.buffer = buff, .length = len);
         | 
| 184 191 | 
             
              } else {
         | 
| 185 192 | 
             
                if (((ws_s *)ws)->is_client) {
         | 
| 186 | 
            -
                  fio_write2(ws->fd, .data.buffer = "\ | 
| 193 | 
            +
                  fio_write2(ws->fd, .data.buffer = "\x8a\x80mask", .length = 6,
         | 
| 187 194 | 
             
                             .after.dealloc = FIO_DEALLOC_NOOP);
         | 
| 188 195 | 
             
                } else {
         | 
| 189 | 
            -
                  fio_write2(ws->fd, .data.buffer = "\ | 
| 196 | 
            +
                  fio_write2(ws->fd, .data.buffer = "\x8a\x00", .length = 2,
         | 
| 190 197 | 
             
                             .after.dealloc = FIO_DEALLOC_NOOP);
         | 
| 191 198 | 
             
                }
         | 
| 192 199 | 
             
              }
         | 
| 200 | 
            +
              FIO_LOG_DEBUG("Received ping and sent pong for Websocket %p (%d)", ws_p,
         | 
| 201 | 
            +
                            (int)(((ws_s *)ws_p)->fd));
         | 
| 193 202 | 
             
            }
         | 
| 194 203 | 
             
            static void websocket_on_protocol_pong(void *ws_p, void *msg, uint64_t len) {
         | 
| 204 | 
            +
              FIO_LOG_DEBUG("Received pong for Websocket %p (%d)", ws_p,
         | 
| 205 | 
            +
                            (int)(((ws_s *)ws_p)->fd));
         | 
| 195 206 | 
             
              (void)len;
         | 
| 196 207 | 
             
              (void)msg;
         | 
| 197 208 | 
             
              (void)ws_p;
         | 
| @@ -220,6 +231,7 @@ static void ws_ping(intptr_t fd, fio_protocol_s *ws) { | |
| 220 231 | 
             
                fio_write2(fd, .data.buffer = "\x89\x00", .length = 2,
         | 
| 221 232 | 
             
                           .after.dealloc = FIO_DEALLOC_NOOP);
         | 
| 222 233 | 
             
              }
         | 
| 234 | 
            +
              FIO_LOG_DEBUG("Sent ping for Websocket %p (%d)", (void *)ws, (int)fd);
         | 
| 223 235 | 
             
            }
         | 
| 224 236 |  | 
| 225 237 | 
             
            static void on_close(intptr_t uuid, fio_protocol_s *_ws) {
         | 
| @@ -238,10 +250,10 @@ static uint8_t on_shutdown(intptr_t fd, fio_protocol_s *ws) { | |
| 238 250 | 
             
              if (ws && ((ws_s *)ws)->on_shutdown)
         | 
| 239 251 | 
             
                ((ws_s *)ws)->on_shutdown((ws_s *)ws);
         | 
| 240 252 | 
             
              if (((ws_s *)ws)->is_client) {
         | 
| 241 | 
            -
                fio_write2(fd, .data.buffer = "\ | 
| 253 | 
            +
                fio_write2(fd, .data.buffer = "\x88\x80MASK", .length = 6,
         | 
| 242 254 | 
             
                           .after.dealloc = FIO_DEALLOC_NOOP);
         | 
| 243 255 | 
             
              } else {
         | 
| 244 | 
            -
                fio_write2(fd, .data.buffer = "\ | 
| 256 | 
            +
                fio_write2(fd, .data.buffer = "\x88\x00", .length = 2,
         | 
| 245 257 | 
             
                           .after.dealloc = FIO_DEALLOC_NOOP);
         | 
| 246 258 | 
             
              }
         | 
| 247 259 | 
             
              return 0;
         | 
| @@ -255,7 +267,7 @@ static void on_data(intptr_t sockfd, fio_protocol_s *ws_) { | |
| 255 267 | 
             
                  websocket_buffer_peek(ws->buffer.data, ws->length);
         | 
| 256 268 | 
             
              const uint64_t raw_length = info.packet_length + info.head_length;
         | 
| 257 269 | 
             
              /* test expected data amount */
         | 
| 258 | 
            -
              if (ws->max_msg_size < raw_length) {
         | 
| 270 | 
            +
              if (ws->max_msg_size < raw_length + ws->total_length) {
         | 
| 259 271 | 
             
                /* too big */
         | 
| 260 272 | 
             
                websocket_close(ws);
         | 
| 261 273 | 
             
                return;
         | 
| @@ -728,8 +740,13 @@ int websocket_write(ws_s *ws, fio_str_info_s msg, uint8_t is_text) { | |
| 728 740 | 
             
            }
         | 
| 729 741 | 
             
            /** Closes a websocket connection. */
         | 
| 730 742 | 
             
            void websocket_close(ws_s *ws) {
         | 
| 731 | 
            -
               | 
| 732 | 
            -
             | 
| 743 | 
            +
              if (ws->is_client) {
         | 
| 744 | 
            +
                fio_write2(ws->fd, .data.buffer = "\x88\x80MASK", .length = 6,
         | 
| 745 | 
            +
                           .after.dealloc = FIO_DEALLOC_NOOP);
         | 
| 746 | 
            +
              } else {
         | 
| 747 | 
            +
                fio_write2(ws->fd, .data.buffer = "\x88\x00", .length = 2,
         | 
| 748 | 
            +
                           .after.dealloc = FIO_DEALLOC_NOOP);
         | 
| 749 | 
            +
              }
         | 
| 733 750 | 
             
              fio_close(ws->fd);
         | 
| 734 751 | 
             
              return;
         | 
| 735 752 | 
             
            }
         | 
    
        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.49
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Boaz Segev
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2022- | 
| 11 | 
            +
            date: 2022-09-12 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rake
         | 
| @@ -245,7 +245,7 @@ licenses: | |
| 245 245 | 
             
            metadata:
         | 
| 246 246 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 247 247 | 
             
            post_install_message: |-
         | 
| 248 | 
            -
              Thank you for installing Iodine 0.7. | 
| 248 | 
            +
              Thank you for installing Iodine 0.7.49.
         | 
| 249 249 | 
             
              Remember: if iodine supports your business, it's only fair to give value back (code contributions / donations).
         | 
| 250 250 | 
             
            rdoc_options: []
         | 
| 251 251 | 
             
            require_paths:
         |