iodine 0.7.41 → 0.7.45
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/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- data/.gitignore +1 -0
- data/CHANGELOG.md +24 -0
- data/README.md +2 -2
- data/SPEC-PubSub-Draft.md +89 -47
- data/SPEC-WebSocket-Draft.md +92 -55
- data/examples/async_task.ru +92 -0
- data/ext/iodine/extconf.rb +21 -16
- data/ext/iodine/fio.c +1108 -162
- data/ext/iodine/fio.h +49 -13
- data/ext/iodine/fio_cli.c +1 -1
- data/ext/iodine/fio_tls_missing.c +8 -0
- data/ext/iodine/fio_tls_openssl.c +8 -0
- data/ext/iodine/fio_tmpfile.h +13 -1
- data/ext/iodine/fiobj_data.c +6 -4
- data/ext/iodine/fiobj_data.h +2 -1
- data/ext/iodine/fiobj_hash.c +32 -6
- data/ext/iodine/fiobj_mustache.c +9 -0
- data/ext/iodine/fiobj_numbers.c +86 -8
- data/ext/iodine/fiobj_str.c +24 -11
- data/ext/iodine/fiobject.c +1 -1
- data/ext/iodine/fiobject.h +5 -3
- data/ext/iodine/http.c +66 -10
- data/ext/iodine/http1.c +2 -1
- data/ext/iodine/http1_parser.h +1065 -103
- data/ext/iodine/http_internal.c +1 -0
- data/ext/iodine/http_internal.h +4 -2
- data/ext/iodine/iodine.c +66 -1
- data/ext/iodine/iodine.h +3 -0
- data/ext/iodine/iodine_caller.c +48 -8
- data/ext/iodine/iodine_connection.c +24 -8
- data/ext/iodine/iodine_http.c +32 -8
- data/ext/iodine/iodine_mustache.c +2 -4
- data/ext/iodine/iodine_rack_io.c +21 -0
- data/ext/iodine/iodine_tcp.c +14 -0
- data/ext/iodine/iodine_tls.c +8 -0
- data/ext/iodine/mustache_parser.h +4 -0
- data/ext/iodine/redis_engine.c +14 -11
- data/ext/iodine/websockets.c +7 -3
- data/iodine.gemspec +5 -4
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +6 -0
- metadata +15 -13
data/ext/iodine/redis_engine.c
CHANGED
@@ -493,6 +493,7 @@ static void redis_pub_ping(intptr_t uuid, fio_protocol_s *pr) {
|
|
493
493
|
return;
|
494
494
|
}
|
495
495
|
redis_commands_s *cmd = fio_malloc(sizeof(*cmd) + 15);
|
496
|
+
FIO_ASSERT_ALLOC(cmd);
|
496
497
|
*cmd = (redis_commands_s){.cmd_len = 14};
|
497
498
|
memcpy(cmd->cmd, "*1\r\n$4\r\nPING\r\n\0", 15);
|
498
499
|
redis_attach_cmd(r, cmd);
|
@@ -534,6 +535,7 @@ static void redis_on_connect(intptr_t uuid, void *i_) {
|
|
534
535
|
r = pub2redis(i);
|
535
536
|
if (r->auth_len) {
|
536
537
|
redis_commands_s *cmd = fio_malloc(sizeof(*cmd) + r->auth_len);
|
538
|
+
FIO_ASSERT_ALLOC(cmd);
|
537
539
|
*cmd =
|
538
540
|
(redis_commands_s){.cmd_len = r->auth_len, .callback = redis_on_auth};
|
539
541
|
memcpy(cmd->cmd, r->auth, r->auth_len);
|
@@ -638,6 +640,7 @@ static void redis_on_publish_root(const fio_pubsub_engine_s *eng,
|
|
638
640
|
uint8_t is_json) {
|
639
641
|
redis_engine_s *r = (redis_engine_s *)eng;
|
640
642
|
redis_commands_s *cmd = fio_malloc(sizeof(*cmd) + channel.len + msg.len + 96);
|
643
|
+
FIO_ASSERT_ALLOC(cmd);
|
641
644
|
*cmd = (redis_commands_s){.cmd_len = 0};
|
642
645
|
memcpy(cmd->cmd, "*3\r\n$7\r\nPUBLISH\r\n$", 18);
|
643
646
|
char *buf = (char *)cmd->cmd + 18;
|
@@ -684,7 +687,7 @@ static void redis_on_publish_child(const fio_pubsub_engine_s *eng,
|
|
684
687
|
fio_str_s tmp = FIO_STR_INIT;
|
685
688
|
/* by using fio_str_s, short names are allocated on the stack */
|
686
689
|
fio_str_info_s tmp_info = fio_str_resize(&tmp, channel.len + 8);
|
687
|
-
fio_u2str64(tmp_info.data, (
|
690
|
+
fio_u2str64(tmp_info.data, (uintptr_t)eng);
|
688
691
|
memcpy(tmp_info.data + 8, channel.data, channel.len);
|
689
692
|
/* forward publication request to Root */
|
690
693
|
fio_publish(.filter = -1, .channel = tmp_info, .message = msg,
|
@@ -701,7 +704,7 @@ Root Publication Handler
|
|
701
704
|
static void redis_on_internal_publish(fio_msg_s *msg) {
|
702
705
|
if (msg->channel.len < 8)
|
703
706
|
return; /* internal error, unexpected data */
|
704
|
-
void *en = (void *)fio_str2u64(msg->channel.data);
|
707
|
+
void *en = (void *)(uintptr_t)fio_str2u64(msg->channel.data);
|
705
708
|
if (en != msg->udata1)
|
706
709
|
return; /* should be delivered by a different engine */
|
707
710
|
/* step after the engine data */
|
@@ -721,8 +724,8 @@ Sending commands using the Root connection
|
|
721
724
|
static void redis_forward_reply(fio_pubsub_engine_s *e, FIOBJ reply,
|
722
725
|
void *udata) {
|
723
726
|
uint8_t *data = udata;
|
724
|
-
fio_pubsub_engine_s *engine = (fio_pubsub_engine_s *)fio_str2u64(data + 0);
|
725
|
-
void *callback = (void *)fio_str2u64(data + 8);
|
727
|
+
fio_pubsub_engine_s *engine = (fio_pubsub_engine_s *)(uintptr_t)fio_str2u64(data + 0);
|
728
|
+
void *callback = (void *)(uintptr_t)fio_str2u64(data + 8);
|
726
729
|
if (engine != e || !callback) {
|
727
730
|
FIO_LOG_DEBUG("Redis reply not forwarded (callback: %p)", callback);
|
728
731
|
return;
|
@@ -738,7 +741,7 @@ static void redis_forward_reply(fio_pubsub_engine_s *e, FIOBJ reply,
|
|
738
741
|
static void redis_on_internal_cmd(fio_msg_s *msg) {
|
739
742
|
// void*(void *)fio_str2u64(msg->msg.data);
|
740
743
|
fio_pubsub_engine_s *engine =
|
741
|
-
(fio_pubsub_engine_s *)fio_str2u64(msg->channel.data + 0);
|
744
|
+
(fio_pubsub_engine_s *)(uintptr_t)fio_str2u64(msg->channel.data + 0);
|
742
745
|
if (engine != msg->udata1) {
|
743
746
|
return;
|
744
747
|
}
|
@@ -756,7 +759,7 @@ static void redis_on_internal_cmd(fio_msg_s *msg) {
|
|
756
759
|
/* Listens on filter `-10 -getpid()` for incoming reply data */
|
757
760
|
static void redis_on_internal_reply(fio_msg_s *msg) {
|
758
761
|
fio_pubsub_engine_s *engine =
|
759
|
-
(fio_pubsub_engine_s *)fio_str2u64(msg->channel.data + 0);
|
762
|
+
(fio_pubsub_engine_s *)(uintptr_t)fio_str2u64(msg->channel.data + 0);
|
760
763
|
if (engine != msg->udata1) {
|
761
764
|
FIO_LOG_DEBUG("Redis reply not forwarded (engine mismatch: %p != %p)",
|
762
765
|
(void *)engine, msg->udata1);
|
@@ -765,8 +768,8 @@ static void redis_on_internal_reply(fio_msg_s *msg) {
|
|
765
768
|
FIOBJ reply;
|
766
769
|
fiobj_json2obj(&reply, msg->msg.data, msg->msg.len);
|
767
770
|
void (*callback)(fio_pubsub_engine_s *, FIOBJ, void *) = (void (*)(
|
768
|
-
fio_pubsub_engine_s *, FIOBJ, void *))fio_str2u64(msg->channel.data + 8);
|
769
|
-
void *udata = (void *)fio_str2u64(msg->channel.data + 16);
|
771
|
+
fio_pubsub_engine_s *, FIOBJ, void *))(uintptr_t)fio_str2u64(msg->channel.data + 8);
|
772
|
+
void *udata = (void *)(uintptr_t)fio_str2u64(msg->channel.data + 16);
|
770
773
|
callback(engine, reply, udata);
|
771
774
|
fiobj_free(reply);
|
772
775
|
}
|
@@ -788,9 +791,9 @@ intptr_t redis_engine_send(fio_pubsub_engine_s *engine, FIOBJ command,
|
|
788
791
|
fio_str_s tmp = FIO_STR_INIT;
|
789
792
|
fio_str_info_s ti = fio_str_resize(&tmp, 28);
|
790
793
|
/* combine metadata */
|
791
|
-
fio_u2str64(ti.data + 0, (
|
792
|
-
fio_u2str64(ti.data + 8, (
|
793
|
-
fio_u2str64(ti.data + 16, (
|
794
|
+
fio_u2str64(ti.data + 0, (uintptr_t)engine);
|
795
|
+
fio_u2str64(ti.data + 8, (uintptr_t)callback);
|
796
|
+
fio_u2str64(ti.data + 16, (uintptr_t)udata);
|
794
797
|
fio_u2str32(ti.data + 24, (uint32_t)getpid());
|
795
798
|
FIOBJ cmd = fiobj2resp_tmp(command);
|
796
799
|
fio_publish(.filter = -2, .channel = ti, .message = fiobj_obj2cstr(cmd),
|
data/ext/iodine/websockets.c
CHANGED
@@ -17,7 +17,9 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
17
17
|
#include <http.h>
|
18
18
|
#include <http_internal.h>
|
19
19
|
|
20
|
+
#ifndef __MINGW32__
|
20
21
|
#include <arpa/inet.h>
|
22
|
+
#endif
|
21
23
|
#include <errno.h>
|
22
24
|
#include <stdio.h>
|
23
25
|
#include <stdlib.h>
|
@@ -26,7 +28,7 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
26
28
|
|
27
29
|
#include <websocket_parser.h>
|
28
30
|
|
29
|
-
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
|
31
|
+
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) && !defined(__MINGW32__)
|
30
32
|
#include <endian.h>
|
31
33
|
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) && \
|
32
34
|
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
@@ -71,6 +73,7 @@ struct buffer_s create_ws_buffer(ws_s *owner) {
|
|
71
73
|
struct buffer_s buff;
|
72
74
|
buff.size = WS_INITIAL_BUFFER_SIZE;
|
73
75
|
buff.data = malloc(buff.size);
|
76
|
+
FIO_ASSERT_ALLOC(buff.data);
|
74
77
|
return buff;
|
75
78
|
}
|
76
79
|
|
@@ -79,7 +82,6 @@ struct buffer_s resize_ws_buffer(ws_s *owner, struct buffer_s buff) {
|
|
79
82
|
void *tmp = realloc(buff.data, buff.size);
|
80
83
|
if (!tmp) {
|
81
84
|
free_ws_buffer(owner, buff);
|
82
|
-
buff.data = NULL;
|
83
85
|
buff.size = 0;
|
84
86
|
}
|
85
87
|
buff.data = tmp;
|
@@ -174,6 +176,7 @@ static void websocket_on_protocol_ping(void *ws_p, void *msg_, uint64_t len) {
|
|
174
176
|
ws_s *ws = ws_p;
|
175
177
|
if (msg_) {
|
176
178
|
void *buff = malloc(len + 16);
|
179
|
+
FIO_ASSERT_ALLOC(buff);
|
177
180
|
len = (((ws_s *)ws)->is_client
|
178
181
|
? websocket_client_wrap(buff, msg_, len, 10, 1, 1, 0)
|
179
182
|
: websocket_server_wrap(buff, msg_, len, 10, 1, 1, 0));
|
@@ -305,6 +308,7 @@ Create/Destroy the websocket object
|
|
305
308
|
static ws_s *new_websocket(intptr_t uuid) {
|
306
309
|
// allocate the protocol object
|
307
310
|
ws_s *ws = malloc(sizeof(*ws));
|
311
|
+
FIO_ASSERT_ALLOC(ws);
|
308
312
|
*ws = (ws_s){
|
309
313
|
.protocol.ping = ws_ping,
|
310
314
|
.protocol.on_data = on_data_first,
|
@@ -330,7 +334,6 @@ static void destroy_ws(ws_s *ws) {
|
|
330
334
|
void websocket_attach(intptr_t uuid, http_settings_s *http_settings,
|
331
335
|
websocket_settings_s *args, void *data, size_t length) {
|
332
336
|
ws_s *ws = new_websocket(uuid);
|
333
|
-
FIO_ASSERT_ALLOC(ws);
|
334
337
|
// we have an active websocket connection - prep the connection buffer
|
335
338
|
ws->buffer = create_ws_buffer(ws);
|
336
339
|
// Setup ws callbacks
|
@@ -383,6 +386,7 @@ static void websocket_write_impl(intptr_t fd, void *data, size_t len, char text,
|
|
383
386
|
char first, char last, char client) {
|
384
387
|
if (len <= WS_MAX_FRAME_SIZE) {
|
385
388
|
void *buff = fio_malloc(len + 16);
|
389
|
+
FIO_ASSERT_ALLOC(buff);
|
386
390
|
len = (client ? websocket_client_wrap(buff, data, len, (text ? 1 : 2),
|
387
391
|
first, last, 0)
|
388
392
|
: websocket_server_wrap(buff, data, len, (text ? 1 : 2),
|
data/iodine.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Boaz Segev']
|
10
10
|
spec.email = ['bo@plezi.io']
|
11
11
|
|
12
|
-
spec.summary = 'iodine - a fast HTTP / Websocket Server with Pub/Sub support, optimized for Ruby MRI on Linux / BSD'
|
13
|
-
spec.description = 'A fast HTTP / Websocket Server with built-in Pub/Sub support (with or without Redis), static file support and many other features, optimized for Ruby MRI on Linux / BSD / macOS'
|
12
|
+
spec.summary = 'iodine - a fast HTTP / Websocket Server with Pub/Sub support, optimized for Ruby MRI on Linux / BSD / Windows'
|
13
|
+
spec.description = 'A fast HTTP / Websocket Server with built-in Pub/Sub support (with or without Redis), static file support and many other features, optimized for Ruby MRI on Linux / BSD / macOS / Windows'
|
14
14
|
spec.homepage = 'https://github.com/boazsegev/iodine'
|
15
15
|
spec.license = 'MIT'
|
16
16
|
|
@@ -35,10 +35,11 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.requirements << 'An updated C compiler.'
|
36
36
|
spec.requirements << 'Ruby >= 2.3.8 (Ruby EOL).'
|
37
37
|
spec.requirements << 'Ruby >= 2.5.0 recommended.'
|
38
|
-
spec.requirements << 'TLS requires OpenSSL >= 1.1.0'
|
38
|
+
spec.requirements << 'TLS requires OpenSSL >= 1.1.0.'
|
39
|
+
spec.requirements << 'Or Windows with Ruby >= 3.0.0 build with MingW and MingW as compiler.'
|
39
40
|
|
40
41
|
# spec.add_development_dependency 'bundler', '>= 1.10', '< 2.0'
|
41
|
-
spec.add_development_dependency 'rake', '
|
42
|
+
spec.add_development_dependency 'rake', '>= 12.0', '< 14.0'
|
42
43
|
spec.add_development_dependency 'minitest', '>=5', '< 6.0'
|
43
44
|
spec.add_development_dependency 'rspec', '>=3.9.0', '< 4.0'
|
44
45
|
spec.add_development_dependency 'spec', '>=5.3.0', '< 6.0'
|
data/lib/iodine/version.rb
CHANGED
data/lib/rack/handler/iodine.rb
CHANGED
metadata
CHANGED
@@ -1,35 +1,35 @@
|
|
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.45
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '12.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '14.0'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - "
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '12.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '14.0'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: minitest
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,7 +112,7 @@ dependencies:
|
|
112
112
|
version: '2.0'
|
113
113
|
description: A fast HTTP / Websocket Server with built-in Pub/Sub support (with or
|
114
114
|
without Redis), static file support and many other features, optimized for Ruby
|
115
|
-
MRI on Linux / BSD / macOS
|
115
|
+
MRI on Linux / BSD / macOS / Windows
|
116
116
|
email:
|
117
117
|
- bo@plezi.io
|
118
118
|
executables:
|
@@ -142,6 +142,7 @@ files:
|
|
142
142
|
- bin/poc/config.ru
|
143
143
|
- bin/poc/gemfile
|
144
144
|
- bin/poc/www/index.html
|
145
|
+
- examples/async_task.ru
|
145
146
|
- examples/config.ru
|
146
147
|
- examples/echo.ru
|
147
148
|
- examples/hello.ru
|
@@ -243,7 +244,7 @@ licenses:
|
|
243
244
|
metadata:
|
244
245
|
allowed_push_host: https://rubygems.org
|
245
246
|
post_install_message: |-
|
246
|
-
Thank you for installing Iodine 0.7.
|
247
|
+
Thank you for installing Iodine 0.7.45.
|
247
248
|
Remember: if iodine supports your business, it's only fair to give value back (code contributions / donations).
|
248
249
|
rdoc_options: []
|
249
250
|
require_paths:
|
@@ -264,10 +265,11 @@ requirements:
|
|
264
265
|
- An updated C compiler.
|
265
266
|
- Ruby >= 2.3.8 (Ruby EOL).
|
266
267
|
- Ruby >= 2.5.0 recommended.
|
267
|
-
- TLS requires OpenSSL >= 1.1.0
|
268
|
-
|
269
|
-
|
268
|
+
- TLS requires OpenSSL >= 1.1.0.
|
269
|
+
- Or Windows with Ruby >= 3.0.0 build with MingW and MingW as compiler.
|
270
|
+
rubygems_version: 3.2.3
|
271
|
+
signing_key:
|
270
272
|
specification_version: 4
|
271
273
|
summary: iodine - a fast HTTP / Websocket Server with Pub/Sub support, optimized for
|
272
|
-
Ruby MRI on Linux / BSD
|
274
|
+
Ruby MRI on Linux / BSD / Windows
|
273
275
|
test_files: []
|