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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
| | # Copyright (C) 2013-2016 all contributors <yahns-public@yhbt.net>
# License: GPL-3.0+ (https://www.gnu.org/licenses/gpl-3.0.txt)
# frozen_string_literal: true
require_relative 'server_helper'
class TestClientMaxBodySize < Testcase
ENV["N"].to_i > 1 and parallelize_me!
include ServerHelper
alias setup server_helper_setup
alias teardown server_helper_teardown
DEFMBS = 1024 * 1024
DRAINER = lambda do |e|
input = e["rack.input"]
buf = ''.dup
nr = 0
while rv = input.read(16384, buf)
nr += rv.size
end
body = nr.to_s
h = { "Content-Length" => body.size.to_s, "Content-Type" => 'text/plain' }
[ 200, h, [body] ]
end
def identity_req(bytes, body = true)
body_bytes = body ? bytes : 0
"PUT / HTTP/1.1\r\nConnection: close\r\nHost: example.com\r\n" \
"Content-Length: #{bytes}\r\n\r\n#{'*' * body_bytes}"
end
def test_0_lazy; cmbs_test_0(:lazy); end
def test_0_true; cmbs_test_0(true); end
def test_0_false; cmbs_test_0(false); end
def cmbs_test_0(btype)
err = @err
cfg = Yahns::Config.new
host, port = @srv.addr[3], @srv.addr[1]
cfg.instance_eval do
GTL.synchronize {
app(:rack, DRAINER) {
listen "#{host}:#{port}"
input_buffering btype
client_max_body_size 0
}
}
logger(Logger.new(err.path))
end
pid = mkserver(cfg)
default_identity_checks(host, port, 0)
default_chunked_checks(host, port, 0)
ensure
quit_wait(pid)
end
def test_cmbs_lazy; cmbs_test(:lazy); end
def test_cmbs_true; cmbs_test(true); end
def test_cmbs_false; cmbs_test(false); end
def cmbs_test(btype)
err = @err
cfg = Yahns::Config.new
host, port = @srv.addr[3], @srv.addr[1]
cfg.instance_eval do
GTL.synchronize {
app(:rack, DRAINER) {
listen "#{host}:#{port}"
input_buffering btype
}
}
logger(Logger.new(err.path))
end
pid = mkserver(cfg)
default_identity_checks(host, port)
default_chunked_checks(host, port)
ensure
quit_wait(pid)
end
def test_inf_false; big_test(false); end
def test_inf_true; big_test(true); end
def test_inf_lazy; big_test(:lazy); end
def big_test(btype)
err = @err
cfg = Yahns::Config.new
host, port = @srv.addr[3], @srv.addr[1]
cfg.instance_eval do
GTL.synchronize {
app(:rack, DRAINER) {
listen "#{host}:#{port}"
input_buffering btype
client_max_body_size nil
}
}
logger(Logger.new(err.path))
end
pid = mkserver(cfg)
bytes = 10 * 1024 * 1024
r = `dd if=/dev/zero bs=#{bytes} count=1 2>/dev/null | \
curl -sSf -HExpect: -T- http://#{host}:#{port}/`
assert $?.success?, $?.inspect
assert_equal bytes.to_s, r
r = `dd if=/dev/zero bs=#{bytes} count=1 2>/dev/null | \
curl -sSf -HExpect: -HContent-Length:#{bytes} -HTransfer-Encoding: \
-T- http://#{host}:#{port}/`
assert $?.success?, $?.inspect
assert_equal bytes.to_s, r
ensure
quit_wait(pid)
end
def default_chunked_checks(host, port, defmax = DEFMBS)
r = `curl -sSf -HExpect: -T- </dev/null http://#{host}:#{port}/`
assert $?.success?, $?.inspect
assert_equal "0", r
r = `dd if=/dev/zero bs=#{defmax} count=1 2>/dev/null | \
curl -sSf -HExpect: -T- http://#{host}:#{port}/`
assert $?.success?, $?.inspect
assert_equal "#{defmax}", r
r = `dd if=/dev/zero bs=#{defmax + 1} count=1 2>/dev/null | \
curl -sf -HExpect: -T- --write-out %{http_code} \
http://#{host}:#{port}/ 2>&1`
refute $?.success?, $?.inspect
assert_equal "413", r
end
def default_identity_checks(host, port, defmax = DEFMBS)
if defmax >= 666
c = get_tcp_client(host, port)
c.write(identity_req(666))
assert_equal "666", c.read.split(/\r\n\r\n/)[1]
c.close
end
c = get_tcp_client(host, port)
c.write(identity_req(0))
assert_equal "0", c.read.split(/\r\n\r\n/)[1]
c.close
c = get_tcp_client(host, port)
c.write(identity_req(defmax))
assert_equal "#{defmax}", c.read.split(/\r\n\r\n/)[1]
c.close
toobig = defmax + 1
c = get_tcp_client(host, port)
c.write(identity_req(toobig, false))
assert_match(%r{\AHTTP/1\.[01] 413 }, Timeout.timeout(10) { c.read })
c.close
end
end
|