iodine 0.3.6 → 0.4.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.

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/CHANGELOG.md +46 -0
  3. data/LIMITS.md +25 -0
  4. data/README.md +39 -80
  5. data/SPEC-Websocket-Draft.md +129 -4
  6. data/bin/echo +2 -2
  7. data/bin/http-hello +1 -0
  8. data/bin/updated api +113 -0
  9. data/bin/ws-echo +0 -1
  10. data/examples/broadcast.ru +56 -0
  11. data/examples/echo.ru +57 -0
  12. data/examples/hello.ru +30 -0
  13. data/examples/redis.ru +69 -0
  14. data/examples/shootout.ru +53 -0
  15. data/exe/iodine +2 -80
  16. data/ext/iodine/defer.c +11 -5
  17. data/ext/iodine/empty.h +26 -0
  18. data/ext/iodine/evio.h +1 -1
  19. data/ext/iodine/facil.c +103 -61
  20. data/ext/iodine/facil.h +20 -12
  21. data/ext/iodine/fio_dict.c +446 -0
  22. data/ext/iodine/fio_dict.h +90 -0
  23. data/ext/iodine/fio_hash_table.h +370 -0
  24. data/ext/iodine/fio_list.h +30 -3
  25. data/ext/iodine/http.c +169 -37
  26. data/ext/iodine/http.h +33 -10
  27. data/ext/iodine/http1.c +78 -42
  28. data/ext/iodine/http_request.c +6 -0
  29. data/ext/iodine/http_request.h +3 -0
  30. data/ext/iodine/http_response.c +43 -11
  31. data/ext/iodine/iodine.c +380 -0
  32. data/ext/iodine/iodine.h +62 -0
  33. data/ext/iodine/iodine_helpers.c +235 -0
  34. data/ext/iodine/iodine_helpers.h +13 -0
  35. data/ext/iodine/iodine_http.c +409 -241
  36. data/ext/iodine/iodine_http.h +7 -14
  37. data/ext/iodine/iodine_protocol.c +626 -0
  38. data/ext/iodine/iodine_protocol.h +13 -0
  39. data/ext/iodine/iodine_pubsub.c +646 -0
  40. data/ext/iodine/iodine_pubsub.h +27 -0
  41. data/ext/iodine/iodine_websockets.c +796 -0
  42. data/ext/iodine/iodine_websockets.h +19 -0
  43. data/ext/iodine/pubsub.c +544 -0
  44. data/ext/iodine/pubsub.h +215 -0
  45. data/ext/iodine/random.c +4 -4
  46. data/ext/iodine/rb-call.c +1 -5
  47. data/ext/iodine/rb-defer.c +3 -20
  48. data/ext/iodine/rb-rack-io.c +22 -22
  49. data/ext/iodine/rb-rack-io.h +3 -4
  50. data/ext/iodine/rb-registry.c +111 -118
  51. data/ext/iodine/redis_connection.c +277 -0
  52. data/ext/iodine/redis_connection.h +77 -0
  53. data/ext/iodine/redis_engine.c +398 -0
  54. data/ext/iodine/redis_engine.h +68 -0
  55. data/ext/iodine/resp.c +842 -0
  56. data/ext/iodine/resp.h +253 -0
  57. data/ext/iodine/sock.c +26 -12
  58. data/ext/iodine/sock.h +14 -3
  59. data/ext/iodine/spnlock.inc +19 -2
  60. data/ext/iodine/websockets.c +299 -11
  61. data/ext/iodine/websockets.h +159 -6
  62. data/lib/iodine.rb +104 -1
  63. data/lib/iodine/cli.rb +106 -0
  64. data/lib/iodine/monkeypatch.rb +40 -0
  65. data/lib/iodine/pubsub.rb +70 -0
  66. data/lib/iodine/version.rb +1 -1
  67. data/lib/iodine/websocket.rb +12 -0
  68. data/lib/rack/handler/iodine.rb +33 -7
  69. metadata +35 -7
  70. data/ext/iodine/iodine_core.c +0 -760
  71. data/ext/iodine/iodine_core.h +0 -79
  72. data/ext/iodine/iodine_websocket.c +0 -551
  73. data/ext/iodine/iodine_websocket.h +0 -22
  74. data/lib/iodine/http.rb +0 -4
data/bin/echo CHANGED
@@ -33,7 +33,7 @@ class EchoProtocol
33
33
  # `on_message` has a 1Kb buffer that recycles itself for memory optimization.
34
34
  def on_message(buffer)
