nitro 0.27.0 → 0.28.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.
- data/CHANGELOG +276 -0
- data/ProjectInfo +4 -4
- data/README +9 -1
- data/Rakefile +1 -1
- data/doc/AUTHORS +30 -17
- data/doc/RELEASES +110 -23
- data/lib/glue/sweeper.rb +1 -1
- data/lib/glue/webfile.rb +1 -1
- data/lib/nitro.rb +1 -1
- data/lib/nitro/adapter/acgi.rb +5 -1
- data/lib/nitro/adapter/cgi.rb +4 -0
- data/lib/nitro/adapter/fastcgi.rb +12 -1
- data/lib/nitro/adapter/mongrel.rb +219 -0
- data/lib/nitro/adapter/scgi.rb +62 -69
- data/lib/nitro/caching.rb +6 -5
- data/lib/nitro/caching/actions.rb +14 -8
- data/lib/nitro/caching/fragments.rb +32 -17
- data/lib/nitro/caching/output.rb +10 -2
- data/lib/nitro/cgi.rb +7 -3
- data/lib/nitro/cgi/stream.rb +1 -3
- data/lib/nitro/compiler.rb +5 -4
- data/lib/nitro/compiler/errors.rb +1 -1
- data/lib/nitro/compiler/morphing.rb +2 -2
- data/lib/nitro/compiler/script.rb +1 -1
- data/lib/nitro/context.rb +8 -2
- data/lib/nitro/controller.rb +1 -1
- data/lib/nitro/dispatcher.rb +0 -2
- data/lib/nitro/element.rb +5 -5
- data/lib/nitro/flash.rb +1 -1
- data/lib/nitro/helper.rb +2 -2
- data/lib/nitro/helper/form.rb +1 -1
- data/lib/nitro/helper/form/controls.rb +2 -1
- data/lib/nitro/helper/javascript.rb +1 -1
- data/lib/nitro/helper/javascript/morphing.rb +1 -1
- data/lib/nitro/helper/layout.rb +1 -1
- data/lib/nitro/helper/pager.rb +7 -3
- data/lib/nitro/helper/rss.rb +1 -1
- data/lib/nitro/render.rb +1 -1
- data/lib/nitro/scaffolding.rb +26 -4
- data/lib/nitro/server/drb.rb +106 -0
- data/lib/nitro/server/runner.rb +23 -2
- data/lib/nitro/session.rb +33 -16
- data/lib/nitro/session/drb.rb +6 -20
- data/lib/nitro/session/file.rb +4 -49
- data/lib/nitro/session/memory.rb +16 -0
- data/lib/nitro/session/og.rb +4 -46
- data/src/part/admin/controller.rb +2 -3
- data/src/part/admin/template/index.xhtml +1 -1
- data/test/nitro/tc_cgi.rb +72 -3
- data/test/nitro/tc_render.rb +1 -1
- data/test/nitro/tc_session.rb +16 -15
- metadata +12 -14
- data/lib/nitro/caching/invalidation.rb +0 -25
- data/lib/nitro/caching/stores.rb +0 -94
- data/lib/nitro/helper/form/test.xhtml +0 -0
- data/lib/nitro/session/drbserver.rb +0 -84
data/lib/glue/sweeper.rb
CHANGED
|
@@ -60,7 +60,7 @@ private
|
|
|
60
60
|
# Expire affected cached fragments.
|
|
61
61
|
|
|
62
62
|
def expire_affected_fragment(name, options = {})
|
|
63
|
-
Nitro::Caching::Fragments.
|
|
63
|
+
Nitro::Caching::Fragments.cache.delete(name, options)
|
|
64
64
|
end
|
|
65
65
|
alias_method :expire_fragment, :expire_affected_fragment
|
|
66
66
|
|
data/lib/glue/webfile.rb
CHANGED
data/lib/nitro.rb
CHANGED
data/lib/nitro/adapter/acgi.rb
CHANGED
|
@@ -14,6 +14,10 @@ require 'glue/flexob'
|
|
|
14
14
|
|
|
15
15
|
Socket.do_not_reverse_lookup = true
|
|
16
16
|
|
|
17
|
+
# No multi-threading.
|
|
18
|
+
|
|
19
|
+
Og.thread_safe = false
|
|
20
|
+
|
|
17
21
|
module Nitro
|
|
18
22
|
|
|
19
23
|
# ACGI Adaptor. ACGI is a language independent,
|
|
@@ -33,7 +37,7 @@ module Nitro
|
|
|
33
37
|
# instead of fcgi.rb / cgi.rb
|
|
34
38
|
#
|
|
35
39
|
#--
|
|
36
|
-
# gmosx: not tested
|
|
40
|
+
# gmosx: not tested! Use at your own risk!
|
|
37
41
|
#++
|
|
38
42
|
|
|
39
43
|
class ACGI < ::CGI
|
data/lib/nitro/adapter/cgi.rb
CHANGED
|
@@ -11,6 +11,10 @@ require 'glue/flexob'
|
|
|
11
11
|
|
|
12
12
|
Socket.do_not_reverse_lookup = true
|
|
13
13
|
|
|
14
|
+
# No multi-threading.
|
|
15
|
+
|
|
16
|
+
Og.thread_safe = false
|
|
17
|
+
|
|
14
18
|
module Nitro
|
|
15
19
|
|
|
16
20
|
# FastCGI Adaptor. FastCGI is a language independent,
|
|
@@ -18,7 +22,12 @@ module Nitro
|
|
|
18
22
|
# performance without the limitations of server
|
|
19
23
|
# specific APIs.
|
|
20
24
|
#
|
|
21
|
-
#
|
|
25
|
+
# === Sessions
|
|
26
|
+
#
|
|
27
|
+
# As FCGI is process based, you have cant use the default
|
|
28
|
+
# in-memory session store. For production web sites you should
|
|
29
|
+
# use the drb session store. Moreover, there is no need for
|
|
30
|
+
# DB connection pooling in Og.
|
|
22
31
|
|
|
23
32
|
class FastCGI
|
|
24
33
|
|
|
@@ -34,3 +43,5 @@ class FastCGI
|
|
|
34
43
|
end
|
|
35
44
|
|
|
36
45
|
end
|
|
46
|
+
|
|
47
|
+
# * George Moschovitis <gm@navel.gr>
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
require 'stringio'
|
|
2
|
+
|
|
3
|
+
require 'mongrel'
|
|
4
|
+
|
|
5
|
+
require 'glue/flexob'
|
|
6
|
+
require 'nitro/cgi'
|
|
7
|
+
require 'nitro/context'
|
|
8
|
+
require 'nitro/dispatcher'
|
|
9
|
+
|
|
10
|
+
# Speeds things up, more comaptible with OSX.
|
|
11
|
+
|
|
12
|
+
Socket.do_not_reverse_lookup = true
|
|
13
|
+
|
|
14
|
+
#--
|
|
15
|
+
# Fix for Nitro.
|
|
16
|
+
#++
|
|
17
|
+
|
|
18
|
+
module Mongrel # :nodoc: all
|
|
19
|
+
class HttpRequest
|
|
20
|
+
def method_missing(name, *args)
|
|
21
|
+
if @params.has_key?(name.to_s.upcase)
|
|
22
|
+
return @params[name.to_s.upcase]
|
|
23
|
+
elsif name.to_s =~ /\A(.*)=\Z/ && @params.has_key?($1.upcase)
|
|
24
|
+
@params[$1.upcase] = args[0]
|
|
25
|
+
else
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
module Nitro
|
|
34
|
+
|
|
35
|
+
class Mongrel
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
attr_accessor :mongrel
|
|
39
|
+
|
|
40
|
+
# Start the Webrick adapter.
|
|
41
|
+
|
|
42
|
+
def start(server)
|
|
43
|
+
# TODO add logging.
|
|
44
|
+
|
|
45
|
+
mongrel_options = server.options.dup
|
|
46
|
+
|
|
47
|
+
mongrel_options.update(
|
|
48
|
+
:BindAddress => server.address,
|
|
49
|
+
:Port => server.port,
|
|
50
|
+
:DocumentRoot => server.public_root
|
|
51
|
+
)
|
|
52
|
+
@mongrel = ::Mongrel::HttpServer.new(mongrel_options[:BindAddress],
|
|
53
|
+
mongrel_options[:Port])
|
|
54
|
+
|
|
55
|
+
trap('INT') { stop } # will this work?
|
|
56
|
+
|
|
57
|
+
@mongrel.register('/', MongrelAdapter.new(server))
|
|
58
|
+
|
|
59
|
+
initialize_mongrel(server)
|
|
60
|
+
|
|
61
|
+
@mongrel_thread = @mongrel.run
|
|
62
|
+
@mongrel_thread.join
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Stop the Mongrel adapter.
|
|
66
|
+
|
|
67
|
+
def stop
|
|
68
|
+
@mongrel_thread.kill
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Override this method to perform customized mongrel
|
|
72
|
+
# initialization.
|
|
73
|
+
|
|
74
|
+
def initialize_mongrel(server)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# A special handler for Xhtml files.
|
|
82
|
+
|
|
83
|
+
#class XhtmlFileHandler < WEBrick::HTTPServlet::DefaultFileHandler
|
|
84
|
+
# def do_GET(req, res)
|
|
85
|
+
# res['content-type'] = 'text/html'
|
|
86
|
+
# res.body = '<html><body>Permission denied</body></html>'
|
|
87
|
+
# end
|
|
88
|
+
#end
|
|
89
|
+
|
|
90
|
+
# A Mongrel Adapter for Nitro.
|
|
91
|
+
|
|
92
|
+
class MongrelAdapter < ::Mongrel::HttpHandler
|
|
93
|
+
attr_accessor :server
|
|
94
|
+
|
|
95
|
+
STATUS_CODES = {
|
|
96
|
+
200 => "OK", "304" => "Not Modified",
|
|
97
|
+
"404" => "Not found", "500" => "Server Error"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
def initialize(server)
|
|
101
|
+
@server = server
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def process(req, res)
|
|
105
|
+
handle(req, res)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Handle a static file. Also handles cached pages.
|
|
109
|
+
|
|
110
|
+
def handle_file(req, res)
|
|
111
|
+
begin
|
|
112
|
+
rewrite(req)
|
|
113
|
+
# TODO handle If-Modified-Since and add Last-Modified headers
|
|
114
|
+
filename = [@server.public_root, req.path_info].join("/")
|
|
115
|
+
File.open(filename, "r") { |f|
|
|
116
|
+
# TODO look up mime type
|
|
117
|
+
# TODO check whether path circumvents public_root directory?
|
|
118
|
+
size = File.size(filename)
|
|
119
|
+
res.socket << "HTTP/1.1 200 OK\r\n"
|
|
120
|
+
res.socket << "Content-type: text/plain\r\n"
|
|
121
|
+
res.socket << "Content-length: #{size}\r\n"
|
|
122
|
+
res.socket << "\r\n"
|
|
123
|
+
res.socket << f.read # XXX inefficient for large files, may cause leaks
|
|
124
|
+
}
|
|
125
|
+
return true
|
|
126
|
+
rescue Object => ex
|
|
127
|
+
return false
|
|
128
|
+
ensure
|
|
129
|
+
unrewrite(req)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Handle the request.
|
|
134
|
+
|
|
135
|
+
def handle(req, res)
|
|
136
|
+
unless handle_file(req, res)
|
|
137
|
+
path = req.path_info
|
|
138
|
+
|
|
139
|
+
unless path =~ /\./
|
|
140
|
+
begin
|
|
141
|
+
context = Context.new(@server)
|
|
142
|
+
|
|
143
|
+
context.in = StringIO.new(req.body || "")
|
|
144
|
+
|
|
145
|
+
context.headers = {}
|
|
146
|
+
req.params.each { |h, v|
|
|
147
|
+
if h =~ /\AHTTP_(.*)\Z/
|
|
148
|
+
context.headers[$1.gsub("_", "-")] = v
|
|
149
|
+
end
|
|
150
|
+
context.headers[h] = v
|
|
151
|
+
}
|
|
152
|
+
# context.headers.update(req.meta_vars)
|
|
153
|
+
|
|
154
|
+
context.headers['REQUEST_URI'] = context.headers['SCRIPT_NAME']
|
|
155
|
+
|
|
156
|
+
if context.headers['PATH_INFO'].blank?
|
|
157
|
+
context.headers['REQUEST_URI'] = '/'
|
|
158
|
+
else
|
|
159
|
+
context.headers['REQUEST_URI'] = '/' + context.headers['PATH_INFO']
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# gmosx: make compatible with fastcgi.
|
|
163
|
+
#context.headers['REQUEST_URI'].slice!(/http:\/\/(.*?)\//)
|
|
164
|
+
# context.headers['REQUEST_URI'] << '/'
|
|
165
|
+
|
|
166
|
+
Cgi.parse_params(context)
|
|
167
|
+
Cgi.parse_cookies(context)
|
|
168
|
+
|
|
169
|
+
context.render(path)
|
|
170
|
+
|
|
171
|
+
res.socket << "HTTP/1.1 #{context.status.to_s} "
|
|
172
|
+
|
|
173
|
+
if STATUS_CODES.has_key? context.status
|
|
174
|
+
res.socket << STATUS_CODES[context.status]
|
|
175
|
+
else
|
|
176
|
+
res.socket << "Unknown Status Code"
|
|
177
|
+
end
|
|
178
|
+
res.socket << "\r\n"
|
|
179
|
+
|
|
180
|
+
headers = context.response_headers
|
|
181
|
+
headers["Content-length"] = context.out.size
|
|
182
|
+
headers.each { |h,v| res.socket << "#{h}: #{v}\r\n" }
|
|
183
|
+
res.socket << "\r\n"
|
|
184
|
+
|
|
185
|
+
# TODO handle setting cookies
|
|
186
|
+
res.socket << context.out
|
|
187
|
+
|
|
188
|
+
context.close
|
|
189
|
+
ensure
|
|
190
|
+
Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def rewrite(req)
|
|
197
|
+
if req.path_info == '/' || req.path_info == ''
|
|
198
|
+
req.path_info = '/index.html'
|
|
199
|
+
elsif req.path_info =~ /^([^.]+)$/
|
|
200
|
+
req.path_info = "#{$1}/index.html"
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Rewrite back to the original path.
|
|
205
|
+
|
|
206
|
+
def unrewrite(req)
|
|
207
|
+
if req.path_info == '/index.html'
|
|
208
|
+
req.path_info = '/'
|
|
209
|
+
elsif req.path_info =~ /^([^.]+)\/index.html$/
|
|
210
|
+
req.path_info = $1
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# * Joshua Hoke
|
|
218
|
+
# * George Moschovitis <gm@navel.gr>
|
|
219
|
+
|
data/lib/nitro/adapter/scgi.rb
CHANGED
|
@@ -10,57 +10,6 @@ require 'singleton'
|
|
|
10
10
|
|
|
11
11
|
module SCGI # :nodoc: all
|
|
12
12
|
|
|
13
|
-
class LogFactory < Monitor
|
|
14
|
-
include Singleton
|
|
15
|
-
|
|
16
|
-
def initialize
|
|
17
|
-
super()
|
|
18
|
-
@@logs = {}
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def create(file)
|
|
22
|
-
result = nil
|
|
23
|
-
synchronize do
|
|
24
|
-
result = @@logs[file]
|
|
25
|
-
if not result
|
|
26
|
-
result = Log.new(file)
|
|
27
|
-
@@logs[file] = result
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
return result
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class Log < Monitor
|
|
35
|
-
def initialize(file)
|
|
36
|
-
super()
|
|
37
|
-
@out = open(file, "a+")
|
|
38
|
-
@out.sync = true
|
|
39
|
-
@pid = Process.pid
|
|
40
|
-
@info = "[INF][#{Process.pid}] "
|
|
41
|
-
@error = "[ERR][#{Process.pid}] "
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def info(msg)
|
|
45
|
-
synchronize do
|
|
46
|
-
@out.print @info, msg,"\n"
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def error(msg, exc=nil)
|
|
51
|
-
if exc
|
|
52
|
-
synchronize do
|
|
53
|
-
@out.print @error, "#{msg}: #{exc}\n"
|
|
54
|
-
@out.print @error, exc.backtrace.join("\n"), "\n"
|
|
55
|
-
end
|
|
56
|
-
else
|
|
57
|
-
synchronize do
|
|
58
|
-
@out.print @error, msg,"\n"
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
13
|
# Modifies CGI so that we can use it.
|
|
65
14
|
class SCGIFixed < ::CGI # :nodoc: all
|
|
66
15
|
public :env_table
|
|
@@ -78,6 +27,8 @@ module SCGI # :nodoc: all
|
|
|
78
27
|
def env_table
|
|
79
28
|
@env_table
|
|
80
29
|
end
|
|
30
|
+
alias_method :env, :env_table
|
|
31
|
+
|
|
81
32
|
def stdinput
|
|
82
33
|
@input
|
|
83
34
|
end
|
|
@@ -86,14 +37,14 @@ module SCGI # :nodoc: all
|
|
|
86
37
|
end
|
|
87
38
|
end
|
|
88
39
|
|
|
89
|
-
|
|
90
40
|
class SCGIProcessor < Monitor # :nodoc: all
|
|
91
41
|
attr_reader :settings
|
|
92
42
|
|
|
93
|
-
def initialize(settings = {})
|
|
43
|
+
def initialize(server, settings = {})
|
|
94
44
|
@conns = 0
|
|
95
45
|
@shutdown = false
|
|
96
46
|
@dead = false
|
|
47
|
+
@server = server
|
|
97
48
|
super()
|
|
98
49
|
|
|
99
50
|
configure(settings)
|
|
@@ -101,15 +52,18 @@ module SCGI # :nodoc: all
|
|
|
101
52
|
|
|
102
53
|
def configure(settings)
|
|
103
54
|
@settings = settings
|
|
104
|
-
|
|
105
|
-
@
|
|
55
|
+
#@log = LogFactory.instance.create(settings[:logfile])
|
|
56
|
+
@log = Logger
|
|
57
|
+
@log = Logger.new(settings[:logfile]) if settings[:logfile]
|
|
58
|
+
|
|
59
|
+
@maxconns = settings[:maxconns]
|
|
106
60
|
@started = Time.now
|
|
107
61
|
|
|
108
62
|
if settings[:socket]
|
|
109
63
|
@socket = settings[:socket]
|
|
110
64
|
else
|
|
111
|
-
@host = settings[:host]
|
|
112
|
-
@port = settings[:port]
|
|
65
|
+
@host = settings[:host]
|
|
66
|
+
@port = settings[:port]
|
|
113
67
|
end
|
|
114
68
|
|
|
115
69
|
@throttle_sleep = 1.0/settings[:conns_second] if settings[:conns_second]
|
|
@@ -125,14 +79,14 @@ module SCGI # :nodoc: all
|
|
|
125
79
|
break if @shutdown and @conns <= 0
|
|
126
80
|
end
|
|
127
81
|
rescue Interrupt
|
|
128
|
-
@log.info("Shutting down from SIGINT.")
|
|
82
|
+
@log.info("SCGI: Shutting down from SIGINT.")
|
|
129
83
|
rescue Object
|
|
130
|
-
@log.
|
|
84
|
+
@log.warn("SCGI: while listening for connections on #@host:#@port -- #{$!.class} #$! #{$!.backtrace.join("\n")}" )
|
|
131
85
|
end
|
|
132
86
|
|
|
133
87
|
@socket.close if not @socket.closed?
|
|
134
88
|
@dead = true
|
|
135
|
-
@log.info("Exited accept loop. Shutdown complete.")
|
|
89
|
+
@log.info("SCGI: Exited accept loop. Shutdown complete.")
|
|
136
90
|
end
|
|
137
91
|
|
|
138
92
|
|
|
@@ -158,14 +112,14 @@ module SCGI # :nodoc: all
|
|
|
158
112
|
# we should now either have a payload length to get
|
|
159
113
|
payload = socket.read(len.to_i)
|
|
160
114
|
if (c = socket.read(1)) != ','
|
|
161
|
-
@log.
|
|
115
|
+
@log.warn("SCGI: Malformed request, does not end with ','")
|
|
162
116
|
else
|
|
163
117
|
read_header(socket, payload, @conns)
|
|
164
118
|
end
|
|
165
119
|
rescue IOError
|
|
166
|
-
@log.
|
|
120
|
+
@log.warn("SCGI: received IOError #$! when handling client. Your web server doesn't like me.")
|
|
167
121
|
rescue Object
|
|
168
|
-
@log.
|
|
122
|
+
@log.warn("SCGI: after accepting client #@host:#@port -- #{$!.class} #$! #{$!.backtrace.join("\n")}")
|
|
169
123
|
ensure
|
|
170
124
|
synchronize { @conns -= 1 if not in_shutdown}
|
|
171
125
|
socket.close if not socket.closed?
|
|
@@ -197,10 +151,26 @@ module SCGI # :nodoc: all
|
|
|
197
151
|
end
|
|
198
152
|
|
|
199
153
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
154
|
+
def process_request(request, body, socket)
|
|
155
|
+
return if socket.closed?
|
|
156
|
+
cgi = SCGIFixed.new(request, body, socket)
|
|
157
|
+
begin
|
|
158
|
+
#--
|
|
159
|
+
# TODO: remove sync, Nitro *is* thread safe!
|
|
160
|
+
#++
|
|
161
|
+
# guill: and why not ? ;)
|
|
162
|
+
#synchronize do
|
|
163
|
+
#--
|
|
164
|
+
# FIXME: this is uggly, something better?
|
|
165
|
+
#++
|
|
166
|
+
cgi.stdinput.rewind
|
|
167
|
+
cgi.env["QUERY_STRING"] = (cgi.env["REQUEST_URI"] =~ /^[^?]+\?(.+)$/ and $1).to_s
|
|
168
|
+
Nitro::Cgi.process(@server, cgi, cgi.stdinput, cgi.stdoutput)
|
|
169
|
+
#end
|
|
170
|
+
ensure
|
|
171
|
+
Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
204
174
|
|
|
205
175
|
def split_body(data)
|
|
206
176
|
result = {}
|
|
@@ -234,12 +204,35 @@ module SCGI # :nodoc: all
|
|
|
234
204
|
|
|
235
205
|
if force
|
|
236
206
|
@socket.close
|
|
237
|
-
@log.info("FORCED shutdown requested. Oh well.")
|
|
207
|
+
@log.info("SCGI: FORCED shutdown requested. Oh well.")
|
|
238
208
|
else
|
|
239
|
-
@log.info("Shutdown requested. Beginning graceful shutdown with #@conns connected.")
|
|
209
|
+
@log.info("SCGI: Shutdown requested. Beginning graceful shutdown with #@conns connected.")
|
|
240
210
|
end
|
|
241
211
|
end
|
|
242
212
|
end
|
|
213
|
+
|
|
214
|
+
class << self
|
|
215
|
+
def start(server)
|
|
216
|
+
settings = {
|
|
217
|
+
:host => server.address,
|
|
218
|
+
:port => server.port,
|
|
219
|
+
:logfile => nil, # will use Logger
|
|
220
|
+
:maxconns => 2**30-1,
|
|
221
|
+
:socket => nil,
|
|
222
|
+
:conns_second => nil,
|
|
223
|
+
:env => nil,
|
|
224
|
+
:drb_enable => false,
|
|
225
|
+
:drb_port => server.port - 1000,
|
|
226
|
+
:drb_password => ""
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
settings.update(server.options)
|
|
230
|
+
|
|
231
|
+
@nitro = SCGIProcessor.new(server, settings)
|
|
232
|
+
Logger.info("SCGI: Running on #{settings[:host]}:#{settings[:port]}")
|
|
233
|
+
@nitro.listen
|
|
234
|
+
end
|
|
235
|
+
end
|
|
243
236
|
end
|
|
244
237
|
|
|
245
238
|
# * Zed A Shaw <zedshaw@zedshaw.com>
|