rage-iodine 4.4.0 → 5.1.0

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: 303b190ec5ec7b3f67818e9c1a3b3b87352547c338685e3af8a319588652e945
4
- data.tar.gz: 9060a19940097808b32b0d210a11c2bcc9fc1354d123be5fd6c61f2a9d5f18fa
3
+ metadata.gz: 5780b0bd483cbceaee368b8416a0fc6cdfc7fcf155f67eaa5715a3748790e032
4
+ data.tar.gz: 3191054adbffcac948151b9cb1367033819b3639ffc027bc052313bb216a7d20
5
5
  SHA512:
6
- metadata.gz: e98de1cdf973e91d5b2401f112fdc9487625ba90e985399914cf4ce387040255e35c4073d80ad89e6337800777f2d5bc3b89d7909cb4dfdd582afc89d8071309
7
- data.tar.gz: b1e68feee5ba155887c7ea7ab9c372bacc3724a79c83849b19f20bdb701b7e4412a90ea90a5e7858566248dd0c01903c2f9e6f7e6272522f9e13e803c031dcfb
6
+ metadata.gz: 6e07a2923d319c9e561216101dd59a31a13bb2a85f370e89d40718ed99fd1293990ecf033bd8ca23ccb65e1ea5395500529503a59d208a01c4d96a36cab90ee4
7
+ data.tar.gz: 2b57180029bf202fb8b825304b96e7f4307220576920c05e052b79ed2292d3780437ba7056876222bf33f3d120692794b182bab816f6c3ffedda2d3d987e3b38
data/CHANGELOG.md CHANGED
@@ -6,6 +6,17 @@ Please notice that this change log contains changes for upcoming releases as wel
6
6
 
7
7
  ## Changes:
8
8
 
9
+ #### Change log v.5.1.0 (2026-03-04)
10
+
11
+ **Update**: Verify SSE connection are open before calling the protocol object
12
+ **Update**: Invert upgrade flow to move the upgrade decisions to the framework level
13
+
14
+ #### Change log v.5.0.0 (2026-02-25)
15
+
16
+ **Update**: Stop formatting SSE events
17
+ **Update**: Update accept header check for SSE
18
+ **Update**: Support fiber pauses during upgrades
19
+
9
20
  #### Change log v.4.4.0 (2025-11-28)
10
21
 
11
22
  **Update**: Update the `rackup` interface.
@@ -12,12 +12,12 @@ Feel free to copy, use and enjoy according to the license provided.
12
12
  Internal Request / Response Handlers
13
13
  ***************************************************************************** */
14
14
 
15
+ /* Used by HTTP client response handler for WebSocket upgrade detection */
15
16
  static uint64_t http_upgrade_hash = 0;
17
+
16
18
  /** Use this function to handle HTTP requests.*/
17
19
  void http_on_request_handler______internal(http_s *h,
18
20
  http_settings_s *settings) {
19
- if (!http_upgrade_hash)
20
- http_upgrade_hash = fiobj_hash_string("upgrade", 7);
21
21
  h->udata = settings->udata;
22
22
 
23
23
  static uint64_t host_hash = 0;
@@ -34,14 +34,7 @@ void http_on_request_handler______internal(http_s *h,
34
34
  }
35
35
  }
36
36
 
37
- FIOBJ t = fiobj_hash_get2(h->headers, http_upgrade_hash);
38
- if (t)
39
- goto upgrade;
40
-
41
- if (fiobj_iseq(
42
- fiobj_hash_get2(h->headers, fiobj_obj2hash(HTTP_HEADER_ACCEPT)),
43
- HTTP_HVALUE_SSE_MIME))
44
- goto eventsource;
37
+ /* Static file handling */
45
38
  if (settings->public_folder &&
46
39
  (fiobj_obj2cstr(h->method).len != 4 || strncasecmp("post", fiobj_obj2cstr(h->method).data, 4))) {
47
40
  fio_str_info_s path_str = fiobj_obj2cstr(h->path);
@@ -51,24 +44,11 @@ void http_on_request_handler______internal(http_s *h,
51
44
  return;
52
45
  }
53
46
  }
47
+
48
+ /* Always call on_request - let the framework decide upgrades */
54
49
  settings->on_request(h);
55
50
  return;
56
51
 