35
35
  # writing will never block and will use a buffer written in C when needed.
36
- write "Echo: #{buffer}"
36
+ write! "Echo: #{buffer}"
37
37
  puts buffer.dump
38
38
  close if buffer =~ /^bye[\r\n]/i
39
39
  end
@@ -41,6 +41,6 @@ end
41
41
 
42
42
  # create the server object and setup any settings we might need.
43
43
  Iodine.listen 3000, EchoProtocol
44
- # server.threads = 10
44
+ Iodine.threads = 10
45
45
  # server.processes = 1
46
46
  Iodine.start
@@ -19,6 +19,7 @@ Iodine::Rack.public = '~/Documents/Scratch'
19
19
  count = 2
20
20
  Iodine::Rack.app = proc { |_env| [200, { 'Content-Length'.freeze => '12'.freeze }, ['He11o World!'.freeze]] }
21
21
  puts Iodine::Rack.address
22
+ Iodine::HTTP.listen app: Iodine::Rack.app, port: "3030", public: '~/Documents/Scratch'
22
23
  Iodine.start
23
24
 
24
25
  # puts env.to_a.map { |pair| pair.join(': ') } .join("\n").to_s;
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
4
+ puts `rake clean`
5
+ puts `rake compile`
6
+
7
+ require 'benchmark'
8
+ $LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
9
+ require 'bundler/setup'
10
+ require 'iodine'
11
+ require 'rack'
12
+
13
+ class WSEcho
14
+ def self.call(env)
15
+ if env['upgrade.websocket?'.freeze] # && env['HTTP_UPGRADE'.freeze] =~ /websocket/i
16
+ env['upgrade.websocket'.freeze] = WSEcho
17
+ return [0, {}, []]
18
+ end
19
+ out = "ENV:\r\n#{env.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}\n"
20
+ request = Rack::Request.new(env)
21
+ out += "\nRequest Path: #{request.path_info}\nParams:\r\n#{request.params.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}\n" unless request.params.empty?
22
+ [200, { 'Content-Length' => out.length, 'Content-Type' => 'text/plain; charset=UTF-8;' }, [out]]
23
+ end
24
+
25
+ def on_open
26
+ puts 'We have a websocket connection'
27
+ Iodine::Websocket.defer(uuid) { |ws| puts "This websocket's uuid is #{ws.uuid}" }
28
+ end
29
+
30
+ def on_close
31
+ puts "Bye Bye... only #{count} left..."
32
+ end
33
+
34
+ def on_shutdown
35
+ puts "I'm shutting down #{self}"
36
+ end
37
+
38
+ def on_ready
39
+ puts "on_ready called for #{self}"
40
+ end
41
+
42
+ def on_message(data)
43
+ puts "got message: #{data}"
44
+ write data
45
+ write (data * 16_384) if data =~ /^multi me$/
46
+ end
47
+
48
+ def echo(data)
49
+ write "echo: #{data}"
50
+ end
51
+ end
52
+
53
+ # create the server object and setup any settings we might need.
54
+ Iodine.threads ||= 4
55
+ Iodine.processes ||= 1
56
+ count = 2
57
+
58
+ Iodine::HTTP.listen app: WSEcho, log: true, port: 3000
59
+ Iodine.start
60
+ # server.on_http= Proc.new do |env|
61
+ # # [200, {"Content-Length".freeze => "12".freeze}, ["Hello World!".freeze]];
62
+ # if env["HTTP_UPGRADE".freeze] =~ /websocket/i.freeze
63
+ # env['iodine.websocket'.freeze] = WSEcho.new
64
+ # [0,{}, []]
65
+ # else
66
+ # req = Rack::Request.new env
67
+ # res = Rack::Response.new
68
+ # res.write "Hello World!".freeze
69
+ # res.to_a
70
+ # end
71
+ # end
72
+
73
+ # server.on_start do
74
+ # server.run_every(1000) {puts "#{server.connection_count} clients connected."}
75
+ # end
76
+
77
+ # puts "Press enter to start (#{Process.pid})"
78
+ # gets
79
+
80
+ # def nag
81
+ # puts `ab -n 200000 -c 2000 -k http://127.0.0.1:3000/`
82
+ # sleep 2
83
+ # end
84
+ #
85
+ # nag while true
86
+ #
87
+ # def nag
88
+ # puts `wrk -c2000 -d10 -t4 http://localhost:3000/`
89
+ # sleep 3
90
+ # end
91
+ #
92
+ # nag while true
93
+
94
+ # ab -n 100000 -c 200 -k http://127.0.0.1:3000/
95
+ # ab -n 100000 -c 4000 -k http://127.0.0.1:3000/
96
+ # ab -n 1000000 -c 20000 -k http://127.0.0.1:3000/
97
+ # ~/ruby/wrk/wrk -c400 -d10 -t12 http://localhost:3000/
98
+ # wrk -c200 -d4 -t12 http://localhost:3000/
99
+ # ab -n 2000 -c 20 -H "Connection: close" http://127.0.0.1:3000/
100
+ # RACK_ENV="production" rackup -p 3000 -s iodine
101
+
102
+ # thor --amount 5000 ws://localhost:3000/echo
103
+ # thor --amount 5000 ws://localhost:3000/broadcast
104
+
105
+ # ws = new WebSocket("ws://localhost:3000"); ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data);}; ws.onclose = function(e) {console.log("closed")}; ws.onopen = function(e) {ws.send("hi");};
106
+ # for(i = 0; i< 256; i++) {
107
+ # ws = new WebSocket("ws://localhost:3000");
108
+ # ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data); e.target.close(); };
109
+ # ws.onclose = function(e) {console.log("closed")};
110
+ # ws.onopen = function(e) {e.target.send("hi");};
111
+ # };
112
+ # ws = new WebSocket("ws://localhost:3000"); ws.onmessage = function(e) {console.log("Got message " + e.data.length + " bytes long"); for(var i = 0; i < e.data.length ; i += 4) {if (e.data.slice(i, i+4) != "text") {console.log( "incoming message corrupted? ", e.data.slice(i, i+4) ); return;};}; }; ws.onclose = function(e) {console.log("closed")}; ws.onopen = function(e) {ws.send("hi");};
113
+ # str = "text"; function size_test() { if(ws.readyState != 1) return; if(str.length > 4194304) {console.log("str reached 4MiB!"); str = "test"; return;}; ws.send(str); str = str + str; window.setTimeout(size_test, 150); }; size_test();
@@ -58,7 +58,6 @@ Iodine::Rack.log = 1
58
58
  count = 2
59
59
  Iodine::Rack.app = WSEcho
60
60
  Iodine.start
61
-
62
61
  # server.on_http= Proc.new do |env|
63
62
  # # [200, {"Content-Length".freeze => "12".freeze}, ["Hello World!".freeze]];
64
63
  # if env["HTTP_UPGRADE".freeze] =~ /websocket/i.freeze
@@ -0,0 +1,56 @@
1
+ # This is a Websocket echo application.
2
+ #
3
+ # Running this application from the command line is eacy with:
4
+ #
5
+ # iodine hello.ru
6
+ #
7
+ # Or, in single thread and single process:
8
+ #
9
+ # iodine -t 1 -w 1 hello.ru
10
+ #
11
+ # Benchmark with `ab` or `wrk` (a 5 seconds benchmark with 2000 concurrent clients):
12
+ #
13
+ # ab -c 2000 -t 5 -n 1000000 -k http://127.0.0.1:3000/
14
+ # wrk -c2000 -d5 -t12 http://localhost:3000/
15
+
16
+
17
+ # A simple router - Checks for Websocket Upgrade and answers HTTP.
18
+ module MyHTTPRouter
19
+ # This is the HTTP response object according to the Rack specification.
20
+ HTTP_RESPONSE = [200, { 'Content-Type' => 'text/html',
21
+ 'Content-Length' => '32' },
22
+ ['Please connect using websockets.']]
23
+
24
+ WS_RESPONSE = [0, {}, []].freeze
25
+
26
+ # this is function will be called by the Rack server (iodine) for every request.
27
+ def self.call env
28
+ # check if this is an upgrade request.
29
+ if(env['upgrade.websocket?'.freeze])
30
+ env['upgrade.websocket'.freeze] = WebsocketBroadcast
31
+ return WS_RESPONSE
32
+ end
33
+ # simply return the RESPONSE object, no matter what request was received.
34
+ HTTP_RESPONSE
35
+ end
36
+ end
37
+
38
+ # A simple Websocket Callback Object.
39
+ class WebsocketBroadcast
40
+ # seng a message to new clients.
41
+ def on_open
42
+ puts self
43
+ write "Welcome to our echo service!"
44
+ end
45
+ # send a message, letting the client know the server is suggunt down.
46
+ def on_shutdown
47
+ write "Server shutting down. Goodbye."
48
+ end
49
+ # perform the echo
50
+ def on_message data
51
+ write data
52
+ end
53
+ end
54
+
55
+ # this function call links our HelloWorld application with Rack
56
+ run MyHTTPRouter
@@ -0,0 +1,57 @@
1
+ # This is a Websocket echo application.
2
+ #
3
+ # Running this application from the command line is eacy with:
4
+ #
5
+ # iodine hello.ru
6
+ #
7
+ # Or, in single thread and single process:
8
+ #
9
+ # iodine -t 1 -w 1 hello.ru
10
+ #
11
+ # Benchmark with `ab` or `wrk` (a 5 seconds benchmark with 2000 concurrent clients):
12
+ #
13
+ # ab -c 2000 -t 5 -n 1000000 -k http://127.0.0.1:3000/
14
+ # wrk -c2000 -d5 -t12 http://localhost:3000/
15
+
16
+
17
+ # A simple router - Checks for Websocket Upgrade and answers HTTP.
18
+ module MyHTTPRouter
19
+ # This is the HTTP response object according to the Rack specification.
20
+ HTTP_RESPONSE = [200, { 'Content-Type' => 'text/html',
21
+ 'Content-Length' => '32' },
22
+ ['Please connect using websockets.']]
23
+
24
+ WS_RESPONSE = [0, {}, []].freeze
25
+
26
+ # this is function will be called by the Rack server (iodine) for every request.
27
+ def self.call env
28
+ # check if this is an upgrade request.
29
+ if(env['upgrade.websocket?'.freeze])
30
+ env['upgrade.websocket'.freeze] = WebsocketEcho
31
+ return [0, {}, []]
32
+ return WS_RESPONSE
33
+ end
34
+ # simply return the RESPONSE object, no matter what request was received.
35
+ HTTP_RESPONSE
36
+ end
37
+ end
38
+
39
+ # A simple Websocket Callback Object.
40
+ class WebsocketEcho
41
+ # seng a message to new clients.
42
+ def on_open
43
+ p self
44
+ write "Welcome to our echo service!"
45
+ end
46
+ # send a message, letting the client know the server is suggunt down.
47
+ def on_shutdown
48
+ write "Server shutting down. Goodbye."
49
+ end
50
+ # perform the echo
51
+ def on_message data
52
+ write data
53
+ end
54
+ end
55
+
56
+ # this function call links our HelloWorld application with Rack
57
+ run MyHTTPRouter
@@ -0,0 +1,30 @@
1
+ # This is a simple Hello World Rack application
2
+ #
3
+ # Running this application from the command line is eacy with:
4
+ #
5
+ # iodine hello.ru
6
+ #
7
+ # Or, in single thread and single process:
8
+ #
9
+ # iodine -t 1 -w 1 hello.ru
10
+ #
11
+ # Benchmark with `ab` or `wrk` (a 5 seconds benchmark with 2000 concurrent clients):
12
+ #
13
+ # ab -c 2000 -t 5 -n 1000000 -k http://127.0.0.1:3000/
14
+ # wrk -c2000 -d5 -t12 http://localhost:3000/
15
+
16
+ module HelloWorld
17
+ # This is the HTTP response object according to the Rack specification.
18
+ RESPONSE = [200, { 'Content-Type' => 'text/html',
19
+ 'Content-Length' => '32' },
20
+ ['Please connect using websockets.']]
21
+
22
+ # this is function will be called by the Rack server (iodine) for every request.
23
+ def self.call env
24
+ # simply return the RESPONSE object, no matter what request was received.
25
+ RESPONSE
26
+ end
27
+ end
28
+
29
+ # this function call links our HelloWorld application with Rack
30
+ run HelloWorld
@@ -0,0 +1,69 @@
1
+ # This example implements a Redis pub/sub engine according to the Iodine::PubSub::Engine specifications.
2
+ #
3
+ # The engine code is locates at examples/redis_pubsub.rb and it requires the hiredis gem.
4
+ #
5
+ # Run this applications on two ports, in two terminals to see the synchronization is action
6
+ #
7
+ # REDIS_URL=redis://localhost:6379/0 iodine -t 1 -p 3000 redis.ru
8
+ # REDIS_URL=redis://localhost:6379/0 iodine -t 1 -p 3030 redis.ru
9
+ #
10
+ require 'uri'
11
+ # initialize the Redis engine for each Iodine process by using `Iodine.run`
12
+ if ENV["REDIS_URL"]
13
+ uri = URI(ENV["REDIS_URL"])
14
+ Iodine.default_pubsub = Iodine::PubSub::RedisEngine.new(uri.host, uri.port, 0, uri.password)
15
+ else
16
+ puts "* No Redis! pub/sub is limited to the process cluster."
17
+ end
18
+ puts "The default Pub/Sub engine is:", Iodine.default_pubsub
19
+
20
+ # A simple router - Checks for Websocket Upgrade and answers HTTP.
21
+ module MyHTTPRouter
22
+ # This is the HTTP response object according to the Rack specification.
23
+ HTTP_RESPONSE = [200, { 'Content-Type' => 'text/html',
24
+ 'Content-Length' => '32' },
25
+ ['Please connect using websockets.']]
26
+
27
+ WS_RESPONSE = [0, {}, []]
28
+
29
+ # this is function will be called by the Rack server (iodine) for every request.
30
+ def self.call env
31
+ # check if this is an upgrade request.
32
+ if(env['upgrade.websocket?'.freeze])
33
+ env['upgrade.websocket'.freeze] = WS_RedisPubSub.new(env['PATH_INFO'] ? env['PATH_INFO'][1..-1] : "guest")
34
+ return [0, {}, []]
35
+ return WS_RESPONSE
36
+ end
37
+ # simply return the RESPONSE object, no matter what request was received.
38
+ HTTP_RESPONSE
39
+ end
40
+ end
41
+
42
+ # A simple Websocket Callback Object.
43
+ class WS_RedisPubSub
44
+ def initialize name
45
+ @name = name
46
+ end
47
+ # seng a message to new clients.
48
+ def on_open
49
+ subscribe channel: "chat"
50
+ # let everyone know we arrived
51
+ # publish channel: "chat", message: "#{@name} entered the chat."
52
+ end
53
+ # send a message, letting the client know the server is suggunt down.
54
+ def on_shutdown
55
+ write "Server shutting down. Goodbye."
56
+ end
57
+ # perform the echo
58
+ def on_message data
59
+ publish channel: "chat", message: "#{@name}: #{data}"
60
+ end
61
+ def on_close
62
+ # let everyone know we left
63
+ publish channel: "chat", message: "#{@name} left the chat."
64
+ # we don't need to unsubscribe, subscriptions are cleared automatically once the connection is closed.
65
+ end
66
+ end
67
+
68
+ # this function call links our HelloWorld application with Rack
69
+ run MyHTTPRouter
@@ -0,0 +1,53 @@
1
+ require 'iodine'
2
+
3
+ # ON_IDLE = proc { Iodine::Base.db_print_registry ; Iodine.on_idle(&ON_IDLE) }
4
+ # ON_IDLE.call
5
+
6
+ class ShootoutApp
7
+ # the default HTTP response
8
+ def self.call(env)
9
+ if env['upgrade.websocket?'.freeze] # && env['HTTP_UPGRADE'.freeze] =~ /websocket/i
10
+ env['upgrade.websocket'.freeze] = ShootoutApp.new
11
+ return [0, {}, []]
12
+ end
13
+ out = "ENV:\r\n#{env.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}\n"
14
+ request = Rack::Request.new(env)
15
+ out += "\nRequest Path: #{request.path_info}\nParams:\r\n#{request.params.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}\n" unless request.params.empty?
16
+ [200, { 'Content-Length' => out.length, 'Content-Type' => 'text/plain; charset=UTF-8;' }, [out]]
17
+ end
18
+ # We'll base the shootout on the internal Pub/Sub service.
19
+ # It's slower than writing to every socket a pre-parsed message, but it's closer
20
+ # to real-life implementations.
21
+ def on_open
22
+ subscribe channel: "shootout"
23
+ end
24
+ def on_message data
25
+ if data[0] == 'b' # binary
26
+ publish(channel: "shootout", message: data)
27
+ data[0] = 'r'
28
+ write data
29
+ return
30
+ end
31
+ cmd, payload = JSON(data).values_at('type', 'payload')
32
+ if cmd == 'echo'
33
+ write({type: 'echo', payload: payload}.to_json)
34
+ else
35
+ # data = {type: 'broadcast', payload: payload}.to_json
36
+ # broadcast :push2client, data
37
+ publish(channel: "shootout", message: ({type: 'broadcast', payload: payload}.to_json))
38
+ write({type: "broadcastResult", payload: payload}.to_json)
39
+ end
40
+ rescue
41
+ puts "Incoming message format error - not JSON?"
42
+ end
43
+ end
44
+
45
+ run ShootoutApp
46
+ #
47
+ # def cycle
48
+ # puts `websocket-bench broadcast ws://127.0.0.1:3000/ --concurrent 10 --sample-size 100 --server-type binary --step-size 1000 --limit-percentile 95 --limit-rtt 250ms --initial-clients 1000`
49
+ # sleep(2)
50
+ # puts `wrk -c4000 -d15 -t12 http://localhost:3000/`
51
+ # true
52
+ # end
53
+ # sleep(10) while cycle
data/exe/iodine CHANGED
@@ -1,83 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'iodine'
4
- require 'rack'
3
+ require 'iodine/cli'
5
4
 
6
- if ARGV[0] =~ /(\-\?)|(help)|(\?)$/
7
- puts <<-EOS
8
-
9
- Iodine's HTTP/Websocket server version #{Iodine::VERSION}
10
-
11
- Use:
12
-
13
- iodine <options> <filename>
14
-
15
- Both <options> and <filename> are optional.
16
-
17
- Available options:
18
- -p Port number. Default: 3000.
19
- -t Number of threads. Default: half of the CPU core count.
20
- -w Number of worker processes. half of the CPU core count.
21
- -www Public folder for static file serving. Default: nil (none).
22
- -v Log responses.
23
- -q Never log responses.
24
- -warmup Warmup invokes autoloading (lazy loading) during server startup.
25
- -tout HTTP inactivity connection timeout. Default: 5.
26
- -maxbd Maximum Mb per HTTP message (max body size). Default: 50Mib.
27
- -maxms Maximum Bytes per Websocket message. Default: 250Kib.
28
- -ping Websocket ping interval in seconds. Default: 40 seconds.
29
- <filename> Defaults to: config.ru
30
-
31
- Example:
32
-
33
- iodine -p 80
34
-
35
- iodine -p 8080 path/to/app/conf.ru
36
-
37
- iodine -p 8080 -w 4 -t 16
38
-
39
- EOS
40
- exit(0)
41
- end
42
-
43
- app, opt = nil, nil
44
- filename = (ARGV[-2].to_s[0] != '-' && ARGV[-1].to_s[0] != '-' && ARGV[-1]) || 'config.ru'
45
-
46
- begin
47
- app, opt = Rack::Builder.parse_file filename
48
- rescue
49
- if ARGV.index('-www') && ARGV[ARGV.index('-www') + 1]
50
- puts "WARNING: Ruby application not found - missing #{filename}?"
51
- puts " Running only static file service."
52
- app = Rack::Builder.new do
53
- run lambda { |env| [404, {'Content-Type' => 'text/plain', 'Content-Length'.freeze => '21'.freeze}, ['Error 404 - Not Found']] }
54
- end
55
- opt = Rack::Server::Options.new.parse!([])
56
- p app, opt
57
- else
58
- puts "ERROR: Ruby application not found - missing #{filename}? For help run:"
59
- puts " iodine -?"
60
- exit(0)
61
- end
62
- end
63
-
64
- if ARGV.index('-maxbd') && ARGV[ARGV.index('-maxbd') + 1]
65
- Iodine::Rack.max_body_size = ARGV[ARGV.index('-maxbd') + 1].to_i
66
- end
67
- if ARGV.index('-maxms') && ARGV[ARGV.index('-maxms') + 1]
68
- Iodine::Rack.max_msg_size = ARGV[ARGV.index('-maxms') + 1].to_i
69
- end
70
- if ARGV.index('-ping') && ARGV[ARGV.index('-ping') + 1]
71
- Iodine::Rack.ws_timeout = ARGV[ARGV.index('-ping') + 1].to_i
72
- end
73
- if ARGV.index('-www') && ARGV[ARGV.index('-www') + 1]
74
- Iodine::Rack.public = ARGV[ARGV.index('-www') + 1]
75
- end
76
- if ARGV.index('-tout') && ARGV[ARGV.index('-tout') + 1]
77
- Iodine::Rack.timeout = ARGV[ARGV.index('-tout') + 1].to_i
78
- puts "WARNNING: Iodine::Rack.timeout set to 0 (ignored, timeout will be ~5 minutes)."
79
- end
80
- Iodine::Rack.log = true if ARGV.index('-v')
81
- Iodine::Rack.log = false if ARGV.index('-q')
82
- Iodine.warmup if ARGV.index('-warmup')
83
- Iodine::Rack.run(app, opt)
5
+ Iodine::Base::CLI.call