rainbows 3.2.0 → 3.3.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/.document +1 -0
- data/COPYING +617 -282
- data/Documentation/comparison.haml +81 -24
- data/FAQ +3 -0
- data/GIT-VERSION-GEN +1 -1
- data/LICENSE +14 -5
- data/README +10 -9
- data/Sandbox +25 -0
- data/TODO +2 -22
- data/lib/rainbows.rb +50 -49
- data/lib/rainbows/client.rb +6 -5
- data/lib/rainbows/configurator.rb +191 -37
- data/lib/rainbows/const.rb +1 -1
- data/lib/rainbows/coolio.rb +4 -1
- data/lib/rainbows/coolio/client.rb +2 -2
- data/lib/rainbows/coolio/heartbeat.rb +2 -1
- data/lib/rainbows/coolio_fiber_spawn.rb +12 -7
- data/lib/rainbows/coolio_thread_pool.rb +19 -10
- data/lib/rainbows/coolio_thread_spawn.rb +3 -0
- data/lib/rainbows/epoll.rb +27 -5
- data/lib/rainbows/epoll/client.rb +3 -3
- data/lib/rainbows/ev_core.rb +2 -1
- data/lib/rainbows/event_machine.rb +4 -0
- data/lib/rainbows/event_machine/client.rb +2 -1
- data/lib/rainbows/fiber.rb +5 -0
- data/lib/rainbows/fiber/base.rb +1 -0
- data/lib/rainbows/fiber/coolio/methods.rb +0 -1
- data/lib/rainbows/fiber/io.rb +10 -6
- data/lib/rainbows/fiber/io/pipe.rb +6 -1
- data/lib/rainbows/fiber/io/socket.rb +6 -1
- data/lib/rainbows/fiber_pool.rb +12 -7
- data/lib/rainbows/fiber_spawn.rb +11 -6
- data/lib/rainbows/http_server.rb +55 -59
- data/lib/rainbows/join_threads.rb +4 -0
- data/lib/rainbows/max_body.rb +29 -10
- data/lib/rainbows/never_block.rb +7 -10
- data/lib/rainbows/pool_size.rb +14 -0
- data/lib/rainbows/process_client.rb +23 -1
- data/lib/rainbows/queue_pool.rb +8 -6
- data/lib/rainbows/response.rb +12 -11
- data/lib/rainbows/revactor.rb +14 -7
- data/lib/rainbows/revactor/client.rb +2 -2
- data/lib/rainbows/stream_file.rb +11 -4
- data/lib/rainbows/thread_pool.rb +12 -28
- data/lib/rainbows/thread_spawn.rb +14 -13
- data/lib/rainbows/thread_timeout.rb +118 -30
- data/lib/rainbows/writer_thread_pool/client.rb +1 -1
- data/lib/rainbows/writer_thread_spawn/client.rb +2 -2
- data/lib/rainbows/xepoll.rb +13 -5
- data/lib/rainbows/xepoll/client.rb +19 -17
- data/lib/rainbows/xepoll_thread_pool.rb +82 -0
- data/lib/rainbows/xepoll_thread_pool/client.rb +129 -0
- data/lib/rainbows/xepoll_thread_spawn.rb +58 -0
- data/lib/rainbows/xepoll_thread_spawn/client.rb +121 -0
- data/pkg.mk +4 -0
- data/rainbows.gemspec +4 -1
- data/t/GNUmakefile +5 -1
- data/t/client_header_buffer_size.ru +5 -0
- data/t/simple-http_XEpollThreadPool.ru +10 -0
- data/t/simple-http_XEpollThreadSpawn.ru +10 -0
- data/t/t0022-copy_stream-byte-range.sh +1 -15
- data/t/t0026-splice-copy_stream-byte-range.sh +25 -0
- data/t/t0027-nil-copy_stream.sh +60 -0
- data/t/t0041-optional-pool-size.sh +2 -2
- data/t/t0042-client_header_buffer_size.sh +65 -0
- data/t/t9100-thread-timeout.sh +1 -6
- data/t/t9101-thread-timeout-threshold.sh +1 -6
- data/t/test-lib.sh +58 -0
- data/t/test_isolate.rb +9 -3
- metadata +47 -16
@@ -10,7 +10,7 @@ module Rainbows::Epoll::Client
|
|
10
10
|
OUT = SleepyPenguin::Epoll::OUT | SleepyPenguin::Epoll::ET
|
11
11
|
KATO = {}
|
12
12
|
KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
|
13
|
-
|
13
|
+
Rainbows.config!(self, :keepalive_timeout)
|
14
14
|
EP = Rainbows::Epoll::EP
|
15
15
|
@@last_expire = Time.now
|
16
16
|
|
@@ -33,7 +33,7 @@ module Rainbows::Epoll::Client
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def on_readable
|
36
|
-
case rv = kgio_tryread(
|
36
|
+
case rv = kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, RBUF)
|
37
37
|
when String
|
38
38
|
on_read(rv)
|
39
39
|
return if @wr_queue[0] || closed?
|
@@ -226,7 +226,7 @@ module Rainbows::Epoll::Client
|
|
226
226
|
else # nil => EOF
|
227
227
|
return pipe.close # nil
|
228
228
|
end while true
|
229
|
-
rescue
|
229
|
+
rescue
|
230
230
|
pipe.close
|
231
231
|
raise
|
232
232
|
end
|
data/lib/rainbows/ev_core.rb
CHANGED
@@ -9,6 +9,7 @@ module Rainbows::EvCore
|
|
9
9
|
autoload :CapInput, 'rainbows/ev_core/cap_input'
|
10
10
|
RBUF = ""
|
11
11
|
Z = "".freeze
|
12
|
+
Rainbows.config!(self, :client_header_buffer_size)
|
12
13
|
|
13
14
|
# Apps may return this Rack response: AsyncResponse = [ -1, {}, [] ]
|
14
15
|
ASYNC_CALLBACK = "async.callback".freeze
|
@@ -132,7 +133,7 @@ module Rainbows::EvCore
|
|
132
133
|
end
|
133
134
|
|
134
135
|
def mkinput
|
135
|
-
max = Rainbows.
|
136
|
+
max = Rainbows.server.client_max_body_size
|
136
137
|
len = @hp.content_length
|
137
138
|
if len
|
138
139
|
if max && (len > max)
|
@@ -40,6 +40,10 @@ EM::VERSION >= '0.12.10' or abort 'eventmachine 0.12.10 is required'
|
|
40
40
|
# the Rack application to process data as it arrives. This means
|
41
41
|
# "rack.input" will be fully buffered in memory or to a temporary file
|
42
42
|
# before the application is entered.
|
43
|
+
#
|
44
|
+
# === RubyGem Requirements
|
45
|
+
#
|
46
|
+
# * event_machine 0.12.10
|
43
47
|
module Rainbows::EventMachine
|
44
48
|
autoload :ResponsePipe, 'rainbows/event_machine/response_pipe'
|
45
49
|
autoload :ResponseChunkPipe, 'rainbows/event_machine/response_chunk_pipe'
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# :enddoc:
|
3
3
|
class Rainbows::EventMachine::Client < EM::Connection
|
4
4
|
include Rainbows::EvCore
|
5
|
+
Rainbows.config!(self, :keepalive_timeout)
|
5
6
|
|
6
7
|
def initialize(io)
|
7
8
|
@_io = io
|
@@ -87,7 +88,7 @@ class Rainbows::EventMachine::Client < EM::Connection
|
|
87
88
|
if alive
|
88
89
|
if @deferred.nil?
|
89
90
|
if @buf.empty?
|
90
|
-
set_comm_inactivity_timeout(
|
91
|
+
set_comm_inactivity_timeout(KEEPALIVE_TIMEOUT)
|
91
92
|
else
|
92
93
|
EM.next_tick { receive_data(nil) }
|
93
94
|
end
|
data/lib/rainbows/fiber.rb
CHANGED
@@ -8,6 +8,11 @@ end
|
|
8
8
|
# :startdoc:
|
9
9
|
|
10
10
|
# core namespace for all things that use Fibers in \Rainbows!
|
11
|
+
#
|
12
|
+
# It's generally not recommended to use any of this in your applications
|
13
|
+
# unless you're willing to accept breakage. Most of this is very
|
14
|
+
# difficult-to-use, fragile and we don't have much time to devote to
|
15
|
+
# supporting these in the future.
|
11
16
|
module Rainbows::Fiber
|
12
17
|
|
13
18
|
# :stopdoc:
|
data/lib/rainbows/fiber/base.rb
CHANGED
data/lib/rainbows/fiber/io.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
|
3
|
-
# A Fiber-aware IO class, gives users the illusion of a synchronous
|
4
|
-
# interface that yields away from the current Fiber whenever
|
3
|
+
# A \Fiber-aware IO class, gives users the illusion of a synchronous
|
4
|
+
# interface that yields away from the current \Fiber whenever
|
5
5
|
# the underlying descriptor is blocked on reads or write
|
6
6
|
#
|
7
|
+
# It's not recommended to use any of this in your applications
|
8
|
+
# unless you're willing to accept breakage. Most of this is very
|
9
|
+
# difficult-to-use, fragile and we don't have much time to devote to
|
10
|
+
# supporting these in the future.
|
11
|
+
#
|
7
12
|
# This is a stable, legacy interface and should be preserved for all
|
8
13
|
# future versions of Rainbows! However, new apps should use
|
9
|
-
# Rainbows::Fiber::IO::Socket or Rainbows::Fiber::IO::Pipe instead
|
10
|
-
|
14
|
+
# Rainbows::Fiber::IO::Socket or Rainbows::Fiber::IO::Pipe instead
|
15
|
+
# (or better yet, avoid any of the Rainbows::Fiber* stuff).
|
11
16
|
class Rainbows::Fiber::IO
|
12
17
|
attr_accessor :to_io
|
13
18
|
|
@@ -45,7 +50,7 @@ class Rainbows::Fiber::IO
|
|
45
50
|
end
|
46
51
|
|
47
52
|
def write(buf)
|
48
|
-
case rv = Kgio.trywrite(buf)
|
53
|
+
case rv = Kgio.trywrite(@to_io, buf)
|
49
54
|
when String
|
50
55
|
buf = rv
|
51
56
|
when :wait_writable
|
@@ -96,7 +101,6 @@ end
|
|
96
101
|
# :stopdoc:
|
97
102
|
require 'rainbows/fiber/io/methods'
|
98
103
|
require 'rainbows/fiber/io/compat'
|
99
|
-
Rainbows::Client.__send__(:include, Rainbows::Fiber::IO::Methods)
|
100
104
|
class Rainbows::Fiber::IO
|
101
105
|
include Rainbows::Fiber::IO::Compat
|
102
106
|
include Rainbows::Fiber::IO::Methods
|
@@ -1,7 +1,12 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
# A Fiber-aware Pipe class, gives users the illusion of a synchronous
|
3
3
|
# interface that yields away from the current Fiber whenever
|
4
|
-
# the underlying descriptor is blocked on reads or write
|
4
|
+
# the underlying descriptor is blocked on reads or write.
|
5
|
+
#
|
6
|
+
# It's not recommended to use any of this in your applications
|
7
|
+
# unless you're willing to accept breakage. Most of this is very
|
8
|
+
# difficult-to-use, fragile and we don't have much time to devote to
|
9
|
+
# supporting these in the future.
|
5
10
|
class Rainbows::Fiber::IO::Pipe < Kgio::Pipe
|
6
11
|
include Rainbows::Fiber::IO::Methods
|
7
12
|
end
|
@@ -1,7 +1,12 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
# A Fiber-aware Socket class, gives users the illusion of a synchronous
|
3
3
|
# interface that yields away from the current Fiber whenever
|
4
|
-
# the underlying descriptor is blocked on reads or write
|
4
|
+
# the underlying descriptor is blocked on reads or write.
|
5
|
+
#
|
6
|
+
# It's not recommended to use any of this in your applications
|
7
|
+
# unless you're willing to accept breakage. Most of this is very
|
8
|
+
# difficult-to-use, fragile and we don't have much time to devote to
|
9
|
+
# supporting these in the future.
|
5
10
|
class Rainbows::Fiber::IO::Socket < Kgio::Socket
|
6
11
|
include Rainbows::Fiber::IO::Methods
|
7
12
|
end
|
data/lib/rainbows/fiber_pool.rb
CHANGED
@@ -3,13 +3,18 @@ require 'rainbows/fiber'
|
|
3
3
|
|
4
4
|
# A Fiber-based concurrency model for Ruby 1.9. This uses a pool of
|
5
5
|
# Fibers to handle client IO to run the application and the root Fiber
|
6
|
-
# for scheduling and connection acceptance.
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# the
|
6
|
+
# for scheduling and connection acceptance.
|
7
|
+
#
|
8
|
+
# This concurrency model is difficult to use with existing applications,
|
9
|
+
# lacks third-party support, and is thus NOT recommended.
|
10
|
+
#
|
11
|
+
# The pool size is equal to the number of +worker_connections+.
|
12
|
+
# Compared to the ThreadPool model, Fibers are very cheap in terms of
|
13
|
+
# memory usage so you can have more active connections. This model
|
14
|
+
# supports a streaming "rack.input" with lightweight concurrency.
|
15
|
+
# Applications are strongly advised to wrap all slow IO objects
|
16
|
+
# (sockets, pipes) using the Rainbows::Fiber::IO class whenever
|
17
|
+
# possible.
|
13
18
|
module Rainbows::FiberPool
|
14
19
|
include Rainbows::Fiber::Base
|
15
20
|
|
data/lib/rainbows/fiber_spawn.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
require 'rainbows/fiber'
|
3
3
|
|
4
|
-
# Simple Fiber-based concurrency model for 1.9. This spawns a new
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
4
|
+
# Simple Fiber-based concurrency model for 1.9. This spawns a new Fiber
|
5
|
+
# for every incoming client connection and the root Fiber for scheduling
|
6
|
+
# and connection acceptance.
|
7
|
+
#
|
8
|
+
# This concurrency model is difficult to use with existing applications,
|
9
|
+
# lacks third-party support, and is thus NOT recommended.
|
10
|
+
#
|
11
|
+
# This exports a streaming "rack.input" with lightweight concurrency.
|
12
|
+
# Applications are strongly advised to wrap all slow IO objects
|
13
|
+
# (sockets, pipes) using the Rainbows::Fiber::IO class whenever
|
14
|
+
# possible.
|
10
15
|
module Rainbows::FiberSpawn
|
11
16
|
include Rainbows::Fiber::Base
|
12
17
|
|
data/lib/rainbows/http_server.rb
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
# :enddoc:
|
3
3
|
|
4
4
|
class Rainbows::HttpServer < Unicorn::HttpServer
|
5
|
+
attr_accessor :copy_stream
|
6
|
+
attr_accessor :worker_connections
|
7
|
+
attr_accessor :keepalive_timeout
|
8
|
+
attr_accessor :client_header_buffer_size
|
9
|
+
attr_accessor :client_max_body_size
|
10
|
+
attr_reader :use
|
11
|
+
|
5
12
|
def self.setup(block)
|
6
13
|
Rainbows.server.instance_eval(&block)
|
7
14
|
end
|
@@ -9,9 +16,9 @@ class Rainbows::HttpServer < Unicorn::HttpServer
|
|
9
16
|
def initialize(app, options)
|
10
17
|
Rainbows.server = self
|
11
18
|
@logger = Unicorn::Configurator::DEFAULTS[:logger]
|
12
|
-
|
13
|
-
defined?(@use) or use
|
14
|
-
@worker_connections ||=
|
19
|
+
super(app, options)
|
20
|
+
defined?(@use) or self.use = Rainbows::Base
|
21
|
+
@worker_connections ||= @use == :Base ? 1 : 50
|
15
22
|
end
|
16
23
|
|
17
24
|
def reopen_worker_logs(worker_nr)
|
@@ -33,80 +40,69 @@ class Rainbows::HttpServer < Unicorn::HttpServer
|
|
33
40
|
end
|
34
41
|
|
35
42
|
def load_config!
|
36
|
-
use :Base
|
37
|
-
Rainbows.keepalive_timeout = 5
|
38
|
-
Rainbows.max_bytes = 1024 * 1024
|
39
|
-
@worker_connections = nil
|
40
43
|
super
|
41
|
-
@worker_connections
|
44
|
+
@worker_connections = 1 if @use == :Base
|
45
|
+
end
|
46
|
+
|
47
|
+
def worker_loop(worker)
|
48
|
+
Rainbows.forked = true
|
49
|
+
orig = method(:worker_loop)
|
50
|
+
extend(Rainbows.const_get(@use))
|
51
|
+
m = method(:worker_loop)
|
52
|
+
orig == m ? super(worker) : worker_loop(worker)
|
42
53
|
end
|
43
54
|
|
44
|
-
def
|
45
|
-
#
|
46
|
-
|
47
|
-
|
55
|
+
def spawn_missing_workers
|
56
|
+
# 5: std{in,out,err} + heartbeat FD + per-process listener
|
57
|
+
nofile = 5 + @worker_connections + LISTENERS.size
|
58
|
+
trysetrlimit(:RLIMIT_NOFILE, nofile)
|
59
|
+
|
60
|
+
case @use
|
61
|
+
when :ThreadSpawn, :ThreadPool, :ActorSpawn,
|
62
|
+
:CoolioThreadSpawn, :RevThreadSpawn,
|
63
|
+
:XEpollThreadSpawn, :WriterThreadPool, :WriterThreadSpawn
|
64
|
+
trysetrlimit(:RLIMIT_NPROC, @worker_connections + LISTENERS.size + 1)
|
65
|
+
when :XEpollThreadPool, :CoolioThreadPool
|
66
|
+
trysetrlimit(:RLIMIT_NPROC, Rainbows::O[:pool_size] + LISTENERS.size + 1)
|
48
67
|
end
|
49
68
|
super
|
50
69
|
end
|
51
70
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
logger.
|
58
|
-
|
59
|
-
|
71
|
+
def trysetrlimit(resource, want)
|
72
|
+
var = Process.const_get(resource)
|
73
|
+
cur, max = Process.getrlimit(var)
|
74
|
+
cur <= want and Process.setrlimit(var, cur = max > want ? max : want)
|
75
|
+
if cur == want
|
76
|
+
@logger.warn "#{resource} rlim_cur=#{cur} is barely enough"
|
77
|
+
@logger.warn "#{svc} may monopolize resources dictated by #{resource}" \
|
78
|
+
" and leave none for your app"
|
60
79
|
end
|
80
|
+
rescue => e
|
81
|
+
@logger.error e.message
|
82
|
+
@logger.error "#{resource} needs to be increased to >=#{want} before" \
|
83
|
+
" starting #{svc}"
|
84
|
+
end
|
61
85
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
else; raise ArgumentError, "can't handle option: #{opt.inspect}"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
mod.setup if mod.respond_to?(:setup)
|
86
|
+
def svc
|
87
|
+
File.basename($0)
|
88
|
+
end
|
89
|
+
|
90
|
+
def use=(mod)
|
91
|
+
@use = mod.to_s.split(/::/)[-1].to_sym
|
72
92
|
new_defaults = {
|
73
|
-
'rainbows.model' =>
|
74
|
-
'rack.multithread' => !!(
|
93
|
+
'rainbows.model' => @use,
|
94
|
+
'rack.multithread' => !!(mod.to_s =~ /Thread/),
|
75
95
|
'rainbows.autochunk' => [:Coolio,:Rev,:Epoll,:XEpoll,
|
76
96
|
:EventMachine,:NeverBlock].include?(@use),
|
77
97
|
}
|
78
98
|
Rainbows::Const::RACK_DEFAULTS.update(new_defaults)
|
79
99
|
end
|
80
100
|
|
81
|
-
def
|
82
|
-
return @worker_connections if args.empty?
|
83
|
-
nr = args[0]
|
84
|
-
(Integer === nr && nr > 0) or
|
85
|
-
raise ArgumentError, "worker_connections must be a positive Integer"
|
86
|
-
@worker_connections = nr
|
87
|
-
end
|
88
|
-
|
89
|
-
def keepalive_timeout(nr)
|
90
|
-
(Integer === nr && nr >= 0) or
|
91
|
-
raise ArgumentError, "keepalive_timeout must be a non-negative Integer"
|
92
|
-
Rainbows.keepalive_timeout = nr
|
93
|
-
end
|
94
|
-
|
95
|
-
def keepalive_requests(nr)
|
96
|
-
Integer === nr or
|
97
|
-
raise ArgumentError, "keepalive_requests must be a non-negative Integer"
|
101
|
+
def keepalive_requests=(nr)
|
98
102
|
Unicorn::HttpRequest.keepalive_requests = nr
|
99
103
|
end
|
100
104
|
|
101
|
-
def
|
102
|
-
|
103
|
-
case nr
|
104
|
-
when nil
|
105
|
-
when Integer
|
106
|
-
nr >= 0 or raise ArgumentError, err
|
107
|
-
else
|
108
|
-
raise ArgumentError, err
|
109
|
-
end
|
110
|
-
Rainbows.max_bytes = nr
|
105
|
+
def keepalive_requests
|
106
|
+
Unicorn::HttpRequest.keepalive_requests
|
111
107
|
end
|
112
108
|
end
|
@@ -5,9 +5,13 @@ module Rainbows::JoinThreads
|
|
5
5
|
|
6
6
|
# blocking acceptor threads must be forced to run
|
7
7
|
def self.acceptors(threads)
|
8
|
+
expire = Time.now + Rainbows.server.timeout
|
8
9
|
threads.delete_if do |thr|
|
9
10
|
Rainbows.tick
|
10
11
|
begin
|
12
|
+
# blocking accept() may not wake up properly
|
13
|
+
thr.raise(Errno::EINTR) if Time.now > expire && thr.stop?
|
14
|
+
|
11
15
|
thr.run
|
12
16
|
thr.join(0.01)
|
13
17
|
rescue
|
data/lib/rainbows/max_body.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# automatically be configured for you based on the client_max_body_size
|
7
7
|
# setting.
|
8
8
|
#
|
9
|
-
# For more fine-grained
|
9
|
+
# For more fine-grained control, you may also define it per-endpoint in
|
10
10
|
# your Rack config.ru like this:
|
11
11
|
#
|
12
12
|
# map "/limit_1M" do
|
@@ -17,16 +17,34 @@
|
|
17
17
|
# use Rainbows::MaxBody, 1024*1024*10
|
18
18
|
# run MyApp
|
19
19
|
# end
|
20
|
-
|
20
|
+
#
|
21
|
+
# This is only compatible with concurrency models that expose a streaming
|
22
|
+
# "rack.input" to the Rack application. Thus it is NOT compatible with
|
23
|
+
# any of the following as they fully buffer the request body before
|
24
|
+
# the application dispatch:
|
25
|
+
#
|
26
|
+
# * :Coolio
|
27
|
+
# * :CoolioThreadPool
|
28
|
+
# * :CoolioThreadSpawn
|
29
|
+
# * :Epoll
|
30
|
+
# * :EventMachine
|
31
|
+
# * :NeverBlock
|
32
|
+
# * :Rev
|
33
|
+
# * :RevThreadPool
|
34
|
+
# * :RevThreadSpawn
|
35
|
+
# * :XEpoll
|
36
|
+
#
|
37
|
+
# However, the global Rainbows::Configurator#client_max_body_size is compatible
|
38
|
+
# with all concurrency models \Rainbows! supports.
|
21
39
|
class Rainbows::MaxBody
|
22
40
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
41
|
+
# This is automatically called when used with Rack::Builder#use
|
42
|
+
def initialize(app, limit = nil)
|
43
|
+
case limit
|
44
|
+
when Integer, nil
|
45
|
+
else
|
46
|
+
raise ArgumentError, "limit not an Integer"
|
47
|
+
end
|
30
48
|
@app, @limit = app, limit
|
31
49
|
end
|
32
50
|
|
@@ -37,6 +55,7 @@ class Rainbows::MaxBody
|
|
37
55
|
|
38
56
|
# our main Rack middleware endpoint
|
39
57
|
def call(env)
|
58
|
+
@limit = Rainbows.server.client_max_body_size if nil == @limit
|
40
59
|
catch(:rainbows_EFBIG) do
|
41
60
|
len = env[CONTENT_LENGTH]
|
42
61
|
if len && len.to_i > @limit
|
@@ -51,7 +70,7 @@ class Rainbows::MaxBody
|
|
51
70
|
# this is called after forking, so it won't ever affect the master
|
52
71
|
# if it's reconfigured
|
53
72
|
def self.setup # :nodoc:
|
54
|
-
Rainbows.
|
73
|
+
Rainbows.server.client_max_body_size or return
|
55
74
|
case Rainbows.server.use
|
56
75
|
when :Rev, :Coolio, :EventMachine, :NeverBlock,
|
57
76
|
:RevThreadSpawn, :RevThreadPool,
|