1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| | # -*- encoding: binary -*-
# Copyright (C) 2013-2016 all contributors <yahns-public@yhbt.net>
# License: GPLv2 or later (https://www.gnu.org/licenses/gpl-2.0.txt)
# frozen_string_literal: true
# Middleware used to enforce client_max_body_size for TeeInput users.
#
# There is no need to configure this middleware manually, it will
# automatically be configured for you based on the client_max_body_size
# setting.
#
# For more fine-grained control, you may also define it per-endpoint in
# your Rack config.ru like this:
#
# map "/limit_1M" do
# use Yahns::MaxBody, 1024*1024
# run MyApp
# end
# map "/limit_10M" do
# use Yahns::MaxBody, 1024*1024*10
# run MyApp
# end
class Yahns::MaxBody # :nodoc:
# This is automatically called when used with Rack::Builder#use
# See Yahns::MaxBody
def initialize(app, limit)
Integer === limit or raise ArgumentError, "limit not an Integer"
@app = app
@limit = limit
end
# our main Rack middleware endpoint
def call(env) # :nodoc:
catch(:yahns_EFBIG) do
len = env['CONTENT_LENGTH']
if len && len.to_i > @limit
return err
elsif /\Achunked\z/i =~ env['HTTP_TRANSFER_ENCODING']
limit_input!(env)
end
@app.call(env)
end || err
end
# Rack response returned when there's an error
def err # :nodoc:
[ 413, { 'Content-Length' => '0', 'Content-Type' => 'text/plain' }, [] ]
end
def limit_input!(env) # :nodoc:
input = env['rack.input']
klass = input.respond_to?(:rewind) ? RewindableWrapper : Wrapper
env['rack.input'] = klass.new(input, @limit)
end
end
require_relative 'max_body/wrapper'
require_relative 'max_body/rewindable_wrapper'
|