57
- upgrade:
58
- if (1) {
59
- fiobj_dup(t); /* allow upgrade name access after http_finish */
60
- fio_str_info_s val = fiobj_obj2cstr(t);
61
- if (val.data[0] == 'h' && val.data[1] == '2') {
62
- http_send_error(h, 400);
63
- } else {
64
- settings->on_upgrade(h, val.data, val.len);
65
- }
66
- fiobj_free(t);
67
- return;
68
- }
69
- eventsource:
70
- settings->on_upgrade(h, (char *)"sse", 3);
71
- return;
72
52
  missing_host:
73
53
  FIO_LOG_DEBUG("missing Host header");
74
54
  http_send_error(h, 400);
@@ -197,24 +197,7 @@ static VALUE iodine_connection_write(VALUE self, VALUE data) {
197
197
  rb_enc_get(data) == IodineUTF8Encoding);
198
198
  return Qtrue;
199
199
  break;
200
- case IODINE_CONNECTION_SSE:
201
- /* SSE */
202
- #if 1
203
- http_sse_write(c->info.arg, .data = IODINE_RSTRINFO(data));
204
- return Qtrue;
205
- #else
206
- if (rb_enc_get(data) == IodineUTF8Encoding) {
207
- http_sse_write(c->info.arg, .data = {.data = RSTRING_PTR(data),
208
- .len = RSTRING_LEN(data)});
209
- return Qtrue;
210
- }
211
- fprintf(stderr, "WARNING: ignoring an attept to write binary data to "
212
- "non-binary protocol (SSE).\n");
213
- return Qfalse;
214
- // rb_raise(rb_eEncodingError,
215
- // "This Connection type requires data to be UTF-8 encoded.");
216
- #endif
217
- break;
200
+ case IODINE_CONNECTION_SSE: /* SSE - raw bytes, framework handles formatting */
218
201
  case IODINE_CONNECTION_RAW: /* fallthrough */
219
202
  default: {
220
203
  fio_write(c->info.uuid, RSTRING_PTR(data), RSTRING_LEN(data));
@@ -447,9 +430,7 @@ static void iodine_on_pubsub(fio_msg_s *msg) {
447
430
  }
448
431
  return;
449
432
  }
450
- case IODINE_CONNECTION_SSE:
451
- http_sse_write(data->info.arg, .data = msg->msg);
452
- return;
433
+ case IODINE_CONNECTION_SSE: /* SSE - raw bytes, framework handles formatting */
453
434
  default:
454
435
  fio_write(data->info.uuid, msg->msg.data, msg->msg.len);
455
436
  return;
@@ -62,10 +62,9 @@ static ID iodine_call_proc_id;
62
62
  static ID fiber_result_var_id;
63
63
  static VALUE http_wait_directive;
64
64
  static ID fiber_id_method_id;
65
+ static ID iodine_env_var_id;
65
66
 
66
- static VALUE env_template_no_upgrade;
67
- static VALUE env_template_websockets;
68
- static VALUE env_template_sse;
67
+ static VALUE env_template;
69
68
 
70
69
  static rb_encoding *IodineUTF8Encoding;
71
70
  static rb_encoding *IodineBinaryEncoding;
@@ -122,11 +121,6 @@ typedef struct {
122
121
  IODINE_HTTP_WAIT,
123
122
  IODINE_HTTP_DEFERRED,
124
123
  } type;
125
- enum iodine_upgrade_type_enum {
126
- IODINE_UPGRADE_NONE = 0,
127
- IODINE_UPGRADE_WEBSOCKET,
128
- IODINE_UPGRADE_SSE,
129
- } upgrade;
130
124
  } iodine_http_request_handle_s;
131
125
 
132
126
  /* *****************************************************************************
@@ -233,15 +227,24 @@ static void iodine_sse_on_shutdown(http_sse_s *sse) {
233
227
  Qnil);
234
228
  }
235
229
  static void iodine_sse_on_close(http_sse_s *sse) {
230
+ if (http_sse2uuid(sse) == -1) {
231
+ // Connection was already closed, skip silently
232
+ return;
233
+ }
236
234
  iodine_connection_fire_event((VALUE)sse->udata, IODINE_CONNECTION_ON_CLOSE,
237
235
  Qnil);
238
236
  }
239
237
 
240
238
  static void iodine_sse_on_open(http_sse_s *sse) {
239
+ intptr_t uuid = http_sse2uuid(sse);
240
+ if (uuid == -1) {
241
+ // Connection was closed before on_open could fire, skip silently
242
+ return;
243
+ }
241
244
  VALUE h = (VALUE)sse->udata;
242
245
  iodine_connection_s *c = iodine_connection_CData(h);
243
246
  c->arg = sse;
244
- c->uuid = http_sse2uuid(sse);
247
+ c->uuid = uuid;
245
248
  iodine_connection_fire_event(h, IODINE_CONNECTION_ON_OPEN, Qnil);
246
249
  sse->on_ready = iodine_sse_on_ready;
247
250
  fio_force_event(c->uuid, FIO_EVENT_ON_READY);
@@ -321,18 +324,7 @@ static int iodine_copy2env_task(FIOBJ o, void *env_) {
321
324
  static inline VALUE copy2env(iodine_http_request_handle_s *handle) {
322
325
  VALUE env;
323
326
  http_s *h = handle->h;
324
- switch (handle->upgrade) {
325
- case IODINE_UPGRADE_WEBSOCKET:
326
- env = rb_hash_dup(env_template_websockets);
327
- break;
328
- case IODINE_UPGRADE_SSE:
329
- env = rb_hash_dup(env_template_sse);
330
- break;
331
- case IODINE_UPGRADE_NONE: /* fallthrough */
332
- default:
333
- env = rb_hash_dup(env_template_no_upgrade);
334
- break;
335
- }
327
+ env = rb_hash_dup(env_template);
336
328
  IodineStore.add(env);
337
329
 
338
330
  fio_str_info_s tmp;
