rage-iodine 3.2.0 → 4.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: 7e0cf25032c21b2f527b8692bfead0da142cecc0bc625eea36da5a45046978ef
4
- data.tar.gz: 512d45f660c336e8b33dd237fce1eec816828039a4139b71c505b318ecf37ef6
3
+ metadata.gz: 26936e113c659cee25877d312515e6fe50ca5ed56ff5e8195e6f5274292f2145
4
+ data.tar.gz: 40b7aa9c791a5bc08513e5e0c478c02274a39c81d9be0fab7736f8478157ffab
5
5
  SHA512:
6
- metadata.gz: 82b018d7b9d1b7a3ce6facec12f22e27b1a3699a093571240ccaa95f98985cbf89a88a68821354eb5f5c3deb268f177c990afd2d396c6d776902dbafbcff96c9
7
- data.tar.gz: 60a58204b498adc19204793c6366168732718393fa8d3cdd49788bc94ae2d6c2a972d912ed51a22b16e24e48850fe05d11cdfb6c5d0839340b7533719267cc3d
6
+ metadata.gz: 1a789b92abed8d78b010ace73cb41d1688ff50c4fc6b590b6705a717196c212721039e252461ba8834a8f0bcd43679fc9c611a9f4d4690a826f3ac212bb3b9e5
7
+ data.tar.gz: 446a4ecf05a3b371266ea71a92cb514d9a510d2c0fb6dc72e212ff26253e60c343bfc1675a68e6f3c9985c267b9940e61492706f4e61d89e6cb73dbba6c05a2c
data/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@ Please notice that this change log contains changes for upcoming releases as wel
6
6
 
7
7
  ## Changes:
8
8
 
9
+ #### Change log v.4.0.0 (2024-09-11)
10
+
11
+ **Update**: Stop disconnecting from the DB on fork.
12
+
13
+ **Update**: Fiber Scheduler updates to correctly close file descriptors.
14
+
15
+ #### Change log v.3.3.0 (2024-08-18)
16
+
17
+ **Update**: Improvements and fixes for the static file service.
18
+
9
19
  #### Change log v.3.2.0 (2024-07-15)
10
20
 
11
21
  **Update**: Explicitly undefine the alloc function on IodineObjectStorage.
