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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a2b1c5f8f5b6ec1d2259cf33e2cde27e3811a2df5715fa3463891062db2c9ae
4
- data.tar.gz: 8b1140297cdbf2501ab145712b5cccce06beb1d7350d0d4d7176e86053d5255a
3
+ metadata.gz: 1dad2816193abeda90adf195c3c9cfcaa53eb9a1c5f1e4ad8364be45cd10bc2f
4
+ data.tar.gz: 02e35b8bbdf6516d210bd8cfc012035a1de2ec3a783e4346152bead0186ba668
5
5
  SHA512:
6
- metadata.gz: 96ce75b3a7ef9548e33e73438b4aaf785a41594b4dec4a214081699c556c60512a54a231748de3f1478f622cb540fd67d3afd6bb87cc1bc38ee32471ab4ce016
7
- data.tar.gz: 40d9d0e4499fd59e7e25f37f300c246c4f9d645246c31a4af7b28f622699a8c12861e0a884ecfd1274451e0a24f5b28be212748286023ff75e6ceb406b6031db
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
- flushed = uuid_data(uuid).rw_hooks->flush(uuid, uuid_data(uuid).rw_udata);
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) && fio_flush(fd2uuid(i)) > 0)
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
- if (rb_hash_aref(rb_opt, as_id) == binary_id) {
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) == redis_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
  }
@@ -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) {
@@ -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__) && !defined(__MINGW32__)
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 = "\x89\x80mask", .length = 2,
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 = "\x89\x00", .length = 2,
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 = "\x8a\x80MASK", .length = 6,
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 = "\x8a\x00", .length = 2,
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
- fio_write2(ws->fd, .data.buffer = "\x88\x00", .length = 2,
732
- .after.dealloc = FIO_DEALLOC_NOOP);
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
  }
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '0.7.46'.freeze
2
+ VERSION = '0.7.49'.freeze
3
3
  end
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.46
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-05-07 00:00:00.000000000 Z
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.46.
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: