iodine 0.7.57 → 0.7.59
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +17 -17
- data/SECURITY.md +32 -0
- data/ext/iodine/fio.c +1 -1
- data/ext/iodine/fio.h +12 -14
- data/ext/iodine/fio_json_parser.h +5 -4
- data/ext/iodine/fio_tls_openssl.c +140 -90
- data/ext/iodine/fiobj_data.c +13 -11
- data/ext/iodine/fiobj_str.h +1 -1
- data/ext/iodine/fiobject.h +5 -4
- data/ext/iodine/http1.c +92 -7
- data/ext/iodine/http1_parser.h +164 -1121
- data/ext/iodine/iodine_caller.c +25 -13
- data/ext/iodine/iodine_store.c +23 -19
- data/ext/iodine/websockets.c +7 -16
- data/lib/iodine/version.rb +1 -1
- data/lib/iodine.rb +4 -0
- metadata +5 -6
data/ext/iodine/iodine_caller.c
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
static pthread_key_t iodine_GVL_state_key;
|
|
11
11
|
static pthread_once_t iodine_GVL_state_once = PTHREAD_ONCE_INIT;
|
|
12
12
|
static void init_iodine_GVL_state_key(void) {
|
|
13
|
-
pthread_key_create(&iodine_GVL_state_key, NULL);
|
|
13
|
+
pthread_key_create(&iodine_GVL_state_key, NULL);
|
|
14
14
|
}
|
|
15
15
|
static void init_iodine_GVL_state_init(void) {
|
|
16
16
|
uint8_t *gvl = malloc(sizeof(uint8_t));
|
|
@@ -47,14 +47,18 @@ static void *iodine_handle_exception(void *ignr) {
|
|
|
47
47
|
if (TYPE(bt) == T_ARRAY) {
|
|
48
48
|
bt = rb_ary_join(bt, rb_str_new_literal("\n"));
|
|
49
49
|
FIO_LOG_ERROR("Iodine caught an unprotected exception - %.*s: %.*s\n%s",
|
|
50
|
-
(int)RSTRING_LEN(exc_class),
|
|
51
|
-
|
|
50
|
+
(int)RSTRING_LEN(exc_class),
|
|
51
|
+
RSTRING_PTR(exc_class),
|
|
52
|
+
(int)RSTRING_LEN(msg),
|
|
53
|
+
RSTRING_PTR(msg),
|
|
52
54
|
StringValueCStr(bt));
|
|
53
55
|
} else {
|
|
54
56
|
FIO_LOG_ERROR("Iodine caught an unprotected exception - %.*s: %.*s\n"
|
|
55
57
|
"No backtrace available.\n",
|
|
56
|
-
(int)RSTRING_LEN(exc_class),
|
|
57
|
-
(
|
|
58
|
+
(int)RSTRING_LEN(exc_class),
|
|
59
|
+
RSTRING_PTR(exc_class),
|
|
60
|
+
(int)RSTRING_LEN(msg),
|
|
61
|
+
RSTRING_PTR(msg));
|
|
58
62
|
}
|
|
59
63
|
rb_backtrace();
|
|
60
64
|
FIO_LOG_ERROR("\n");
|
|
@@ -69,8 +73,12 @@ static void *iodine_handle_exception(void *ignr) {
|
|
|
69
73
|
/* calls the Ruby each method within the protection block */
|
|
70
74
|
static VALUE iodine_ruby_caller_perform_block(VALUE tsk_) {
|
|
71
75
|
iodine_rb_task_s *task = (void *)tsk_;
|
|
72
|
-
return rb_block_call(task->obj,
|
|
73
|
-
task->
|
|
76
|
+
return rb_block_call(task->obj,
|
|
77
|
+
task->method,
|
|
78
|
+
task->argc,
|
|
79
|
+
task->argv,
|
|
80
|
+
(rb_block_call_func_t)(task->each_func),
|
|
81
|
+
task->each_udata);
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
/* calls the Ruby method within the protection block */
|
|
@@ -83,7 +91,8 @@ static VALUE iodine_ruby_caller_perform(VALUE tsk_) {
|
|
|
83
91
|
static void *iodine_protect_ruby_call(void *task_) {
|
|
84
92
|
int state = 0;
|
|
85
93
|
VALUE ret = rb_protect(((iodine_rb_task_s *)task_)->protected_task,
|
|
86
|
-
(VALUE)(task_),
|
|
94
|
+
(VALUE)(task_),
|
|
95
|
+
&state);
|
|
87
96
|
if (state) {
|
|
88
97
|
iodine_handle_exception(NULL);
|
|
89
98
|
}
|
|
@@ -157,10 +166,13 @@ static VALUE iodine_call2(VALUE obj, ID method, int argc, VALUE *argv) {
|
|
|
157
166
|
}
|
|
158
167
|
|
|
159
168
|
/** Calls a Ruby method on a given object, protecting against exceptions. */
|
|
160
|
-
static VALUE iodine_call_block(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
169
|
+
static VALUE iodine_call_block(
|
|
170
|
+
VALUE obj,
|
|
171
|
+
ID method,
|
|
172
|
+
int argc,
|
|
173
|
+
VALUE *argv,
|
|
174
|
+
VALUE udata,
|
|
175
|
+
VALUE(each_func)(VALUE block_arg, VALUE udata, int argc, VALUE *argv)) {
|
|
164
176
|
iodine_rb_task_s task = {
|
|
165
177
|
.obj = obj,
|
|
166
178
|
.argc = argc,
|
|
@@ -186,7 +198,7 @@ static uint8_t iodine_in_GVL(void) {
|
|
|
186
198
|
}
|
|
187
199
|
|
|
188
200
|
/** Forces the GVL state flag. */
|
|
189
|
-
static void iodine_set_GVL(uint8_t state) {
|
|
201
|
+
static void iodine_set_GVL(uint8_t state) {
|
|
190
202
|
pthread_once(&iodine_GVL_state_once, init_iodine_GVL_state_key);
|
|
191
203
|
uint8_t *iodine_GVL_state = pthread_getspecific(iodine_GVL_state_key);
|
|
192
204
|
if (!iodine_GVL_state) {
|
data/ext/iodine/iodine_store.c
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#include "iodine.h"
|
|
2
|
-
|
|
3
1
|
#include "iodine_store.h"
|
|
4
2
|
|
|
5
3
|
#include <inttypes.h>
|
|
6
4
|
#include <stdint.h>
|
|
7
5
|
|
|
8
|
-
#
|
|
6
|
+
#include "iodine.h"
|
|
7
|
+
|
|
8
|
+
#define FIO_SET_NAME fio_store
|
|
9
9
|
#define FIO_SET_OBJ_TYPE uintptr_t
|
|
10
10
|
#include <fio.h>
|
|
11
11
|
|
|
@@ -23,13 +23,11 @@ API
|
|
|
23
23
|
|
|
24
24
|
/** Adds an object to the storage (or increases it's reference count). */
|
|
25
25
|
static VALUE storage_add(VALUE obj) {
|
|
26
|
-
if (!obj || obj == Qnil || obj == Qtrue || obj == Qfalse)
|
|
27
|
-
return obj;
|
|
26
|
+
if (!obj || obj == Qnil || obj == Qtrue || obj == Qfalse) return obj;
|
|
28
27
|
uintptr_t old = 0;
|
|
29
28
|
fio_lock(&iodine_storage_lock);
|
|
30
29
|
fio_store_overwrite(&iodine_storage, obj, 1, &old);
|
|
31
|
-
if (old)
|
|
32
|
-
fio_store_overwrite(&iodine_storage, obj, old + 1, NULL);
|
|
30
|
+
if (old) fio_store_overwrite(&iodine_storage, obj, old + 1, NULL);
|
|
33
31
|
if (iodine_storage_count_max < fio_store_count(&iodine_storage))
|
|
34
32
|
iodine_storage_count_max = fio_store_count(&iodine_storage);
|
|
35
33
|
fio_unlock(&iodine_storage_lock);
|
|
@@ -43,8 +41,7 @@ static VALUE storage_remove(VALUE obj) {
|
|
|
43
41
|
fio_lock(&iodine_storage_lock);
|
|
44
42
|
uintptr_t old = 0;
|
|
45
43
|
fio_store_remove(&iodine_storage, obj, 0, &old);
|
|
46
|
-
if (old > 1)
|
|
47
|
-
fio_store_overwrite(&iodine_storage, obj, old - 1, NULL);
|
|
44
|
+
if (old > 1) fio_store_overwrite(&iodine_storage, obj, old - 1, NULL);
|
|
48
45
|
fio_unlock(&iodine_storage_lock);
|
|
49
46
|
return obj;
|
|
50
47
|
}
|
|
@@ -58,15 +55,22 @@ static void storage_print(void) {
|
|
|
58
55
|
uintptr_t index = 0;
|
|
59
56
|
FIO_SET_FOR_LOOP(&iodine_storage, pos) {
|
|
60
57
|
if (pos->obj) {
|
|
61
|
-
fprintf(stderr,
|
|
62
|
-
|
|
58
|
+
fprintf(stderr,
|
|
59
|
+
"[%" PRIuPTR "] => %" PRIuPTR " X obj %p type %d\n",
|
|
60
|
+
index++,
|
|
61
|
+
pos->obj,
|
|
62
|
+
(void *)pos->hash,
|
|
63
|
+
TYPE(pos->hash));
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
fprintf(stderr, "Total of %" PRIuPTR " objects protected form GC\n", index);
|
|
66
67
|
fprintf(stderr,
|
|
67
|
-
"Storage uses %" PRIuPTR " Hash bins for %" PRIuPTR
|
|
68
|
+
"Storage uses %" PRIuPTR " Hash bins for %" PRIuPTR
|
|
69
|
+
" objects\n"
|
|
68
70
|
"The largest collection was %zu objects.\n",
|
|
69
|
-
iodine_storage.capa,
|
|
71
|
+
iodine_storage.capa,
|
|
72
|
+
iodine_storage.count,
|
|
73
|
+
iodine_storage_count_max);
|
|
70
74
|
fio_unlock(&iodine_storage_lock);
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -85,8 +89,7 @@ GC protection
|
|
|
85
89
|
/* a callback for the GC (marking active objects) */
|
|
86
90
|
static void storage_mark(void *ignore) {
|
|
87
91
|
(void)ignore;
|
|
88
|
-
if (FIO_LOG_LEVEL >= FIO_LOG_LEVEL_DEBUG)
|
|
89
|
-
storage_print();
|
|
92
|
+
if (FIO_LOG_LEVEL >= FIO_LOG_LEVEL_DEBUG) storage_print();
|
|
90
93
|
fio_lock(&iodine_storage_lock);
|
|
91
94
|
// fio_store_compact(&iodine_storage);
|
|
92
95
|
FIO_SET_FOR_LOOP(&iodine_storage, pos) {
|
|
@@ -131,12 +134,13 @@ struct IodineStorage_s IodineStore = {
|
|
|
131
134
|
/** Initializes the storage unit for first use. */
|
|
132
135
|
void iodine_storage_init(void) {
|
|
133
136
|
fio_store_capa_require(&iodine_storage, 512);
|
|
134
|
-
VALUE tmp =
|
|
135
|
-
rb_define_class_under(rb_cObject, "IodineObjectStorage", rb_cObject);
|
|
137
|
+
VALUE tmp = rb_define_module_under(rb_cObject, "IodineObjectStorage");
|
|
136
138
|
VALUE storage_obj =
|
|
137
139
|
TypedData_Wrap_Struct(tmp, &storage_type_struct, &iodine_storage);
|
|
138
140
|
// rb_global_variable(&iodine_storage_obj);
|
|
139
141
|
rb_ivar_set(IodineModule, rb_intern2("storage", 7), storage_obj);
|
|
140
|
-
rb_define_module_function(IodineBaseModule,
|
|
141
|
-
|
|
142
|
+
rb_define_module_function(IodineBaseModule,
|
|
143
|
+
"db_print_protected_objects",
|
|
144
|
+
storage_print_rb,
|
|
145
|
+
0);
|
|
142
146
|
}
|
data/ext/iodine/websockets.c
CHANGED
|
@@ -99,7 +99,7 @@ void free_ws_buffer(ws_s *owner, struct buffer_s buff) {
|
|
|
99
99
|
Create/Destroy the websocket object (prototypes)
|
|
100
100
|
*/
|
|
101
101
|
|
|
102
|
-
static ws_s *new_websocket();
|
|
102
|
+
static ws_s *new_websocket(intptr_t uuid);
|
|
103
103
|
static void destroy_ws(ws_s *ws);
|
|
104
104
|
|
|
105
105
|
/*******************************************************************************
|
|
@@ -190,19 +190,15 @@ static void websocket_on_protocol_ping(void *ws_p, void *msg_, uint64_t len) {
|
|
|
190
190
|
fio_write2(ws->fd, .data.buffer = buff, .length = len);
|
|
191
191
|
} else {
|
|
192
192
|
if (((ws_s *)ws)->is_client) {
|
|
193
|
-
fio_write2(ws->fd, .data.buffer = "\
|
|
193
|
+
fio_write2(ws->fd, .data.buffer = "\x89\x80mask", .length = 2,
|
|
194
194
|
.after.dealloc = FIO_DEALLOC_NOOP);
|
|
195
195
|
} else {
|
|
196
|
-
fio_write2(ws->fd, .data.buffer = "\
|
|
196
|
+
fio_write2(ws->fd, .data.buffer = "\x89\x00", .length = 2,
|
|
197
197
|
.after.dealloc = FIO_DEALLOC_NOOP);
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
FIO_LOG_DEBUG("Received ping and sent pong for Websocket %p (%d)", ws_p,
|
|
201
|
-
(int)(((ws_s *)ws_p)->fd));
|
|
202
200
|
}
|
|
203
201
|
static void websocket_on_protocol_pong(void *ws_p, void *msg, uint64_t len) {
|
|
204
|
-
FIO_LOG_DEBUG("Received pong for Websocket %p (%d)", ws_p,
|
|
205
|
-
(int)(((ws_s *)ws_p)->fd));
|
|
206
202
|
(void)len;
|
|
207
203
|
(void)msg;
|
|
208
204
|
(void)ws_p;
|
|
@@ -250,10 +246,10 @@ static uint8_t on_shutdown(intptr_t fd, fio_protocol_s *ws) {
|
|
|
250
246
|
if (ws && ((ws_s *)ws)->on_shutdown)
|
|
251
247
|
((ws_s *)ws)->on_shutdown((ws_s *)ws);
|
|
252
248
|
if (((ws_s *)ws)->is_client) {
|
|
253
|
-
fio_write2(fd, .data.buffer = "\
|
|
249
|
+
fio_write2(fd, .data.buffer = "\x8a\x80MASK", .length = 6,
|
|
254
250
|
.after.dealloc = FIO_DEALLOC_NOOP);
|
|
255
251
|
} else {
|
|
256
|
-
fio_write2(fd, .data.buffer = "\
|
|
252
|
+
fio_write2(fd, .data.buffer = "\x8a\x00", .length = 2,
|
|
257
253
|
.after.dealloc = FIO_DEALLOC_NOOP);
|
|
258
254
|
}
|
|
259
255
|
return 0;
|
|
@@ -740,13 +736,8 @@ int websocket_write(ws_s *ws, fio_str_info_s msg, uint8_t is_text) {
|
|
|
740
736
|
}
|
|
741
737
|
/** Closes a websocket connection. */
|
|
742
738
|
void websocket_close(ws_s *ws) {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
.after.dealloc = FIO_DEALLOC_NOOP);
|
|
746
|
-
} else {
|
|
747
|
-
fio_write2(ws->fd, .data.buffer = "\x88\x00", .length = 2,
|
|
748
|
-
.after.dealloc = FIO_DEALLOC_NOOP);
|
|
749
|
-
}
|
|
739
|
+
fio_write2(ws->fd, .data.buffer = "\x88\x00", .length = 2,
|
|
740
|
+
.after.dealloc = FIO_DEALLOC_NOOP);
|
|
750
741
|
fio_close(ws->fd);
|
|
751
742
|
return;
|
|
752
743
|
}
|
data/lib/iodine/version.rb
CHANGED
data/lib/iodine.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: iodine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.59
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Boaz Segev
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rake
|
|
@@ -132,6 +131,7 @@ files:
|
|
|
132
131
|
- LIMITS.md
|
|
133
132
|
- README.md
|
|
134
133
|
- Rakefile
|
|
134
|
+
- SECURITY.md
|
|
135
135
|
- SPEC-PubSub-Draft.md
|
|
136
136
|
- SPEC-WebSocket-Draft.md
|
|
137
137
|
- bin/console
|
|
@@ -251,7 +251,7 @@ licenses:
|
|
|
251
251
|
metadata:
|
|
252
252
|
allowed_push_host: https://rubygems.org
|
|
253
253
|
post_install_message: |-
|
|
254
|
-
Thank you for installing Iodine 0.7.
|
|
254
|
+
Thank you for installing Iodine 0.7.59.
|
|
255
255
|
Remember: if iodine supports your business, it's only fair to give value back (code contributions / donations).
|
|
256
256
|
rdoc_options: []
|
|
257
257
|
require_paths:
|
|
@@ -274,8 +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:
|
|
278
|
-
signing_key:
|
|
277
|
+
rubygems_version: 4.0.3
|
|
279
278
|
specification_version: 4
|
|
280
279
|
summary: iodine - a fast HTTP / Websocket Server with Pub/Sub support, optimized for
|
|
281
280
|
Ruby MRI on Linux / BSD / Windows
|