data/ext/iodine/fio.c CHANGED
@@ -363,6 +363,8 @@ typedef struct {
363
363
  uint8_t open;
364
364
  /** indicated that the connection should be closed. */
365
365
  uint8_t close;
366
+ /** indicates whether the fd is coming from the Fiber Scheduler. */
367
+ uint8_t internal;
366
368
  /** peer address length */
367
369
  uint8_t addr_len;
368
370
  /** peer address */
@@ -2075,7 +2077,7 @@ static size_t fio_poll(void) {
2075
2077
  epoll_wait(internal[j].data.fd, events, FIO_POLL_MAX_EVENTS, 0);
2076
2078
  if (active_count > 0) {
2077
2079
  for (int i = 0; i < active_count; i++) {
2078
- if (events[i].events & (~(EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLRDHUP))) {
2080
+ if (events[i].events & (~(EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLRDHUP | EPOLLERR))) {
2079
2081
  // errors are hendled as disconnections (on_close)
2080
2082
  fio_force_close_in_poll(fd2uuid(events[i].data.fd));
2081
2083
  } else {
@@ -2088,9 +2090,12 @@ static size_t fio_poll(void) {
2088
2090
  fio_defer_push_task(deferred_on_data,
2089
2091
  (void *)fd2uuid(events[i].data.fd), NULL);
2090
2092
  }
2091
- if (events[i].events & (EPOLLHUP | EPOLLRDHUP)) {
2092
- fio_defer_push_task(deferred_force_close_in_poll,
2093
- (void *)fd2uuid(events[i].data.fd), NULL);
2093
+ if (events[i].events & (EPOLLHUP | EPOLLRDHUP | EPOLLERR)) {
2094
+ if(fd_data(events[i].data.fd).internal) {
2095
+ fio_force_close_in_poll(fd2uuid(events[i].data.fd));
2096
+ } else {
2097
+ fio_clear_fd((intptr_t)events[i].data.fd, 0);
2098
+ }
2094
2099
  }
2095
2100
  }
2096
2101
  } // end for loop
@@ -2226,8 +2231,11 @@ static size_t fio_poll(void) {
2226
2231
  NULL);
2227
2232
  }
2228
2233
  if (events[i].flags & (EV_EOF | EV_ERROR)) {
2229
- fio_defer_push_task(deferred_force_close_in_poll,
2230
- (void *)fd2uuid(events[i].udata), NULL);
2234
+ if(fd_data(events[i].udata).internal) {
2235
+ fio_force_close_in_poll(fd2uuid(events[i].udata));
2236
+ } else {
2237
+ fio_clear_fd((intptr_t)events[i].udata, 0);
2238
+ }
2231
2239
  }
2232
2240
  }
2233
2241
  } else if (active_count < 0) {
@@ -4033,6 +4041,7 @@ static int fio_attach__internal(void *uuid_, void *protocol_) {
4033
4041
  }
4034
4042
  fio_protocol_s *old_pr = uuid_data(uuid).protocol;
4035
4043
  uuid_data(uuid).open = 1;
4044
+ uuid_data(uuid).internal = 1;
4036
4045
  uuid_data(uuid).protocol = protocol;
4037
4046
  touchfd(fio_uuid2fd(uuid));
4038
4047
  fio_unlock(&uuid_data(uuid).protocol_lock);
@@ -4093,6 +4102,7 @@ static int fio_watch__internal(void *uuid_, void *protocol_) {
4093
4102
 
4094
4103
  fio_protocol_s *old_pr = uuid_data(uuid).protocol;
4095
4104
  uuid_data(uuid).open = 1;
4105
+ uuid_data(uuid).internal = 0;
4096
4106
  uuid_data(uuid).protocol = protocol;
4097
4107
  touchfd(fio_uuid2fd(uuid));
4098
4108
  fio_unlock(&uuid_data(uuid).protocol_lock);
data/ext/iodine/http.c CHANGED
@@ -460,23 +460,16 @@ no_gzip_support:
460
460
  !(S_ISREG(file_data.st_mode) || S_ISLNK(file_data.st_mode)))
461
461
  return -1;
462
462
  found_file:
463
- /* set last-modified */
464
- {
465
- FIOBJ tmp = fiobj_str_buf(32);
466
- fiobj_str_resize(
467
- tmp, http_time2str(fiobj_obj2cstr(tmp).data, file_data.st_mtime));
468
- http_set_header(h, HTTP_HEADER_LAST_MODIFIED, tmp);
469
- }
470
463
  /* set cache-control */
471
464
  http_set_header(h, HTTP_HEADER_CACHE_CONTROL, fiobj_dup(HTTP_HVALUE_MAX_AGE));
465
+ /* set last-modified */
466
+ FIOBJ last_modified_str = fiobj_str_buf(32);
467
+ fiobj_str_resize(
468
+ last_modified_str, http_time2str(fiobj_obj2cstr(last_modified_str).data, file_data.st_mtime));
469
+ http_set_header(h, HTTP_HEADER_LAST_MODIFIED, last_modified_str);
472
470
  /* set & test etag */
473
- uint64_t etag = (uint64_t)file_data.st_size;
474
- etag ^= (uint64_t)file_data.st_mtime;
475
- etag = fiobj_hash_string(&etag, sizeof(uint64_t));
476
- FIOBJ etag_str = fiobj_str_buf(32);
477
- fiobj_str_resize(etag_str,
478
- fio_base64_encode(fiobj_obj2cstr(etag_str).data,
479
- (void *)&etag, sizeof(uint64_t)));
471
+ FIOBJ etag_str = fiobj_str_buf(1);
472
+ fiobj_str_printf(etag_str, "%lx-%llx", file_data.st_mtime, file_data.st_size);
480
473
  /* set */
481
474
  http_set_header(h, HTTP_HEADER_ETAG, etag_str);
482
475
  /* test */
@@ -499,7 +492,7 @@ found_file:
499
492
  if (!ifrange_hash)
500
493
  ifrange_hash = fiobj_hash_string("if-range", 8);
501
494
  FIOBJ tmp = fiobj_hash_get2(h->headers, ifrange_hash);
502
- if (tmp && fiobj_iseq(tmp, etag_str)) {
495
+ if (tmp && !(fiobj_iseq(tmp, etag_str) || fiobj_iseq(tmp, last_modified_str))) {
503
496
  fiobj_hash_delete2(h->headers, range_hash);
504
497
  } else {
505
498
  tmp = fiobj_hash_get2(h->headers, range_hash);
@@ -513,26 +506,30 @@ found_file:
513
506
  char *pos = range.data + 6;
514
507
  int64_t start_at = 0, end_at = 0;
515
508
  start_at = fio_atol(&pos);
516
- if (start_at >= file_data.st_size)
517
- goto open_file;
518
509
  if (start_at >= 0) {
519
510
  pos++;
520
511
  end_at = fio_atol(&pos);
521
- if (end_at <= 0)
522
- goto open_file;
523
512
  }
524
513
  /* we ignore multimple ranges, only responding with the first range. */
525
- if (start_at < 0) {
526
- if (0 - start_at < file_data.st_size) {
527
- offset = file_data.st_size - start_at;
528
- length = 0 - start_at;
529
- }
530
- } else if (end_at) {
514
+ if (end_at) {
515
+ /* "Range bytes=100-200": bytes between `start_at` and `end_at` are requested */
516
+ if (start_at < 0 || end_at <= start_at || end_at >= length)
517
+ goto invalid_range;
518
+
531
519
  offset = start_at;
532
520
  length = end_at - start_at + 1;
533
- if (length + start_at > file_data.st_size || length <= 0)
534
- length = length - start_at;
521
+ } else if (start_at < 0) {
522
+ /* "Range bytes=-100": the last `start_at` bytes are requested */
523
+ if (0 - start_at >= length)
524
+ goto invalid_range;
525
+
526
+ offset = file_data.st_size + start_at;
527
+ length = 0 - start_at;
535
528
  } else {
529
+ /* "Range bytes=100-": all bytes starting at `start_at` are requested */
530
+ if (start_at >= length)
531
+ goto invalid_range;
532
+
536
533
  offset = start_at;
537
534
  length = length - start_at;
538
535
  }
@@ -612,6 +609,14 @@ open_file:
612
609
  }
613
610
  http_sendfile(h, file, length, offset);
614
611
  return 0;
612
+ invalid_range:
613
+ {
614
+ FIOBJ crange = fiobj_str_buf(1);
615
+ fiobj_str_printf(crange, "bytes */%lu", (unsigned long)file_data.st_size);
616
+ http_set_header(h, HTTP_HEADER_CONTENT_RANGE, crange);
617
+ http_send_error(h, 416);
618
+ return 0;
619
+ }
615
620
  }
616
621
 
617
622
  /**
@@ -15,7 +15,8 @@
15
15
  static ID call_id;
16
16
  static uint8_t ATTACH_ON_READ_READY_CALLBACK;
17
17
  static uint8_t ATTACH_ON_WRITE_READY_CALLBACK;
18
- static VALUE timeout_args[1];
18
+ static VALUE e_timeout_args[1];
19
+ static VALUE e_closed_args[1];
19
20
 
20
21
  /* *****************************************************************************
21
22
  Fiber Scheduler API
@@ -36,6 +37,10 @@ typedef struct {
36
37
  static void iodine_scheduler_task_close(intptr_t uuid, fio_protocol_s *fio_protocol) {
37
38
  scheduler_protocol_s *protocol = (scheduler_protocol_s *)fio_protocol;
38
39
 
40
+ if (!protocol->fulfilled) {
41
+ IodineCaller.call2(protocol->block, call_id, 1, e_closed_args);
42
+ }
43
+
39
44
  IodineStore.remove(protocol->block);
40
45
  fio_free(protocol);
41
46
 
@@ -57,7 +62,7 @@ static void iodine_scheduler_task_timeout(intptr_t uuid, fio_protocol_s *fio_pro
57
62
  scheduler_protocol_s *protocol = (scheduler_protocol_s *)fio_protocol;
58
63
 
59
64
  if (!protocol->fulfilled) {
60
- IodineCaller.call2(protocol->block, call_id, 1, timeout_args);
65
+ IodineCaller.call2(protocol->block, call_id, 1, e_timeout_args);
61
66
  protocol->fulfilled = 1;
62
67
  }
63
68
  }
@@ -178,7 +183,8 @@ Scheduler initialization
178
183
 
179
184
  void iodine_scheduler_initialize(void) {
180
185
  call_id = rb_intern2("call", 4);
181
- timeout_args[0] = UINT2NUM(ETIMEDOUT);
186
+ e_timeout_args[0] = INT2NUM(-ETIMEDOUT);
187
+ e_closed_args[0] = INT2NUM(-EIO);
182
188
 
183
189
  VALUE SchedulerModule = rb_define_module_under(IodineModule, "Scheduler");
184
190
 
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '3.2.0'.freeze
2
+ VERSION = '4.0.0'.freeze
3
3
  end
data/lib/iodine.rb CHANGED
@@ -156,12 +156,6 @@ require 'rack/handler/iodine' unless defined? ::Iodine::Rack::IODINE_RACK_LOADED
156
156
 
157
157
  ### Automatic ActiveRecord and Sequel support for forking (preventing connection sharing)
158
158
  Iodine.on_state(:before_fork) do
159
- if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:connection)
160
- begin
161
- ActiveRecord::Base.connection.disconnect!
162
- rescue
163
- end
164
- end
165
159
  if defined?(Sequel)
166
160
  begin
167
161
  Sequel::DATABASES.each { |database| database.disconnect }
@@ -169,14 +163,6 @@ Iodine.on_state(:before_fork) do
169
163
  end
170
164
  end
171
165
  end
172
- Iodine.on_state(:after_fork) do
173
- if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:establish_connection)
174
- begin
175
- ActiveRecord::Base.establish_connection
176
- rescue
177
- end
178
- end
179
- end
180
166
 
181
167
  ### Parse CLI for default HTTP settings
182
168
  Iodine::Base::CLI.parse if defined?(IODINE_PARSE_CLI) && IODINE_PARSE_CLI
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rage-iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-15 00:00:00.000000000 Z
11
+ date: 2024-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -274,7 +274,7 @@ requirements:
274
274
  - Ruby >= 2.5.0 recommended.
275
275
  - TLS requires OpenSSL >= 1.1.0.
276
276
  - Or Windows with Ruby >= 3.0.0 build with MingW and MingW as compiler.
277
- rubygems_version: 3.5.9
277
+ rubygems_version: 3.4.10
278
278
  signing_key:
279
279
  specification_version: 4
280
280
  summary: iodine - a fast HTTP / Websocket Server with Pub/Sub support, optimized for