iodine 0.7.16 → 0.7.17

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of iodine might be problematic. Click here for more details.

Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -4
  3. data/.yardopts +8 -0
  4. data/CHANGELOG.md +26 -0
  5. data/LICENSE.txt +1 -1
  6. data/LIMITS.md +6 -0
  7. data/README.md +93 -13
  8. data/{SPEC-Websocket-Draft.md → SPEC-WebSocket-Draft.md} +0 -0
  9. data/examples/tcp_client.rb +66 -0
  10. data/examples/x-sendfile.ru +14 -0
  11. data/exe/iodine +3 -3
  12. data/ext/iodine/extconf.rb +21 -0
  13. data/ext/iodine/fio.c +659 -69
  14. data/ext/iodine/fio.h +350 -95
  15. data/ext/iodine/fio_cli.c +4 -3
  16. data/ext/iodine/fio_json_parser.h +1 -1
  17. data/ext/iodine/fio_siphash.c +13 -11
  18. data/ext/iodine/fio_siphash.h +6 -3
  19. data/ext/iodine/fio_tls.h +129 -0
  20. data/ext/iodine/fio_tls_missing.c +634 -0
  21. data/ext/iodine/fio_tls_openssl.c +1011 -0
  22. data/ext/iodine/fio_tmpfile.h +1 -1
  23. data/ext/iodine/fiobj.h +1 -1
  24. data/ext/iodine/fiobj_ary.c +1 -1
  25. data/ext/iodine/fiobj_ary.h +1 -1
  26. data/ext/iodine/fiobj_data.c +1 -1
  27. data/ext/iodine/fiobj_data.h +1 -1
  28. data/ext/iodine/fiobj_hash.c +1 -1
  29. data/ext/iodine/fiobj_hash.h +1 -1
  30. data/ext/iodine/fiobj_json.c +18 -16
  31. data/ext/iodine/fiobj_json.h +1 -1
  32. data/ext/iodine/fiobj_mustache.c +4 -0
  33. data/ext/iodine/fiobj_mustache.h +4 -0
  34. data/ext/iodine/fiobj_numbers.c +1 -1
  35. data/ext/iodine/fiobj_numbers.h +1 -1
  36. data/ext/iodine/fiobj_str.c +3 -3
  37. data/ext/iodine/fiobj_str.h +1 -1
  38. data/ext/iodine/fiobject.c +1 -1
  39. data/ext/iodine/fiobject.h +8 -2
  40. data/ext/iodine/http.c +128 -337
  41. data/ext/iodine/http.h +11 -18
  42. data/ext/iodine/http1.c +6 -6
  43. data/ext/iodine/http1.h +1 -1
  44. data/ext/iodine/http1_parser.c +1 -1
  45. data/ext/iodine/http1_parser.h +1 -1
  46. data/ext/iodine/http_internal.c +10 -8
  47. data/ext/iodine/http_internal.h +13 -3
  48. data/ext/iodine/http_mime_parser.h +1 -1
  49. data/ext/iodine/iodine.c +806 -22
  50. data/ext/iodine/iodine.h +33 -0
  51. data/ext/iodine/iodine_connection.c +23 -18
  52. data/ext/iodine/iodine_http.c +239 -225
  53. data/ext/iodine/iodine_http.h +4 -1
  54. data/ext/iodine/iodine_mustache.c +59 -54
  55. data/ext/iodine/iodine_pubsub.c +1 -1
  56. data/ext/iodine/iodine_tcp.c +34 -100
  57. data/ext/iodine/iodine_tcp.h +4 -0
  58. data/ext/iodine/iodine_tls.c +267 -0
  59. data/ext/iodine/iodine_tls.h +13 -0
  60. data/ext/iodine/mustache_parser.h +1 -1
  61. data/ext/iodine/redis_engine.c +14 -6
  62. data/ext/iodine/redis_engine.h +1 -1
  63. data/ext/iodine/resp_parser.h +1 -1
  64. data/ext/iodine/websocket_parser.h +1 -1
  65. data/ext/iodine/websockets.c +1 -1
  66. data/ext/iodine/websockets.h +1 -1
  67. data/iodine.gemspec +2 -1
  68. data/lib/iodine.rb +19 -5
  69. data/lib/iodine/connection.rb +13 -0
  70. data/lib/iodine/mustache.rb +7 -24
  71. data/lib/iodine/tls.rb +16 -0
  72. data/lib/iodine/version.rb +1 -1
  73. data/lib/rack/handler/iodine.rb +1 -1
  74. metadata +15 -5
@@ -0,0 +1,13 @@
1
+ #ifndef H_IODINE_TLS_H
2
+ #define H_IODINE_TLS_H
3
+
4
+ #include "iodine.h"
5
+
6
+ #include "fio_tls.h"
7
+
8
+ void iodine_init_tls(void);
9
+ fio_tls_s *iodine_tls2c(VALUE self);
10
+
11
+ extern VALUE IodineTLSClass;
12
+
13
+ #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright: Boaz Segev, 2018
2
+ Copyright: Boaz Segev, 2018-2019
3
3
  License: MIT
4
4
 
5
5
  Feel free to copy, use and enjoy according to the license provided.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright: Boaz segev, 2016-2017
2
+ Copyright: Boaz segev, 2016-2019
3
3
  License: MIT
4
4
 
5
5
  Feel free to copy, use and enjoy according to the license provided.
@@ -390,6 +390,12 @@ Connection Callbacks (fio_protocol_s) and Engine
390
390
  /** defined later - connects to Redis */
391
391
  static void redis_connect(void *r, void *i);
392
392
 
393
+ #define defer_redis_connect(r, i) \
394
+ do { \
395
+ fio_atomic_add(&(r)->ref, 1); \
396
+ fio_defer(redis_connect, (r), (i)); \
397
+ } while (0);
398
+
393
399
  /** Called when a data is available, but will not run concurrently */
394
400
  static void redis_on_data(intptr_t uuid, fio_protocol_s *pr) {
395
401
  struct redis_engine_internal_s *internal =
@@ -430,7 +436,7 @@ static void redis_on_close(intptr_t uuid, fio_protocol_s *pr) {
430
436
  (int)getpid());
431
437
  }
432
438
  fio_atomic_sub(&r->ref, 1);
433
- fio_defer(redis_connect, r, internal);
439
+ defer_redis_connect(r, internal);
434
440
  } else {
435
441
  redis_free(r);
436
442
  }
@@ -505,7 +511,7 @@ static void redis_on_connect(intptr_t uuid, void *i_) {
505
511
  }
506
512
  fio_pubsub_reattach(&r->en);
507
513
  if (r->pub_data.uuid == -1) {
508
- fio_defer(redis_connect, r, &r->pub_data);
514
+ defer_redis_connect(r, &r->pub_data);
509
515
  }
510
516
  FIO_LOG_INFO("(redis %d) subscription connection established.",
511
517
  (int)getpid());
@@ -551,9 +557,11 @@ static void redis_on_connect_failed(intptr_t uuid, void *i_) {
551
557
  static void redis_connect(void *r_, void *i_) {
552
558
  redis_engine_s *r = r_;
553
559
  struct redis_engine_internal_s *i = i_;
554
- if (r->flag == 0 || i->uuid != -1 || !fio_is_running())
560
+ if (r->flag == 0 || i->uuid != -1 || !fio_is_running()) {
561
+ redis_free(r);
555
562
  return;
556
- fio_atomic_add(&r->ref, 1);
563
+ }
564
+ // fio_atomic_add(&r->ref, 1);
557
565
  i->uuid = fio_connect(.address = r->address, .port = r->port,
558
566
  .on_connect = redis_on_connect, .udata = i,
559
567
  .on_fail = redis_on_connect_failed);
@@ -785,7 +793,7 @@ static void redis_on_facil_start(void *r_) {
785
793
  redis_engine_s *r = r_;
786
794
  r->flag = 1;
787
795
  if (!fio_is_valid(r->sub_data.uuid)) {
788
- fio_defer(redis_connect, r, &r->sub_data);
796
+ defer_redis_connect(r, &r->sub_data);
789
797
  }
790
798
  }
791
799
  static void redis_on_facil_shutdown(void *r_) {
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright: Boaz segev, 2016-2017
2
+ Copyright: Boaz segev, 2016-2019
3
3
  License: MIT
4
4
 
5
5
  Feel free to copy, use and enjoy according to the license provided.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright: Boaz segev, 2016-2017
2
+ Copyright: Boaz segev, 2016-2019
3
3
  License: MIT
4
4
 
5
5
  Feel free to copy, use and enjoy according to the license provided.
@@ -1,5 +1,5 @@
1
1
  /*
2
- copyright: Boaz Segev, 2017
2
+ copyright: Boaz Segev, 2017-2019
3
3
  license: MIT
4
4
 
5
5
  Feel free to copy, use and enjoy according to the license specified.
@@ -1,5 +1,5 @@
1
1
  /*
2
- copyright: Boaz Segev, 2016-2018
2
+ copyright: Boaz Segev, 2016-2019
3
3
  license: MIT
4
4
 
5
5
  Feel free to copy, use and enjoy according to the license provided.
@@ -1,5 +1,5 @@
1
1
  /*
2
- copyright: Boaz Segev, 2016-2018
2
+ copyright: Boaz Segev, 2016-2019
3
3
  license: MIT
4
4
 
5
5
  Feel free to copy, use and enjoy according to the license provided.
@@ -34,7 +34,8 @@ Gem::Specification.new do |spec|
34
34
  spec.requirements << 'A Unix based system: Linux / macOS / BSD.'
35
35
  spec.requirements << 'An updated C compiler.'
36
36
  spec.requirements << 'Ruby >= 2.2.2 required for Rack 2.'
37
- spec.requirements << 'Ruby >= 2.4.0 recommended.'
37
+ spec.requirements << 'Ruby >= 2.5.0 recommended.'
38
+ spec.requirements << 'TLS requires OpenSSL >= 1.1.0'
38
39
 
39
40
  spec.add_development_dependency 'bundler', '>= 1.10', '< 2.0'
40
41
  spec.add_development_dependency 'rake', '~> 12.0', '< 13.0'
@@ -1,4 +1,5 @@
1
- require 'socket' # TCPSocket is used internally for Hijack support
1
+ require 'socket' # TCPSocket is used internally for Hijack support
2
+ # require 'openssl' # For SSL/TLS support using OpenSSL
2
3
 
3
4
  require 'iodine/version'
4
5
  require 'iodine/iodine'
@@ -47,9 +48,7 @@ require 'iodine/iodine'
47
48
  #
48
49
  # Methods for application wide pub/sub include {subscribe}, {unsubscribe} and {publish}. Connection specific pub/sub methods are documented in the {Iodine::Connection} class).
49
50
  #
50
- # Methods for TCP/IP and Unix Sockets connections include {listen} and {connect}.
51
- #
52
- # Methods for HTTP connections include {listen2http}.
51
+ # Methods for TCP/IP, Unix Sockets and HTTP connections include {listen} and {connect}.
53
52
  #
54
53
  # Note that the HTTP server supports both TCP/IP and Unix Sockets as well as SSE / WebSockets extensions.
55
54
  #
@@ -76,6 +75,15 @@ module Iodine
76
75
  end
77
76
 
78
77
 
78
+ # @deprecated use {Iodine.listen} with `service: :http`.
79
+ #
80
+ # Sets a block of code to run once a Worker process shuts down (both in single process mode and cluster mode).
81
+ def self.listen2http(args, &block)
82
+ warn "Iodine.listen2http is deprecated, use Iodine.listen(service: :http)."
83
+ args[:service] = :http;
84
+ Iodine.listen(args, &block)
85
+ end
86
+
79
87
  # @deprecated use {Iodine.on_state}.
80
88
  #
81
89
  # Sets a block of code to run before a new worker process is forked (cluster mode only).
@@ -154,8 +162,14 @@ end
154
162
  ### Parse CLI for default HTTP settings
155
163
  Iodine::Base::CLI.parse
156
164
 
165
+ ### Set default port (if missing)
166
+ Iodine::DEFAULT_SETTINGS[:port] ||= (ENV["PORT"] || "3000")
167
+
168
+ ### Set default binding (if missing)
169
+ Iodine::DEFAULT_SETTINGS[:address] ||= nil
170
+
157
171
  ### Initialize Redis if set in CLI
158
- Iodine::PubSub.default = Iodine::PubSub::Redis.new(Iodine::DEFAULT_HTTP_ARGS[:redis_], ping: Iodine::DEFAULT_HTTP_ARGS[:redis_ping_]) if Iodine::DEFAULT_HTTP_ARGS[:redis_]
172
+ Iodine::PubSub.default = Iodine::PubSub::Redis.new(Iodine::DEFAULT_SETTINGS[:redis_], ping: Iodine::DEFAULT_SETTINGS[:redis_ping_]) if Iodine::DEFAULT_SETTINGS[:redis_]
159
173
 
160
174
  ### Puma / Thin DSL compatibility - depracated (DSLs are evil)
161
175
 
@@ -1,4 +1,17 @@
1
1
  module Iodine
2
+
3
+ # The default connection settings used by {Iodine.listen} and {Iodine.connect}.
4
+ #
5
+ # It's a Hash object that allows Iodine default values to be manipulated. i.e.:
6
+ #
7
+ # DEFAULT_SETTINGS[:port] = "8080" # replaces the default port, which is `ENV["port"] || "3000"`.
8
+ DEFAULT_SETTINGS = {}
9
+
10
+ # @deprecated use {Iodine::DEFAULT_SETTINGS}.
11
+ #
12
+ # The default connection settings used by {Iodine.listen} and {Iodine.connect}.
13
+ DEFAULT_HTTP_ARGS = DEFAULT_SETTINGS
14
+
2
15
  # Iodine's {Iodine::Connection} class is the class that TCP/IP, WebSockets and SSE connections inherit from.
3
16
  #
4
17
  # Instances of this class are passed to the callback objects. i.e.:
@@ -29,9 +29,10 @@ module Iodine
29
29
  # require 'mustache'
30
30
  # require 'iodine'
31
31
  #
32
+ # # Benchmark code was copied, in part, from:
33
+ # # https://github.com/mustache/mustache/blob/master/benchmarks/render_collection_benchmark.rb
34
+ # # The test is, sadly, biased and doesn't test for missing elements, proc/method resolution or template partials.
32
35
  # def benchmark_mustache
33
- # # benchmark code was copied, in part, from:
34
- # # https://github.com/mustache/mustache/blob/master/benchmarks/render_collection_benchmark.rb
35
36
  # template = """
36
37
  # {{#products}}
37
38
  # <div class='product_brick'>
@@ -52,16 +53,12 @@ module Iodine
52
53
  # IO.write "test_template.mustache", template
53
54
  # filename = "test_template.mustache"
54
55
  #
55
- # data_1 = {
56
- # products: [ {
57
- # :external_index=>"This <product> should've been \"properly\" escaped.",
58
- # :url=>"/products/7",
59
- # :image=>"products/product.jpg"
60
- # } ]
61
- # }
62
56
  # data_1000 = {
63
57
  # products: []
64
58
  # }
59
+ # data_1000_escaped = {
60
+ # products: []
61
+ # }
65
62
  #
66
63
  # 1000.times do
67
64
  # data_1000[:products] << {
@@ -69,13 +66,6 @@ module Iodine
69
66
  # :url=>"/products/7",
70
67
  # :image=>"products/product.jpg"
71
68
  # }
72
- # end
73
- #
74
- # data_1000_escaped = {
75
- # products: []
76
- # }
77
- #
78
- # 1000.times do
79
69
  # data_1000_escaped[:products] << {
80
70
  # :external_index=>"This <product> should've been \"properly\" escaped.",
81
71
  # :url=>"/products/7",
@@ -86,14 +76,7 @@ module Iodine
86
76
  # view = Mustache.new
87
77
  # view.template = template
88
78
  # view.render # Call render once so the template will be compiled
89
- # iodine_view = Iodine::Mustache.new(filename)
90
- #
91
- # puts "Ruby Mustache rendering (and HTML escaping) results in:",
92
- # view.render(data_1), "",
93
- # "Notice that Iodine::Mustache rendering (and HTML escaping) results in agressive escaping:",
94
- # iodine_view.render(data_1), "", "----"
95
- #
96
- # # return;
79
+ # iodine_view = Iodine::Mustache.new(template: template)
97
80
  #
98
81
  # Benchmark.ips do |x|
99
82
  # x.report("Ruby Mustache render list of 1000") do |times|
@@ -0,0 +1,16 @@
1
+ module Iodine
2
+ # Iodine's {Iodine::TLS} instances hold SSL/TLS settings for secure connections.
3
+ #
4
+ # This allows both secure client connections and secure server connections to be established.
5
+ #
6
+ # tls = Iodine::TLS.new "localhost" # self-signed certificate
7
+ # Iodine.listen service: "http", handler: APP, tls: tls
8
+ #
9
+ # Iodine abstracts away the underlying SSL/TLS library to minimize the risk of misuse and insecure settings.
10
+ #
11
+ # Calling TLS methods when no SSL/TLS library is available should result in iodine crashing. This is expected behavior.
12
+ #
13
+ # At the moment, only OpenSSL is supported. BearSSL support is planned.
14
+ class TLS
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '0.7.16'.freeze
2
+ VERSION = '0.7.17'.freeze
3
3
  end
@@ -7,7 +7,7 @@ module Iodine
7
7
  # Runs a Rack app, as par the Rack handler requirements.
8
8
  def self.run(app, options = {})
9
9
  # nested applications... is that a thing?
10
- Iodine.listen2http(app: app, port: options[:Port], address: options[:Address])
10
+ Iodine.listen(service: :http, handler: app, port: options[:Port], address: options[:Address])
11
11
 
12
12
  # start Iodine
13
13
  Iodine.start
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.16
4
+ version: 0.7.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-31 00:00:00.000000000 Z
11
+ date: 2019-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -103,6 +103,7 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - ".gitignore"
105
105
  - ".travis.yml"
106
+ - ".yardopts"
106
107
  - CHANGELOG.md
107
108
  - Gemfile
108
109
  - LICENSE.txt
@@ -110,7 +111,7 @@ files:
110
111
  - README.md
111
112
  - Rakefile
112
113
  - SPEC-PubSub-Draft.md
113
- - SPEC-Websocket-Draft.md
114
+ - SPEC-WebSocket-Draft.md
114
115
  - bin/console
115
116
  - bin/info.md
116
117
  - bin/mustache_bench.rb
@@ -126,6 +127,8 @@ files:
126
127
  - examples/redis.ru
127
128
  - examples/shootout.ru
128
129
  - examples/sub-protocols.ru
130
+ - examples/tcp_client.rb
131
+ - examples/x-sendfile.ru
129
132
  - exe/iodine
130
133
  - ext/iodine/extconf.rb
131
134
  - ext/iodine/fio.c
@@ -135,6 +138,9 @@ files:
135
138
  - ext/iodine/fio_json_parser.h
136
139
  - ext/iodine/fio_siphash.c
137
140
  - ext/iodine/fio_siphash.h
141
+ - ext/iodine/fio_tls.h
142
+ - ext/iodine/fio_tls_missing.c
143
+ - ext/iodine/fio_tls_openssl.c
138
144
  - ext/iodine/fio_tmpfile.h
139
145
  - ext/iodine/fiobj.h
140
146
  - ext/iodine/fiobj4fio.h
@@ -189,6 +195,8 @@ files:
189
195
  - ext/iodine/iodine_store.h
190
196
  - ext/iodine/iodine_tcp.c
191
197
  - ext/iodine/iodine_tcp.h
198
+ - ext/iodine/iodine_tls.c
199
+ - ext/iodine/iodine_tls.h
192
200
  - ext/iodine/mustache_parser.h
193
201
  - ext/iodine/redis_engine.c
194
202
  - ext/iodine/redis_engine.h
@@ -203,6 +211,7 @@ files:
203
211
  - lib/iodine/mustache.rb
204
212
  - lib/iodine/pubsub.rb
205
213
  - lib/iodine/rack_utils.rb
214
+ - lib/iodine/tls.rb
206
215
  - lib/iodine/version.rb
207
216
  - lib/rack/handler/iodine.rb
208
217
  - logo.png
@@ -211,7 +220,7 @@ licenses:
211
220
  - MIT
212
221
  metadata:
213
222
  allowed_push_host: https://rubygems.org
214
- post_install_message: 'Thank you for installing Iodine 0.7.16.
223
+ post_install_message: 'Thank you for installing Iodine 0.7.17.
215
224
 
216
225
  '
217
226
  rdoc_options: []
@@ -232,7 +241,8 @@ requirements:
232
241
  - 'A Unix based system: Linux / macOS / BSD.'
233
242
  - An updated C compiler.
234
243
  - Ruby >= 2.2.2 required for Rack 2.
235
- - Ruby >= 2.4.0 recommended.
244
+ - Ruby >= 2.5.0 recommended.
245
+ - TLS requires OpenSSL >= 1.1.0
236
246
  rubyforge_project:
237
247
  rubygems_version: 2.7.7
238
248
  signing_key: