rage-iodine 3.2.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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