1 # -*- encoding: binary -*-
3 # Middleware used to enforce client_max_body_size for TeeInput users.
5 # There is no need to configure this middleware manually, it will
6 # automatically be configured for you based on the client_max_body_size
9 # For more fine-grained control, you may also define it per-endpoint in
10 # your Rack config.ru like this:
13 # use Rainbows::MaxBody, 1024*1024
17 # use Rainbows::MaxBody, 1024*1024*10
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:
28 # * :CoolioThreadSpawn
37 # However, the global Rainbows::Configurator#client_max_body_size is compatible
38 # with all concurrency models \Rainbows! supports.
39 class Rainbows::MaxBody
41 # This is automatically called when used with Rack::Builder#use
42 def initialize(app, limit = nil)
46 raise ArgumentError, "limit not an Integer"
48 @app, @limit = app, limit
51 # our main Rack middleware endpoint
53 @limit = Rainbows.server.client_max_body_size if nil == @limit
54 catch(:rainbows_EFBIG) do
55 len = env['CONTENT_LENGTH']
56 if len && len.to_i > @limit
58 elsif /\Achunked\z/i =~ env['HTTP_TRANSFER_ENCODING']
65 # this is called after forking, so it won't ever affect the master
66 # if it's reconfigured
67 def self.setup # :nodoc:
68 Rainbows.server.client_max_body_size or return
69 case Rainbows.server.use
70 when :Rev, :Coolio, :EventMachine, :NeverBlock,
71 :RevThreadSpawn, :RevThreadPool,
72 :CoolioThreadSpawn, :CoolioThreadPool,
77 # force ourselves to the outermost middleware layer
78 Rainbows.server.app = self.new(Rainbows.server.app)
81 # Rack response returned when there's an error
83 [ 413, { 'Content-Length' => '0', 'Content-Type' => 'text/plain' }, [] ]
87 input = env['rack.input']
88 klass = input.respond_to?(:rewind) ? RewindableWrapper : Wrapper
89 env['rack.input'] = klass.new(input, @limit)
94 require 'rainbows/max_body/wrapper'
95 require 'rainbows/max_body/rewindable_wrapper'