@@ -612,6 +604,8 @@ static inline int ruby2c_review_upgrade(iodine_http_request_handle_s *req,
612
604
  VALUE rbresponse, VALUE env) {
613
605
  http_s *h = req->h;
614
606
  VALUE handler;
607
+ VALUE upgrade_type;
608
+
615
609
  if ((handler = rb_hash_aref(env, IODINE_R_HIJACK_CB)) != Qnil) {
616
610
  // send headers
617
611
  http_finish(h);
@@ -625,37 +619,29 @@ static inline int ruby2c_review_upgrade(iodine_http_request_handle_s *req,
625
619
  goto upgraded;
626
620
  } else if ((handler = rb_hash_aref(env, UPGRADE_TCP)) != Qnil) {
627
621
  goto tcp_ip_upgrade;
628
- } else {
629
- switch (req->upgrade) {
630
- case IODINE_UPGRADE_WEBSOCKET:
631
- if ((handler = rb_hash_aref(env, RACK_UPGRADE)) != Qnil) {
632
- // use response as existing base for native websocket upgrade
633
- iodine_ws_attach(h, handler, env);
634
- goto upgraded;
635
- }
636
- break;
637
- case IODINE_UPGRADE_SSE:
638
- if ((handler = rb_hash_aref(env, RACK_UPGRADE)) != Qnil) {
639
- // use response as existing base for SSE upgrade
640
- iodine_sse_attach(h, handler, env);
641
- goto upgraded;
642
- }
643
- break;
644
- default:
645
- if ((handler = rb_hash_aref(env, RACK_UPGRADE)) != Qnil) {
646
- tcp_ip_upgrade : {
647
- // use response as existing base for raw TCP/IP upgrade
648
- intptr_t uuid = http_hijack(h, NULL);
649
- // send headers
650
- http_finish(h);
651
- // upgrade protocol to raw TCP/IP
652
- iodine_tcp_attch_uuid(uuid, handler);
653
- goto upgraded;
654
- }
655
- }
656
- break;
622
+ }
623
+
624
+ handler = rb_hash_aref(env, RACK_UPGRADE);
625
+ if (handler == Qnil)
626
+ return 0;
627
+
628
+ upgrade_type = rb_hash_aref(env, RACK_UPGRADE_Q);
629
+
630
+ if (upgrade_type == RACK_UPGRADE_WEBSOCKET) {
631
+ iodine_ws_attach(h, handler, env);
632
+ goto upgraded;
633
+ } else if (upgrade_type == RACK_UPGRADE_SSE) {
634
+ iodine_sse_attach(h, handler, env);
635
+ goto upgraded;
636
+ } else if (RTEST(upgrade_type)) {
637
+ tcp_ip_upgrade : {
638
+ intptr_t uuid = http_hijack(h, NULL);
639
+ http_finish(h);
640
+ iodine_tcp_attch_uuid(uuid, handler);
641
+ goto upgraded;
657
642
  }
658
643
  }
644
+
659
645
  return 0;
660
646
 
661
647
  upgraded:
@@ -673,14 +659,15 @@ Handling HTTP requests
673
659
 
674
660
  static inline void *iodine_handle_request_in_GVL(void *handle_) {
675
661
  iodine_http_request_handle_s *handle = handle_;
676
- VALUE rbresponse = 0;
677
- VALUE env = 0, tmp;
662
+ VALUE rbresponse = Qnil;
663
+ VALUE env = Qnil, tmp;
678
664
  http_s *h = handle->h;
679
665
  if (!h->udata)
680
666
  goto err_not_found;
681
667
 
682
668
  if (handle->type == IODINE_HTTP_DEFERRED) {
683
669
  rbresponse = rb_ivar_get((VALUE)h->fiber, fiber_result_var_id);
670
+ env = rb_ivar_get((VALUE)h->fiber, iodine_env_var_id);
684
671
  } else {
685
672
  // create / register env variable
686
673
  env = copy2env(handle);
@@ -698,7 +685,9 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
698
685
  tmp = rb_ary_entry(rbresponse, 0);
699
686
  // rack will return `[:__http_defer__, fiber_to_wait_on]` in case the request needs to be paused
700
687
  if (TYPE(tmp) == T_SYMBOL && tmp == http_wait_directive) {
701
- h->fiber = (void *)IodineStore.add(rb_ary_entry(rbresponse, 1));
688
+ VALUE fiber = rb_ary_entry(rbresponse, 1);
689
+ rb_ivar_set(fiber, iodine_env_var_id, env);
690
+ h->fiber = (void *)IodineStore.add(fiber);
702
691
  goto defer;
703
692
  }
704
693
 
@@ -741,7 +730,7 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
741
730
  // review each header and write it to the response.
742
731
  rb_hash_foreach(response_headers, for_each_header_data, (VALUE)(h));
743
732
  // review for upgrade.
744
- if (handle->type != IODINE_HTTP_DEFERRED && (intptr_t)h->status < 300 &&
733
+ if ((intptr_t)h->status < 300 && env != Qnil &&
745
734
  ruby2c_review_upgrade(handle, rbresponse, env))
746
735
  goto external_done;
747
736
  // send the request body.
@@ -826,7 +815,6 @@ iodine_perform_handle_action(iodine_http_request_handle_s handle) {
826
815
  static inline void http_resume_deferred_request_handler(http_s *h) {
827
816
  iodine_http_request_handle_s handle = (iodine_http_request_handle_s){
828
817
  .h = h,
829
- .upgrade = IODINE_UPGRADE_NONE,
830
818
  .type = IODINE_HTTP_DEFERRED,
831
819
  };
832
820
 
@@ -857,7 +845,6 @@ static inline void http_pause_request_handler(http_pause_handle_s *s) {
857
845
  static void on_rack_request(http_s *h) {
858
846
  iodine_http_request_handle_s handle = (iodine_http_request_handle_s){
859
847
  .h = h,
860
- .upgrade = IODINE_UPGRADE_NONE,
861
848
  };
862
849
  IodineCaller.enterGVL((void *(*)(void *))iodine_handle_request_in_GVL,
863
850
  &handle);
@@ -869,33 +856,15 @@ static void on_rack_request(http_s *h) {
869
856
  }
870
857
  }
871
858
 
872
- static void on_rack_upgrade(http_s *h, char *proto, size_t len) {
873
- iodine_http_request_handle_s handle = (iodine_http_request_handle_s){.h = h};
874
- if (len == 9 && (proto[1] == 'e' || proto[1] == 'E')) {
875
- handle.upgrade = IODINE_UPGRADE_WEBSOCKET;
876
- } else if (len == 3 && proto[0] == 's') {
877
- handle.upgrade = IODINE_UPGRADE_SSE;
878
- }
879
- /* when we stop supporting custom Upgrade headers: */
880
- // else {
881
- // http_send_error(h, 400);
882
- // return;
883
- // }
884
- IodineCaller.enterGVL(iodine_handle_request_in_GVL, &handle);
885
- iodine_perform_handle_action(handle);
886
- (void)proto;
887
- (void)len;
888
- }
889
-
890
859
  /* *****************************************************************************
891
860
  Rack `env` Template Initialization
892
861
  ***************************************************************************** */
893
862
 
894
863
  static void initialize_env_template(void) {
895
- if (env_template_no_upgrade)
864
+ if (env_template)
896
865
  return;
897
- env_template_no_upgrade = rb_hash_new();
898
- IodineStore.add(env_template_no_upgrade);
866
+ env_template = rb_hash_new();
867
+ IodineStore.add(env_template);
899
868
 
900
869
  #define add_str_to_env(env, key, value) \
901
870
  { \
@@ -912,9 +881,9 @@ static void initialize_env_template(void) {
912
881
  rb_hash_aset((env), k, value); \
913
882
  }
914
883
 
915
- /* Set global template */
916
- rb_hash_aset(env_template_no_upgrade, RACK_UPGRADE_Q, Qnil);
917
- rb_hash_aset(env_template_no_upgrade, RACK_UPGRADE, Qnil);
884
+ /* Set global template - framework will set rack.upgrade? if it wants an upgrade */
885
+ rb_hash_aset(env_template, RACK_UPGRADE_Q, Qnil);
886
+ rb_hash_aset(env_template, RACK_UPGRADE, Qnil);
918
887
  {
919
888
  /* add the rack.version */
920
889
  static VALUE rack_version = 0;
@@ -925,7 +894,7 @@ static void initialize_env_template(void) {
925
894
  rb_global_variable(&rack_version);
926
895
  rb_ary_freeze(rack_version);
927
896
  }
928
- add_value_to_env(env_template_no_upgrade, "rack.version", rack_version);
897
+ add_value_to_env(env_template, "rack.version", rack_version);
929
898
  }
930
899
 
931
900
  {
@@ -933,37 +902,27 @@ static void initialize_env_template(void) {
933
902
  if (!sn || (sn[0] == '/' && sn[1] == 0)) {
934
903
  sn = "";
935
904
  }
936
- add_str_to_env(env_template_no_upgrade, "SCRIPT_NAME", sn);
905
+ add_str_to_env(env_template, "SCRIPT_NAME", sn);
937
906
  }
938
- rb_hash_aset(env_template_no_upgrade, IODINE_R_INPUT, IODINE_R_INPUT_DEFAULT);
939
- add_value_to_env(env_template_no_upgrade, "rack.errors", rb_stderr);
940
- add_value_to_env(env_template_no_upgrade, "rack.hijack?", Qtrue);
941
- add_value_to_env(env_template_no_upgrade, "rack.multiprocess", Qtrue);
942
- add_value_to_env(env_template_no_upgrade, "rack.multithread", Qtrue);
943
- add_value_to_env(env_template_no_upgrade, "rack.run_once", Qfalse);
907
+ rb_hash_aset(env_template, IODINE_R_INPUT, IODINE_R_INPUT_DEFAULT);
908
+ add_value_to_env(env_template, "rack.errors", rb_stderr);
909
+ add_value_to_env(env_template, "rack.hijack?", Qtrue);
910
+ add_value_to_env(env_template, "rack.multiprocess", Qtrue);
911
+ add_value_to_env(env_template, "rack.multithread", Qtrue);
912
+ add_value_to_env(env_template, "rack.run_once", Qfalse);
944
913
  /* default schema to http, it might be updated later */
945
- rb_hash_aset(env_template_no_upgrade, R_URL_SCHEME, HTTP_SCHEME);
914
+ rb_hash_aset(env_template, R_URL_SCHEME, HTTP_SCHEME);
946
915
  /* placeholders... minimize rehashing*/
947
- rb_hash_aset(env_template_no_upgrade, HTTP_VERSION, QUERY_STRING);
948
- rb_hash_aset(env_template_no_upgrade, IODINE_R_HIJACK, QUERY_STRING);
949
- rb_hash_aset(env_template_no_upgrade, PATH_INFO, QUERY_STRING);
950
- rb_hash_aset(env_template_no_upgrade, QUERY_STRING, QUERY_STRING);
951
- rb_hash_aset(env_template_no_upgrade, REMOTE_ADDR, QUERY_STRING);
952
- rb_hash_aset(env_template_no_upgrade, REQUEST_METHOD, QUERY_STRING);
953
- rb_hash_aset(env_template_no_upgrade, SERVER_NAME, QUERY_STRING);
954
- rb_hash_aset(env_template_no_upgrade, SERVER_PROTOCOL, QUERY_STRING);
955
- rb_hash_aset(env_template_no_upgrade, IODINE_REQUEST_ID, QUERY_STRING);
956
- rb_hash_aset(env_template_no_upgrade, IODINE_HAS_BODY, QUERY_STRING);
957
-
958
- /* WebSocket upgrade support */
959
- env_template_websockets = rb_hash_dup(env_template_no_upgrade);
960
- IodineStore.add(env_template_websockets);
961
- rb_hash_aset(env_template_websockets, RACK_UPGRADE_Q, RACK_UPGRADE_WEBSOCKET);
962
-
963
- /* SSE upgrade support */
964
- env_template_sse = rb_hash_dup(env_template_no_upgrade);
965
- IodineStore.add(env_template_sse);
966
- rb_hash_aset(env_template_sse, RACK_UPGRADE_Q, RACK_UPGRADE_SSE);
916
+ rb_hash_aset(env_template, HTTP_VERSION, QUERY_STRING);
917
+ rb_hash_aset(env_template, IODINE_R_HIJACK, QUERY_STRING);
918
+ rb_hash_aset(env_template, PATH_INFO, QUERY_STRING);
919
+ rb_hash_aset(env_template, QUERY_STRING, QUERY_STRING);
920
+ rb_hash_aset(env_template, REMOTE_ADDR, QUERY_STRING);
921
+ rb_hash_aset(env_template, REQUEST_METHOD, QUERY_STRING);
922
+ rb_hash_aset(env_template, SERVER_NAME, QUERY_STRING);
923
+ rb_hash_aset(env_template, SERVER_PROTOCOL, QUERY_STRING);
924
+ rb_hash_aset(env_template, IODINE_REQUEST_ID, QUERY_STRING);
925
+ rb_hash_aset(env_template, IODINE_HAS_BODY, QUERY_STRING);
967
926
 
968
927
  #undef add_value_to_env
969
928
  #undef add_str_to_env
@@ -1020,15 +979,15 @@ relevant to HTTP/1.x connections.
1020
979
  intptr_t iodine_http_listen(iodine_connection_args_s args){
1021
980
  // clang-format on
1022
981
  if (args.public.data) {
1023
- rb_hash_aset(env_template_no_upgrade, XSENDFILE_TYPE, XSENDFILE);
1024
- rb_hash_aset(env_template_no_upgrade, XSENDFILE_TYPE_HEADER, XSENDFILE);
982
+ rb_hash_aset(env_template, XSENDFILE_TYPE, XSENDFILE);
983
+ rb_hash_aset(env_template, XSENDFILE_TYPE_HEADER, XSENDFILE);
1025
984
  support_xsendfile = 1;
1026
985
  }
1027
986
  IodineStore.add(args.handler);
1028
987
  #ifdef __MINGW32__
1029
988
  intptr_t uuid = http_listen(
1030
989
  args.port.data, args.address.data, .on_request = on_rack_request,
1031
- .on_upgrade = on_rack_upgrade, .udata = (void *)args.handler,
990
+ .udata = (void *)args.handler,
1032
991
  .timeout = args.timeout, .ws_timeout = args.ping,
1033
992
  .ws_max_msg_size = args.max_msg, .max_header_size = args.max_headers,
1034
993
  .on_finish = free_iodine_http, .log = args.log, .max_clients = args.max_clients,
@@ -1036,7 +995,7 @@ intptr_t iodine_http_listen(iodine_connection_args_s args){
1036
995
  #else
1037
996
  intptr_t uuid = http_listen(
1038
997
  args.port.data, args.address.data, .on_request = on_rack_request,
1039
- .on_upgrade = on_rack_upgrade, .udata = (void *)args.handler,
998
+ .udata = (void *)args.handler,
1040
999
  .tls = args.tls, .timeout = args.timeout, .ws_timeout = args.ping,
1041
1000
  .ws_max_msg_size = args.max_msg, .max_header_size = args.max_headers,
1042
1001
  .on_finish = free_iodine_http, .log = args.log, .max_clients = args.max_clients,
@@ -1245,6 +1204,7 @@ void iodine_init_http(void) {
1245
1204
  fiber_result_var_id = rb_intern("@__result");
1246
1205
  http_wait_directive = ID2SYM(rb_intern("__http_defer__"));
1247
1206
  fiber_id_method_id = rb_intern("__get_id");
1207
+ iodine_env_var_id = rb_intern("@__iodine_env");
1248
1208
 
1249
1209
  IodineUTF8Encoding = rb_enc_find("UTF-8");
1250
1210
  IodineBinaryEncoding = rb_enc_find("binary");
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '4.4.0'.freeze
2
+ VERSION = '5.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rage-iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-11-28 00:00:00.000000000 Z
10
+ date: 2026-03-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake