iodine 0.7.59 → 0.8.0

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.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +15 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -3
  5. data/CHANGELOG.md +132 -12
  6. data/Gemfile +5 -7
  7. data/LICENSE.txt +1 -1
  8. data/README.md +147 -671
  9. data/Rakefile +9 -16
  10. data/examples/chatroom.nru +9 -0
  11. data/examples/client +74 -0
  12. data/examples/config-hello.nru +9 -0
  13. data/examples/config-hello.ru +11 -0
  14. data/examples/config-hijack.ru +13 -0
  15. data/examples/config-shootout.ru +43 -0
  16. data/examples/config.nru +120 -0
  17. data/examples/config.rb +37 -0
  18. data/examples/config.ru +42 -53
  19. data/examples/fake +24 -0
  20. data/examples/hello_neorack +137 -0
  21. data/examples/routes.nru +29 -0
  22. data/examples/routes.ru +42 -0
  23. data/exe/iodine +218 -258
  24. data/ext/iodine/extconf.rb +27 -100
  25. data/ext/iodine/fio-stl.h +128336 -0
  26. data/ext/iodine/fio-stl.md +26396 -0
  27. data/ext/iodine/iodine.c +213 -1393
  28. data/ext/iodine/iodine.h +250 -55
  29. data/ext/iodine/iodine_arg_helper.h +329 -0
  30. data/ext/iodine/iodine_caller.h +234 -25
  31. data/ext/iodine/iodine_cli.h +434 -0
  32. data/ext/iodine/iodine_compression.h +312 -0
  33. data/ext/iodine/iodine_connection.h +3484 -34
  34. data/ext/iodine/iodine_core.h +363 -0
  35. data/ext/iodine/iodine_crypto.h +1441 -0
  36. data/ext/iodine/iodine_defer.h +225 -4
  37. data/ext/iodine/iodine_json.h +738 -4
  38. data/ext/iodine/iodine_listener.h +263 -0
  39. data/ext/iodine/iodine_log.h +297 -0
  40. data/ext/iodine/iodine_minimap.h +543 -0
  41. data/ext/iodine/iodine_mustache.h +461 -4
  42. data/ext/iodine/iodine_pubsub_eng.h +729 -0
  43. data/ext/iodine/iodine_pubsub_history.h +547 -0
  44. data/ext/iodine/iodine_pubsub_msg.h +228 -0
  45. data/ext/iodine/iodine_redis.h +322 -0
  46. data/ext/iodine/iodine_store.h +418 -16
  47. data/ext/iodine/iodine_threads.h +279 -0
  48. data/ext/iodine/iodine_tls.h +515 -6
  49. data/ext/iodine/iodine_utils.h +923 -0
  50. data/iodine.gemspec +37 -42
  51. data/lib/iodine/benchmark.rb +1690 -0
  52. data/lib/iodine/documentation.rb +3085 -0
  53. data/lib/iodine/version.rb +17 -1
  54. data/lib/iodine.rb +54 -255
  55. data/logo.svg +36 -0
  56. data/mustache.md +55 -0
  57. data/sig/iodine.rbs +4 -0
  58. metadata +58 -184
  59. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  60. data/.github/workflows/ruby.yml +0 -42
  61. data/.gitignore +0 -20
  62. data/LIMITS.md +0 -41
  63. data/SPEC-PubSub-Draft.md +0 -159
  64. data/SPEC-WebSocket-Draft.md +0 -239
  65. data/bin/console +0 -22
  66. data/bin/info.md +0 -353
  67. data/bin/mustache_bench.rb +0 -100
  68. data/bin/poc/Gemfile.lock +0 -23
  69. data/bin/poc/README.md +0 -37
  70. data/bin/poc/config.ru +0 -66
  71. data/bin/poc/gemfile +0 -1
  72. data/bin/poc/www/index.html +0 -57
  73. data/examples/async_task.ru +0 -92
  74. data/examples/bates/README.md +0 -3
  75. data/examples/bates/config.ru +0 -342
  76. data/examples/bates/david+bold.pdf +0 -0
  77. data/examples/bates/public/drop-pdf.png +0 -0
  78. data/examples/bates/public/index.html +0 -600
  79. data/examples/echo.ru +0 -59
  80. data/examples/etag.ru +0 -16
  81. data/examples/hello.ru +0 -29
  82. data/examples/pubsub_engine.ru +0 -81
  83. data/examples/rack3.ru +0 -12
  84. data/examples/redis.ru +0 -70
  85. data/examples/shootout.ru +0 -73
  86. data/examples/sub-protocols.ru +0 -90
  87. data/examples/tcp_client.rb +0 -66
  88. data/examples/x-sendfile.ru +0 -14
  89. data/ext/iodine/fio.c +0 -11995
  90. data/ext/iodine/fio.h +0 -6371
  91. data/ext/iodine/fio_cli.c +0 -431
  92. data/ext/iodine/fio_cli.h +0 -189
  93. data/ext/iodine/fio_json_parser.h +0 -688
  94. data/ext/iodine/fio_siphash.c +0 -157
  95. data/ext/iodine/fio_siphash.h +0 -37
  96. data/ext/iodine/fio_tls.h +0 -129
  97. data/ext/iodine/fio_tls_missing.c +0 -649
  98. data/ext/iodine/fio_tls_openssl.c +0 -1106
  99. data/ext/iodine/fio_tmpfile.h +0 -50
  100. data/ext/iodine/fiobj.h +0 -44
  101. data/ext/iodine/fiobj4fio.h +0 -21
  102. data/ext/iodine/fiobj_ary.c +0 -333
  103. data/ext/iodine/fiobj_ary.h +0 -139
  104. data/ext/iodine/fiobj_data.c +0 -1187
  105. data/ext/iodine/fiobj_data.h +0 -167
  106. data/ext/iodine/fiobj_hash.c +0 -409
  107. data/ext/iodine/fiobj_hash.h +0 -176
  108. data/ext/iodine/fiobj_json.c +0 -622
  109. data/ext/iodine/fiobj_json.h +0 -68
  110. data/ext/iodine/fiobj_mem.h +0 -71
  111. data/ext/iodine/fiobj_mustache.c +0 -317
  112. data/ext/iodine/fiobj_mustache.h +0 -62
  113. data/ext/iodine/fiobj_numbers.c +0 -344
  114. data/ext/iodine/fiobj_numbers.h +0 -127
  115. data/ext/iodine/fiobj_str.c +0 -433
  116. data/ext/iodine/fiobj_str.h +0 -172
  117. data/ext/iodine/fiobject.c +0 -620
  118. data/ext/iodine/fiobject.h +0 -655
  119. data/ext/iodine/hpack.h +0 -1923
  120. data/ext/iodine/http.c +0 -2743
  121. data/ext/iodine/http.h +0 -1002
  122. data/ext/iodine/http1.c +0 -910
  123. data/ext/iodine/http1.h +0 -29
  124. data/ext/iodine/http1_parser.h +0 -878
  125. data/ext/iodine/http_internal.c +0 -1279
  126. data/ext/iodine/http_internal.h +0 -237
  127. data/ext/iodine/http_mime_parser.h +0 -350
  128. data/ext/iodine/iodine_caller.c +0 -230
  129. data/ext/iodine/iodine_connection.c +0 -941
  130. data/ext/iodine/iodine_defer.c +0 -420
  131. data/ext/iodine/iodine_fiobj2rb.h +0 -120
  132. data/ext/iodine/iodine_helpers.c +0 -282
  133. data/ext/iodine/iodine_helpers.h +0 -12
  134. data/ext/iodine/iodine_http.c +0 -1181
  135. data/ext/iodine/iodine_http.h +0 -23
  136. data/ext/iodine/iodine_json.c +0 -302
  137. data/ext/iodine/iodine_mustache.c +0 -567
  138. data/ext/iodine/iodine_pubsub.c +0 -580
  139. data/ext/iodine/iodine_pubsub.h +0 -26
  140. data/ext/iodine/iodine_rack_io.c +0 -273
  141. data/ext/iodine/iodine_rack_io.h +0 -20
  142. data/ext/iodine/iodine_store.c +0 -146
  143. data/ext/iodine/iodine_tcp.c +0 -346
  144. data/ext/iodine/iodine_tcp.h +0 -13
  145. data/ext/iodine/iodine_tls.c +0 -261
  146. data/ext/iodine/mustache_parser.h +0 -1546
  147. data/ext/iodine/redis_engine.c +0 -957
  148. data/ext/iodine/redis_engine.h +0 -79
  149. data/ext/iodine/resp_parser.h +0 -317
  150. data/ext/iodine/websocket_parser.h +0 -506
  151. data/ext/iodine/websockets.c +0 -743
  152. data/ext/iodine/websockets.h +0 -185
  153. data/lib/iodine/connection.rb +0 -61
  154. data/lib/iodine/json.rb +0 -42
  155. data/lib/iodine/mustache.rb +0 -113
  156. data/lib/iodine/pubsub.rb +0 -55
  157. data/lib/iodine/rack_utils.rb +0 -43
  158. data/lib/iodine/tls.rb +0 -16
  159. data/lib/rack/handler/iodine.rb +0 -33
  160. data/logo.png +0 -0
@@ -1,3 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Iodine
2
- VERSION = '0.7.59'.freeze
4
+ # The Iodine gem version number
5
+ VERSION = "0.8.0"
6
+ # NeoRack supported extensions.
7
+ def self.extensions
8
+ return (@extensions ||= { iodine: (VERSION.split(?.).map() {|i| i.to_i.to_s == i ? i.to_i : i }),
9
+ neo_rack: "0.0.4".split(?.).map(&:to_i),
10
+ cookies: "0.0.2".split(?.).map(&:to_i),
11
+ from: "0.0.2".split(?.).map(&:to_i),
12
+ pubsub: "0.0.2".split(?.).map(&:to_i),
13
+ rack: "1.3.0".split(?.).map(&:to_i),
14
+ rest: "0.0.2".split(?.).map(&:to_i),
15
+ sse: "0.0.2".split(?.).map(&:to_i),
16
+ ws: "0.0.2".split(?.).map(&:to_i)
17
+ })
18
+ end
3
19
  end
data/lib/iodine.rb CHANGED
@@ -1,278 +1,77 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'stringio' # Used internally as a default RackIO
2
4
  require 'socket' # TCPSocket is used internally for Hijack support
3
- # require 'openssl' # For SSL/TLS support using OpenSSL
4
-
5
- require_relative './iodine/version'
6
- require_relative './iodine/iodine_ext' # loading a binary C extension
7
-
8
- # Iodine is an HTTP / WebSocket server as well as an Evented Network Tool Library. In essense, Iodine is a Ruby port for the [facil.io](http://facil.io) C library.
9
- #
10
- # Here is a simple telnet based echo server using Iodine (see full list at {Iodine::Connection}):
11
- #
12
- #
13
- # require 'iodine'
14
- # # define the protocol for our service
15
- # module EchoProtocol
16
- # def on_open(client)
17
- # # Set a connection timeout
18
- # client.timeout = 10
19
- # # Write a welcome message
20
- # client.write "Echo server running on Iodine #{Iodine::VERSION}.\r\n"
21
- # end
22
- # # this is called for incoming data - note data might be fragmented.
23
- # def on_message(client, data)
24
- # # write the data we received
25
- # client.write "echo: #{data}"
26
- # # close the connection when the time comes
27
- # client.close if data =~ /^bye[\n\r]/
28
- # end
29
- # # called if the connection is still open and the server is shutting down.
30
- # def on_shutdown(client)
31
- # # write the data we received
32
- # client.write "Server going away\r\n"
33
- # end
34
- # extend self
35
- # end
36
- # # create the service instance, the block returns a connection handler.
37
- # Iodine.listen(port: "3000") { EchoProtocol }
38
- # # start the service
39
- # Iodine.threads = 1
40
- # Iodine.start
41
- #
42
- #
43
- #
44
- # Methods for setting up and starting {Iodine} include {start}, {threads}, {threads=}, {workers} and {workers=}.
45
- #
46
- # Methods for setting startup / operational callbacks include {on_idle}, {on_state}.
47
- #
48
- # Methods for asynchronous execution include {run} (same as {defer}), {run_after} and {run_every}.
49
- #
50
- # Methods for application wide pub/sub include {subscribe}, {unsubscribe} and {publish}. Connection specific pub/sub methods are documented in the {Iodine::Connection} class).
51
- #
52
- # Methods for TCP/IP, Unix Sockets and HTTP connections include {listen} and {connect}.
53
- #
54
- # Note that the HTTP server supports both TCP/IP and Unix Sockets as well as SSE / WebSockets extensions.
55
- #
56
- # Iodine doesn't call {patch_rack} automatically, but doing so will improve Rack's performace.
57
- #
58
- # Please read the {file:README.md} file for an introduction to Iodine.
59
- #
60
- module Iodine
61
5
 
62
- # Will monkey patch some Rack methods to increase their performance.
63
- #
64
- # This is recommended, see {Iodine::Rack::Utils} for details.
65
- def self.patch_rack
66
- begin
67
- require 'rack'
68
- rescue LoadError
69
- end
70
- ::Rack::Utils.class_eval do
71
- Iodine::Base::MonkeyPatch::RackUtils.methods(false).each do |m|
72
- ::Rack::Utils.define_singleton_method(m,
73
- Iodine::Base::MonkeyPatch::RackUtils.instance_method(m) )
74
- end
75
- end
76
- end
6
+ require_relative 'iodine/version'
77
7
 
8
+ require 'iodine/iodine'
78
9
 
79
- # @deprecated use {Iodine.listen} with `service: :http`.
80
- #
81
- # Sets a block of code to run once a Worker process shuts down (both in single process mode and cluster mode).
82
- def self.listen2http(args, &block)
83
- warn "Iodine.listen2http is deprecated, use Iodine.listen(service: :http)."
84
- args[:service] = :http;
85
- Iodine.listen(args, &block)
86
- end
10
+ # Support common ENV options for setting concurrency.
11
+ Iodine.threads = ENV['RAILS_MAX_THREADS'].to_i if ENV['RAILS_MAX_THREADS'] && Iodine.threads.zero?
12
+ Iodine.workers = ENV['WEB_CONCURRENCY'].to_i if ENV['WEB_CONCURRENCY'] && Iodine.workers.zero?
13
+ Iodine.threads = ENV['WEB_THREADS'].to_i if ENV['WEB_THREADS'] && Iodine.threads.zero?
14
+ Iodine.workers = ENV['WEB_WORKERS'].to_i if ENV['WEB_WORKERS'] && Iodine.workers.zero?
15
+ Iodine.threads = ENV['THREADS'].to_i if ENV['THREADS'] && Iodine.threads.zero?
16
+ Iodine.workers = ENV['WORKERS'].to_i if ENV['WORKERS'] && Iodine.workers.zero?
87
17
 
88
- # @deprecated use {Iodine.on_state}.
89
- #
90
- # Sets a block of code to run before a new worker process is forked (cluster mode only).
91
- def self.before_fork(&block)
92
- warn "Iodine.before_fork is deprecated, use Iodine.on_state(:before_fork)."
93
- Iodine.on_state(:before_fork, &block)
94
- end
95
- # @deprecated use {Iodine.on_state}.
96
- #
97
- # Sets a block of code to run after a new worker process is forked (cluster mode only).
98
- #
99
- # Code runs in both the parent and the child.
100
- def self.after_fork(&block)
101
- warn "Iodine.after_fork is deprecated, use Iodine.on_state(:after_fork)."
102
- Iodine.on_state(:after_fork, &block)
103
- end
104
- # @deprecated use {Iodine.on_state}.
105
- #
106
- # Sets a block of code to run in the worker process, after a new worker process is forked (cluster mode only).
107
- def self.after_fork_in_worker(&block)
108
- warn "Iodine.after_fork_in_worker is deprecated, use Iodine.on_state(:enter_child)."
109
- Iodine.on_state(:enter_child, &block)
110
- end
111
- # @deprecated use {Iodine.on_state}.
112
- #
113
- # Sets a block of code to run in the master / root process, after a new worker process is forked (cluster mode only).
114
- def self.after_fork_in_master(&block)
115
- warn "Iodine.after_fork_in_master is deprecated, use Iodine.on_state(:enter_master)."
116
- Iodine.on_state(:enter_master, &block)
117
- end
118
- # @deprecated use {Iodine.on_state}.
119
- #
120
- # Sets a block of code to run once a Worker process shuts down (both in single process mode and cluster mode).
121
- def self.on_shutdown(&block)
122
- warn "Iodine.on_shutdown is deprecated, use Iodine.on_state(:on_finish)."
123
- Iodine.on_state(:on_finish, &block)
124
- end
125
-
126
- module PubSub
127
- # @deprecated use {Iodine::PubSub.detach}.
128
- def self.dettach(engine)
129
- warn "Iodine::PubSub.dettach is deprecated (was a typo), use Iodine::PubSub.detach(engine)."
130
- Iodine::PubSub.detach(engine)
131
- end
18
+ module Iodine
19
+ class Base
20
+ # Trap SIGINT only if it wasn't trapped beforehand.
21
+ def self.trap_sigint
22
+ old_trap = trap('SIGINT') { puts "(#{Process.pid}) Received Ctrl-C and shutting down iodine." }
23
+ trap('SIGINT', &old_trap) if old_trap && old_trap.respond_to?(:call)
132
24
  end
25
+ end
133
26
 
134
- ### trap some signals to avoid excessive exception reports
135
- begin
136
- old_sigint = Signal.trap("SIGINT") { old_sigint.call if old_sigint.respond_to?(:call) }
137
- rescue Exception
138
- end
139
- begin
140
- old_sigterm = Signal.trap("SIGTERM") { old_sigterm.call if old_sigterm.respond_to?(:call) }
141
- rescue Exception
142
- end
143
- begin
144
- old_sigpipe = Signal.trap("SIGPIPE") { old_sigpipe.call if old_sigpipe.respond_to?(:call) }
145
- rescue Exception
146
- end
147
- begin
148
- old_sigusr1 = Signal.trap("SIGUSR1") { old_sigusr1.call if old_sigusr1.respond_to?(:call) }
149
- rescue Exception
27
+ module PubSub
28
+ class Engine
29
+ # Base publish method — subclasses override this to route messages to
30
+ # external brokers. The default implementation is a no-op (the built-in
31
+ # CLUSTER and LOCAL engines handle delivery in C).
32
+ #
33
+ # @param msg [Iodine::PubSub::Message] the message to publish
34
+ # @return [void]
35
+ def publish(msg); end
150
36
  end
37
+ end
151
38
  end
152
39
 
153
- require 'rack/handler/iodine' unless defined? ::Iodine::Rack::IODINE_RACK_LOADED
40
+ # Trap SIGINT only if it wasn't trapped beforehand
41
+ Iodine::Base.trap_sigint
154
42
 
155
-
156
- ### Automatic ActiveRecord and Sequel support for forking (preventing connection sharing)
157
- Iodine.on_state(:before_fork) do
158
- if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:connection)
159
- begin
160
- ActiveRecord::Base.connection.disconnect!
161
- rescue
162
- end
163
- begin
164
- ActiveRecord::Base.connection_pool.disconnect!
165
- rescue
166
- end
43
+ # NeoRack Support
44
+ unless defined?(Server)
45
+ # NeoRack support requires Iodine to set the name Server to the Iodine NeoRack server module.
46
+ Server = Iodine
47
+ module Server
48
+ # NeoRack support requires Server::Event to map to the class implementing the NeoRack events.
49
+ Event = Iodine::Connection
167
50
  end
51
+ end
52
+
53
+ ### Automatic Sequel support for forking (preventing connection sharing)
54
+ Iodine.on_state(:before_fork) do
168
55
  if defined?(Sequel)
169
56
  begin
170
- Sequel::DATABASES.each { |database| database.disconnect }
171
- rescue
57
+ Sequel::DATABASES.each(&:disconnect)
58
+ rescue StandardError
172
59
  end
173
60
  end
174
- end
175
- Iodine.on_state(:after_fork) do
176
- if defined?(ActiveRecord) && defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:establish_connection)
61
+ if defined?(ActiveRecord)
177
62
  begin
178
- ActiveRecord::Base.establish_connection
179
- rescue
63
+ ActiveRecord::Base.connection_handlers.each do |handler|
64
+ handler.clear_all_connections!
65
+ end
66
+ rescue StandardError
180
67
  end
181
68
  end
182
69
  end
183
70
 
184
- ### Parse CLI for default HTTP settings
185
- Iodine::Base::CLI.parse if defined?(IODINE_PARSE_CLI) && IODINE_PARSE_CLI
186
-
187
- ### Set default port (if missing)
188
- Iodine::DEFAULT_SETTINGS[:port] ||= (ENV["PORT"] || "3000")
189
-
190
- ### Set default binding (if missing)
191
- Iodine::DEFAULT_SETTINGS[:address] ||= nil
192
-
193
- ### Initialize Redis if set in CLI
194
- Iodine::PubSub.default = Iodine::PubSub::Redis.new(Iodine::DEFAULT_SETTINGS[:redis_], ping: Iodine::DEFAULT_SETTINGS[:redis_ping_]) if Iodine::DEFAULT_SETTINGS[:redis_]
195
-
196
- ### PID file generation
197
- if Iodine::DEFAULT_SETTINGS[:pid_]
198
- pid_filename = Iodine::DEFAULT_SETTINGS[:pid_]
199
- Iodine::DEFAULT_SETTINGS.delete :pid_
200
- pid_filename << "iodine.pid" if(pid_filename[-1] == '/')
201
- if File.exist?(pid_filename)
202
- raise "pid filename shold point to a valid file name (not a folder)!" if(!File.file?(pid_filename))
203
- File.delete(pid_filename)
204
- end
205
- Iodine.on_state(:pre_start) do
206
- IO.binwrite(pid_filename, "#{Process.pid}\r\n")
207
- end
208
- Iodine.on_state(:on_finish) do
209
- File.delete(pid_filename)
210
- end
211
- end
212
-
213
- ### Puma / Thin DSL compatibility - depracated (DSLs are evil)
214
-
215
- if(!defined?(after_fork))
216
- # @deprecated use {Iodine.on_state}.
217
- #
218
- # Performs a block of code whenever a new worker process spins up (performed once per worker).
219
- def after_fork(*args, &block)
220
- warn "after_fork is deprecated, use Iodine.on_state(:after_fork)."
221
- Iodine.on_state(:after_fork, &block)
222
- end
223
- end
224
- if(!defined?(after_fork_in_worker))
225
- # @deprecated use {Iodine.on_state}.
226
- #
227
- # Performs a block of code whenever a new worker process spins up (performed once per worker).
228
- def after_fork_in_worker(*args, &block)
229
- warn "after_fork_in_worker is deprecated, use Iodine.on_state(:enter_child)."
230
- Iodine.on_state(:enter_child, &block)
231
- end
232
- end
233
- if(!defined?(after_fork_in_master))
234
- # @deprecated use {Iodine.on_state}.
235
- #
236
- # Performs a block of code whenever a new worker process spins up (performed once per worker).
237
- def after_fork_in_master(*args, &block)
238
- warn "after_fork_in_master is deprecated, use Iodine.on_state(:enter_master)."
239
- Iodine.on_state(:enter_master, &block)
240
- end
241
- end
242
- if(!defined?(on_worker_boot))
243
- # @deprecated use {Iodine.on_state}.
244
- #
245
- # Performs a block of code before a new worker process spins up (performed once per worker).
246
- def on_worker_boot(*args, &block)
247
- warn "on_worker_boot is deprecated, use Iodine.on_state(:after_fork)."
248
- Iodine.on_state(:after_fork, &block)
249
- end
250
- end
251
- if(!defined?(on_worker_fork))
252
- # @deprecated use {Iodine.on_state}.
253
- #
254
- # Performs a block of code before a new worker process spins up (performed once per worker).
255
- def on_worker_fork(*args, &block)
256
- warn "on_worker_fork is deprecated, use Iodine.on_state(:before_fork)."
257
- Iodine.on_state(:before_fork, &block)
258
- end
259
- end
260
- if(!defined?(before_fork))
261
- # @deprecated use {Iodine.on_state}.
262
- #
263
- # Performs a block of code just before a new worker process spins up (performed once per worker, in the master thread).
264
- def before_fork(*args, &block)
265
- warn "before_fork is deprecated, use Iodine.on_state(:before_fork)."
266
- Iodine.on_state(:before_fork, &block)
267
- end
268
- end
269
-
270
-
271
- #############
272
- ## At end of loading
273
-
274
- ### Load configuration filer
275
- if Iodine::DEFAULT_SETTINGS[:conf_]
276
- require Iodine::DEFAULT_SETTINGS[:conf_]
277
- Iodine::DEFAULT_SETTINGS.delete :conf_
71
+ ### Initialize RESP3 engine if set in CLI
72
+ if Iodine::Base::CLI['-r']
73
+ Iodine::PubSub.default = Iodine::PubSub::Engine::RESP3.new(
74
+ Iodine::Base::CLI['-r'],
75
+ ping: (Iodine::Base::CLI['-rp'] ? Iodine::Base::CLI['-rp'].to_i : nil)
76
+ )
278
77
  end
data/logo.svg ADDED
@@ -0,0 +1,36 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:20;">
4
+
5
+ <!-- Main Diamond Paths -->
6
+ <path d="M50,80 L10,40 L25,10 L75,10 L90,40Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
7
+ <path d="M50,80 L20,40 L35,20 L65,20 L80,40Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
8
+
9
+ <!-- Diamond Connector Lines -->
10
+ <path d="M35,20 L25,10Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
11
+ <path d="M65,20 L75,10Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
12
+ <path d="M10,40 L20,40" style="fill:none;stroke:#A24;stroke-width:1px;"/>
13
+ <path d="M90,40, L80,40Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
14
+
15
+ <path d="M28,30 L72,30Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
16
+ <path d="M30,53 L70,53Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
17
+
18
+ <!-- Circles + Connectors -->
19
+ <circle cx="5" cy="20" r="2" style="fill:none;stroke:#A24;stroke-width:1px;"/>
20
+ <path d="M28,30 L7,21Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
21
+
22
+ <circle cx="95" cy="20" r="2" style="fill:none;stroke:#A24;stroke-width:1px;"/>
23
+ <path d="M72,30 L93,21Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
24
+
25
+ <circle cx="95" cy="70" r="2" style="fill:none;stroke:#A24;stroke-width:1px;"/>
26
+ <path d="M70,53 L93,69Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
27
+
28
+ <circle cx="5" cy="70" r="2" style="fill:none;stroke:#A24;stroke-width:1px;"/>
29
+ <path d="M30,53 L7,69Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
30
+
31
+ <circle cx="50" cy="95" r="2" style="fill:none;stroke:#A24;stroke-width:1px;"/>
32
+ <path d="M50,53 L50,93Z" style="fill:none;stroke:#A24;stroke-width:1px;"/>
33
+
34
+ <!-- Iodine Name -->
35
+ <text x="50" y="42" font-family="Arial, sans-serif" font-size="17" fill="#A24" text-anchor="middle" alignment-baseline="middle" font-weight="bold">iodine</text>
36
+ </svg>
data/mustache.md ADDED
@@ -0,0 +1,55 @@
1
+ # Iodine::Mustashe
2
+
3
+ Iodine::Mustache is a lighter implementation of the mustache template rendering gem, with a focus on a few minor security details:
4
+
5
+ 1. HTML escaping is more aggressive, increasing XSS protection. Read why at: [wonko.com/post/html-escaping](https://wonko.com/post/html-escaping).
6
+
7
+ 2. Dot notation is tested in whole as well as in part (i.e. `user.name.first` will be tested as is, than the couplet `user`, `name.first` and than as each `user`, `name` , `first`), allowing for the Hash data to contain keys with dots while still supporting dot notation shortcuts.
8
+
9
+ 3. Less logic: i.e., lambdas / procs do not automatically invoke a re-rendering... I'd remove them completely as unsafe, but for now there's that.
10
+
11
+ 4. Improved Protection against Endless Recursion: i.e., Partial templates reference themselves when recursively nested (instead of being recursively re-loaded); and Partial's context is limited to their starting point's context (cannot access parent context).
12
+
13
+ It wasn't designed specifically for speed or performance... but it ended up being significantly faster.
14
+
15
+ ## Usage
16
+
17
+ This approach to Mustache templates may require more forethought when designing either the template or the context's data format, however it should force implementations to be more secure and performance aware.
18
+
19
+ Approach:
20
+
21
+ ```ruby
22
+ require 'iodine'
23
+ # One-off rendering of (possibly dynamic) template:
24
+ result = Iodine::Mustache.render(template: "{{foo}}", ctx: {foo: "bar"}) # => "bar"
25
+ # caching of parsed template data for multiple render operations:
26
+ view = Iodine::Mustache.new(file: "./views/foo.mustache", template: "{{foo}}")
27
+ results = Array.new(100) {|i| view.render(foo: "bar#{i}") } # => ["bar0", "bar1", ...]
28
+ ```
29
+
30
+ ## Performance
31
+
32
+ Performance testing requires the main Ruby `mustache` gem as well as the `benchmark-ips` gem.
33
+
34
+ Test using:
35
+
36
+ ```ruby
37
+ require 'iodine/benchmark'
38
+ Iodine::Benchmark.mustache
39
+ ```
40
+
41
+ On my machine this benchmark indicates about an x10 performance boost.
42
+
43
+ ## Contributing
44
+
45
+ Bug reports and pull requests are welcome on GitHub at https://github.com/boazsegev/iodine.
46
+
47
+ This gem is a C extension, so you will need to know C to use it.
48
+
49
+ The gem also leverages the facil.io C STL library under the hood, so things related to the facil.io library will have to go in the facil.io repo.
50
+
51
+ Good luck!
52
+
53
+ ## License
54
+
55
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/sig/iodine.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Iodine
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end