iodine 0.8.5 → 0.8.6

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: a93e062310eea6dc1375a7b4ae65879f2650830e861b249c5b9e594f93c5cc2e
4
- data.tar.gz: 60f6946949c76161446694fbb2e501a1ed14c00f0eb57ad856164145103059e8
3
+ metadata.gz: a78e5e3d245628f5435cee4464e5d3cda671089abd62fb77d3774ef2c2f96f85
4
+ data.tar.gz: f7f6be135b098c5a83dd8d2b0991a2bb379cb26db33314984bdca2c8a343739d
5
5
  SHA512:
6
- metadata.gz: 5bcf4e2802b3776e3db522c4f8af42510fe8db84e85afaea1e3e3984c9902bf6adbaa52b87016e0fba7d7daf7c7474b2237fda2731afdd2cd0e35057c94e9fae
7
- data.tar.gz: f5add513aa84de7938426065a967a5251c93b28018514e54d4b4108e86698da90a901a8a24ad30431f83cc397964840aeef5a94719c082f0057d7fc2023524a1
6
+ metadata.gz: 3e364ad32ead143b4f809bcd8c4a86d3bb30cce41d642d91a7212d46bb36bd752c08ce0328333cbd2acd15ec0771b08b66aa8b163b09898363872a6cfa0188cb
7
+ data.tar.gz: 2d994564dcef4a132011da2ce1f7d1ba1d6eccad17c66321409decfccb88872d8684c38bccba580c771f095d89ff35de4ba9a1d4a9b79c15c06207f0696bd659
data/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@ Please refer to the current gem version to review the relevant changes for your
7
7
 
8
8
  ## Changes
9
9
 
10
+ #### 0.8.6 - 2026-11-10
11
+
12
+ **Fix**: `rack.input#rewind` moves to the start of the body and `rack.input#seek` with no argument returns the current position (both moved to the end of the body since 0.8.3, leaving Rails with empty JSON and form bodies). Credit to Nazarenko Viktor (@vnazarenko) for PR #173.
13
+
14
+ **Fix**: the Rack env sets `CONTENT_LENGTH` (not `HTTP_CONTENT_LENGTH`), so `ActionDispatch::Request#raw_post` reads JSON bodies. Credit to Nazarenko Viktor (@vnazarenko) for PR #174.
15
+
16
+ **Fix**: the exposed exception log message no longer has a format specifier without a matching argument, which read garbage from the stack.
17
+
10
18
  #### 0.8.5 - 2026-11-07
11
19
 
12
20
  **Feature**: (`crypto`) `Iodine::Base::Crypto::P256` and `Iodine::Base::Crypto::P384` provide ECDSA signatures (ES256 / ES384: `keypair`, `public_key`, `sign`, `verify`) with OpenSSL compatible encodings (uncompressed SEC 1 public keys, DER signatures).
@@ -50,7 +50,7 @@ static void *iodine_handle_exception(void *ignr) {
50
50
  (int)RSTRING_LEN(msg),
51
51
  RSTRING_PTR(msg));
52
52
  } else {
53
- FIO_LOG_ERROR("exposed exception message: %.*s: %.*s\n %s\n"
53
+ FIO_LOG_ERROR("exposed exception message: %.*s: %.*s\n"
54
54
  "BACKTRACE UNAVAILABLE!\n",
55
55
  (int)RSTRING_LEN(exc_class),
56
56
  RSTRING_PTR(exc_class),
@@ -51,7 +51,8 @@ This module is the heart of Iodine's connection handling. It manages:
51
51
  - `length` - Body length in bytes
52
52
  - `read([maxlen], [out_string])` - Read body data
53
53
  - `gets([limit])` - Read line from body
54
- - `seek(pos)` / `rewind` - Seek in body
54
+ - `seek([pos])` - Seek in body (no argument returns the current position)
55
+ - `rewind` - Move back to the start of the body
55
56
  - `close_body` - Release body resources (frees buffer / temporary file)
56
57
 
57
58
  ### Network Information
@@ -840,10 +841,20 @@ FIO_SFUNC VALUE iodine_connection_body_seek(int argc, VALUE *argv, VALUE o) {
840
841
  return Qnil;
841
842
  int64_t pos = SSIZE_MAX;
842
843
  iodine_rb2c_arg(argc, argv, IODINE_ARG_NUM(pos, 0, "pos", 0));
844
+ if (pos == SSIZE_MAX) /* no position given: report the current one */
845
+ return ULL2NUM(fio_http_body_pos(c->http));
843
846
  pos = (long long)fio_http_body_seek(c->http, (ssize_t)pos);
844
847
  return ULL2NUM(pos);
845
848
  }
846
849
 
850
+ /* Rack `rack.input#rewind`: moves the read position back to the start. */
851
+ FIO_SFUNC VALUE iodine_connection_body_rewind(VALUE o) {
852
+ iodine_connection_s *c = iodine_connection_ptr(o);
853
+ if (!c->http)
854
+ return Qnil;
855
+ return ULL2NUM(fio_http_body_seek(c->http, 0));
856
+ }
857
+
847
858
  FIO_SFUNC VALUE iodine_connection_body_close(VALUE o) {
848
859
  VALUE r = Qtrue;
849
860
  iodine_connection_s *c = iodine_connection_ptr(o);
@@ -3540,7 +3551,7 @@ static void Init_Iodine_Connection(void) {
3540
3551
  val = STORE.frozen_str(FIO_STR_INFO1((char *)str)); \
3541
3552
  STORE.hold(val)
3542
3553
 
3543
- IODINE_RACK_CONTENT_LENGTH = STORE.header_name(FIO_STR_INFO1((char *)"CONTENT_LENGTH"));
3554
+ IODINE_RACK_CONTENT_LENGTH = STORE.header_name(FIO_STR_INFO1((char *)"content-length"));
3544
3555
  STORE.hold(IODINE_RACK_CONTENT_LENGTH);
3545
3556
 
3546
3557
  IODINE_CONST_RACK_STORE(IODINE_RACK_INPUT, "rack.input");
@@ -3598,7 +3609,7 @@ static void Init_Iodine_Connection(void) {
3598
3609
  rb_define_method(m, "gets", iodine_connection_body_gets, -1);
3599
3610
  rb_define_method(m, "read", iodine_connection_body_read, -1);
3600
3611
  rb_define_method(m, "seek", iodine_connection_body_seek, -1);
3601
- rb_define_method(m, "rewind", iodine_connection_body_seek, -1);
3612
+ rb_define_method(m, "rewind", iodine_connection_body_rewind, 0);
3602
3613
  rb_define_method(m, "close_body", iodine_connection_body_close, 0);
3603
3614
 
3604
3615
  rb_define_method(m, "open?", iodine_connection_is_open, 0);
@@ -76,8 +76,8 @@ static _Bool iodinde_hmap_object_cmp(VALUE a, VALUE b) {
76
76
  * used during key duplication to prevent GC issues.
77
77
  */
78
78
  typedef struct {
79
- iodine_hmap_s map; /**< The underlying facil.io hash map */
80
- VALUE tmp; /**< Temporary holder during key operations */
79
+ iodine_hmap_s map; /**< The underlying facil.io hash map */
80
+ VALUE tmp; /**< Temporary holder during key operations */
81
81
  } iodine_minimap_s;
82
82
 
83
83
  static int iodine_minimap_gc_mark_task(iodine_hmap_each_s *e) {
@@ -428,11 +428,11 @@ static VALUE iodine_minimap_benchmark_c(VALUE klass, VALUE object_count) {
428
428
  insert = fio_time_micro() - start; \
429
429
  if (klass##_count(&m) != OBJECTS) \
430
430
  FIO_LOG_ERROR("map counter error (%zu != %zu)!", \
431
- klass##_count(&m), \
431
+ (size_t)klass##_count(&m), \
432
432
  OBJECTS); \
433
433
  if (klass##_capa(&m) < OBJECTS) \
434
434
  FIO_LOG_ERROR("map capacity error (%zu < %zu)!", \
435
- klass##_capa(&m), \
435
+ (size_t)klass##_capa(&m), \
436
436
  OBJECTS); \
437
437
  start = fio_time_micro(); \
438
438
  for (size_t j = 0; j < CYCLES; ++j) { \
@@ -442,11 +442,11 @@ static VALUE iodine_minimap_benchmark_c(VALUE klass, VALUE object_count) {
442
442
  overwrite = fio_time_micro() - start; \
443
443
  if (klass##_count(&m) != OBJECTS) \
444
444
  FIO_LOG_ERROR("map counter error (%zu != %zu)!", \
445
- klass##_count(&m), \
445
+ (size_t)klass##_count(&m), \
446
446
  OBJECTS); \
447
447
  if (klass##_capa(&m) < OBJECTS) \
448
448
  FIO_LOG_ERROR("map capacity error (%zu < %zu)!", \
449
- klass##_capa(&m), \
449
+ (size_t)klass##_capa(&m), \
450
450
  OBJECTS); \
451
451
  start = fio_time_micro(); \
452
452
  for (size_t sc = 0; sc < FIND_CYCLES; ++sc) \
@@ -454,8 +454,8 @@ static VALUE iodine_minimap_benchmark_c(VALUE klass, VALUE object_count) {
454
454
  if (klass##_get(&m, numbers[i]) != numbers[i]) \
455
455
  FIO_LOG_ERROR(FIO_MACRO2STR(klass) "_get error ([%zu] %zu != %zu)!", \
456
456
  i, \
457
- numbers[i], \
458
- klass##_get(&m, i)); \
457
+ (size_t)numbers[i], \
458
+ (size_t)klass##_get(&m, i)); \
459
459
  } \
460
460
  find = fio_time_micro() - start; \
461
461
  start = fio_time_micro(); \
@@ -466,8 +466,8 @@ static VALUE iodine_minimap_benchmark_c(VALUE klass, VALUE object_count) {
466
466
  FIO_MACRO2STR(klass) "_get error" \
467
467
  "([%zu] %zu shouldn't exist but == %zu)!", \
468
468
  i, \
469
- numbers[i], \
470
- klass##_get(&m, numbers[i])); \
469
+ (size_t)numbers[i], \
470
+ (size_t)klass##_get(&m, numbers[i])); \
471
471
  } \
472
472
  find_missing = fio_time_micro() - start; \
473
473
  start = fio_time_micro(); \
@@ -484,11 +484,11 @@ static VALUE iodine_minimap_benchmark_c(VALUE klass, VALUE object_count) {
484
484
  FIO_MACRO2STR(klass), \
485
485
  (size_t)klass##_count(&m), \
486
486
  (size_t)klass##_capa(&m), \
487
- insert, \
488
- overwrite, \
489
- find, \
490
- find_missing, \
491
- loop); \
487
+ (size_t)insert, \
488
+ (size_t)overwrite, \
489
+ (size_t)find, \
490
+ (size_t)find_missing, \
491
+ (size_t)loop); \
492
492
  klass##_destroy(&m); \
493
493
  } while (0);
494
494
  for (size_t tst = 0; tst < TESTS; ++tst) {
@@ -1887,6 +1887,11 @@ module Iodine
1887
1887
  # @return [Integer] the current position
1888
1888
  def seek(pos = nil); end
1889
1889
 
1890
+ # (HTTP Only) Moves the body's read position back to the start, so `rack.input` can be read again.
1891
+ #
1892
+ # @return [Integer] the new position (always `0`)
1893
+ def rewind; end
1894
+
1890
1895
  # (HTTP Only) Releases the body's resources, freeing the in-memory buffer and closing any temporary file.
1891
1896
  #
1892
1897
  # Subsequent body reads will return `nil` and `length` will return `0`. The connection itself remains open.
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Iodine
4
4
  # The Iodine gem version number
5
- VERSION = "0.8.5"
5
+ VERSION = "0.8.6"
6
6
  # NeoRack supported extensions.
7
7
  def self.extensions
8
8
  return (@extensions ||= { iodine: (VERSION.split(?.).map() {|i| i.to_i.to_s == i ? i.to_i : i }),
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5
4
+ version: 0.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
@@ -134,7 +134,7 @@ metadata:
134
134
  homepage_uri: https://github.com/boazsegev/iodine
135
135
  source_code_uri: https://github.com/boazsegev/iodine
136
136
  changelog_uri: https://github.com/boazsegev/iodine/blob/master/CHANGELOG.md
137
- post_install_message: Thank you for installing Iodine 0.8.5.
137
+ post_install_message: Thank you for installing Iodine 0.8.6.
138
138
  rdoc_options: []
139
139
  require_paths:
140
140
  - lib