rage-iodine 4.4.0 → 5.0.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: 658449c4bf690e24a8c0bd0b6b98f0fdaf848aa1cff34d59ea3091e423c81247
4
+ data.tar.gz: 0bfb9f771695d2132dfd7247908b38deb7c8e9122d3624da441c66db8b98a745
5
5
  SHA512:
6
- metadata.gz: e98de1cdf973e91d5b2401f112fdc9487625ba90e985399914cf4ce387040255e35c4073d80ad89e6337800777f2d5bc3b89d7909cb4dfdd582afc89d8071309
7
- data.tar.gz: b1e68feee5ba155887c7ea7ab9c372bacc3724a79c83849b19f20bdb701b7e4412a90ea90a5e7858566248dd0c01903c2f9e6f7e6272522f9e13e803c031dcfb
6
+ metadata.gz: 7921a4cc9de1d7234eae0423ad1f0b51b1f953ae4b01b8495f837be05603a12f3889ff06f463a2622bdd841997be585fbb6b611fdac0a7592eec7179ae3064bb
7
+ data.tar.gz: 7eea1914ceda33dc67be0efebd5007222a604f92b1d4f9f5a884627f43c9978bc67585de34357070485807bec144106110952d74773c3789dc362dbc3d6244f2
@@ -13,6 +13,47 @@ Internal Request / Response Handlers
13
13
  ***************************************************************************** */
14
14
 
15
15
  static uint64_t http_upgrade_hash = 0;
16
+
17
+ static inline uint8_t http_accept_item_is_sse(char *item, size_t len) {
18
+ while (len && (*item == ' ' || *item == '\t')) {
19
+ ++item;
20
+ --len;
21
+ }
22
+ while (len && (item[len - 1] == ' ' || item[len - 1] == '\t')) {
23
+ --len;
24
+ }
25
+ return (len == 17 && !strncasecmp(item, "text/event-stream", 17));
26
+ }
27
+
28
+ static inline uint8_t http_accepts_sse(FIOBJ value) {
29
+ if (!value)
30
+ return 0;
31
+ if (FIOBJ_TYPE_IS(value, FIOBJ_T_ARRAY)) {
32
+ for (size_t i = 0; i < fiobj_ary_count(value); ++i) {
33
+ if (http_accepts_sse(fiobj_ary_index(value, i)))
34
+ return 1;
35
+ }
36
+ return 0;
37
+ }
38
+ fio_str_info_s accept = fiobj_obj2cstr(value);
39
+ if (!accept.data || !accept.len)
40
+ return 0;
41
+
42
+ size_t i = 0;
43
+ while (i < accept.len) {
44
+ size_t start = i;
45
+ while (i < accept.len && accept.data[i] != ';' && accept.data[i] != ',')
46
+ ++i;
47
+ if (http_accept_item_is_sse(accept.data + start, i - start))
48
+ return 1;
49
+ while (i < accept.len && accept.data[i] != ',')
50
+ ++i;
51
+ if (i < accept.len)
52
+ ++i;
53
+ }
54
+ return 0;
55
+ }
56
+
16
57
  /** Use this function to handle HTTP requests.*/
17
58
  void http_on_request_handler______internal(http_s *h,
18
59
  http_settings_s *settings) {
@@ -38,9 +79,8 @@ void http_on_request_handler______internal(http_s *h,
38
79
  if (t)
39
80
  goto upgrade;
40
81
 
41
- if (fiobj_iseq(
42
- fiobj_hash_get2(h->headers, fiobj_obj2hash(HTTP_HEADER_ACCEPT)),
43
- HTTP_HVALUE_SSE_MIME))
82
+ if (http_accepts_sse(
83
+ fiobj_hash_get2(h->headers, fiobj_obj2hash(HTTP_HEADER_ACCEPT))))
44
84
  goto eventsource;
45
85
  if (settings->public_folder &&
46
86
  (fiobj_obj2cstr(h->method).len != 4 || strncasecmp("post", fiobj_obj2cstr(h->method).data, 4))) {
@@ -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,6 +62,8 @@ 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;
66
+ static ID iodine_upgrade_var_id;
65
67
 
66
68
  static VALUE env_template_no_upgrade;
67
69
  static VALUE env_template_websockets;
@@ -681,6 +683,8 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
681
683
 
682
684
  if (handle->type == IODINE_HTTP_DEFERRED) {
683
685
  rbresponse = rb_ivar_get((VALUE)h->fiber, fiber_result_var_id);
686
+ env = rb_ivar_get((VALUE)h->fiber, iodine_env_var_id);
687
+ handle->upgrade = FIX2INT(rb_ivar_get((VALUE)h->fiber, iodine_upgrade_var_id));
684
688
  } else {
685
689
  // create / register env variable
686
690
  env = copy2env(handle);
@@ -698,7 +702,10 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
698
702
  tmp = rb_ary_entry(rbresponse, 0);
699
703
  // rack will return `[:__http_defer__, fiber_to_wait_on]` in case the request needs to be paused
700
704
  if (TYPE(tmp) == T_SYMBOL && tmp == http_wait_directive) {
701
- h->fiber = (void *)IodineStore.add(rb_ary_entry(rbresponse, 1));
705
+ VALUE fiber = rb_ary_entry(rbresponse, 1);
706
+ rb_ivar_set(fiber, iodine_env_var_id, env);
707
+ rb_ivar_set(fiber, iodine_upgrade_var_id, INT2FIX(handle->upgrade));
708
+ h->fiber = (void *)IodineStore.add(fiber);
702
709
  goto defer;
703
710
  }
704
711
 
@@ -741,8 +748,7 @@ static inline void *iodine_handle_request_in_GVL(void *handle_) {
741
748
  // review each header and write it to the response.
742
749
  rb_hash_foreach(response_headers, for_each_header_data, (VALUE)(h));
743
750
  // review for upgrade.
744
- if (handle->type != IODINE_HTTP_DEFERRED && (intptr_t)h->status < 300 &&
745
- ruby2c_review_upgrade(handle, rbresponse, env))
751
+ if ((intptr_t)h->status < 300 && ruby2c_review_upgrade(handle, rbresponse, env))
746
752
  goto external_done;
747
753
  // send the request body.
748
754
  if (ruby2c_response_send(handle, rbresponse, env))
@@ -882,7 +888,12 @@ static void on_rack_upgrade(http_s *h, char *proto, size_t len) {
882
888
  // return;
883
889
  // }
884
890
  IodineCaller.enterGVL(iodine_handle_request_in_GVL, &handle);
885
- iodine_perform_handle_action(handle);
891
+
892
+ if (handle.type == IODINE_HTTP_WAIT) {
893
+ http_pause(handle.h, http_pause_request_handler);
894
+ } else {
895
+ iodine_perform_handle_action(handle);
896
+ }
886
897
  (void)proto;
887
898
  (void)len;
888
899
  }
@@ -1245,6 +1256,8 @@ void iodine_init_http(void) {
1245
1256
  fiber_result_var_id = rb_intern("@__result");
1246
1257
  http_wait_directive = ID2SYM(rb_intern("__http_defer__"));
1247
1258
  fiber_id_method_id = rb_intern("__get_id");
1259
+ iodine_env_var_id = rb_intern("@__iodine_env");
1260
+ iodine_upgrade_var_id = rb_intern("@__iodine_upgrade");
1248
1261
 
1249
1262
  IodineUTF8Encoding = rb_enc_find("UTF-8");
1250
1263
  IodineBinaryEncoding = rb_enc_find("binary");
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '4.4.0'.freeze
2
+ VERSION = '5.0.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.0.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-02-25 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake