unicorn-camilo 4.8.2.5.19 → 5.0.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.
- checksums.yaml +4 -4
- data/.document +0 -1
- data/.gitignore +2 -2
- data/{.wrongdoc.yml → .olddoc.yml} +7 -2
- data/Documentation/unicorn.1.txt +9 -2
- data/Documentation/unicorn_rails.1.txt +2 -2
- data/FAQ +9 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +31 -46
- data/HACKING +13 -27
- data/ISSUES +80 -16
- data/KNOWN_ISSUES +10 -10
- data/Links +10 -7
- data/PHILOSOPHY +1 -1
- data/README +8 -13
- data/Rakefile +0 -44
- data/Sandbox +1 -1
- data/TUNING +6 -3
- data/archive/.gitignore +3 -0
- data/archive/slrnpull.conf +4 -0
- data/bin/unicorn +1 -1
- data/bin/unicorn_rails +1 -1
- data/examples/unicorn.conf.rb +11 -0
- data/ext/unicorn_http/httpdate.c +1 -1
- data/ext/unicorn_http/unicorn_http.rl +48 -150
- data/lib/unicorn.rb +9 -15
- data/lib/unicorn/configurator.rb +3 -20
- data/lib/unicorn/const.rb +2 -25
- data/lib/unicorn/http_request.rb +4 -1
- data/lib/unicorn/http_response.rb +1 -3
- data/lib/unicorn/http_server.rb +85 -86
- data/lib/unicorn/socket_helper.rb +33 -67
- data/lib/unicorn/tee_input.rb +8 -1
- data/lib/unicorn/tmpio.rb +2 -4
- data/lib/unicorn/util.rb +1 -0
- data/lib/unicorn/worker.rb +1 -13
- data/t/GNUmakefile +1 -5
- data/t/README +1 -1
- data/t/t0002-parser-error.sh +3 -3
- data/test/exec/test_exec.rb +1 -1
- data/test/test_helper.rb +2 -2
- data/test/unit/test_http_parser.rb +3 -3
- data/test/unit/test_http_parser_ng.rb +8 -117
- data/test/unit/test_request.rb +1 -1
- data/test/unit/test_response.rb +3 -9
- data/test/unit/test_server.rb +3 -3
- data/test/unit/test_signals.rb +1 -1
- data/test/unit/test_socket_helper.rb +5 -5
- data/test/unit/test_tee_input.rb +10 -0
- data/test/unit/test_upload.rb +1 -1
- data/test/unit/test_util.rb +1 -1
- data/unicorn.gemspec +7 -10
- metadata +15 -33
- data/examples/git.ru +0 -13
- data/lib/unicorn/app/exec_cgi.rb +0 -154
- data/lib/unicorn/app/inetd.rb +0 -109
- data/lib/unicorn/ssl_client.rb +0 -11
- data/lib/unicorn/ssl_configurator.rb +0 -104
- data/lib/unicorn/ssl_server.rb +0 -42
- data/local.mk.sample +0 -59
- data/script/isolate_for_tests +0 -31
- data/t/t0016-trust-x-forwarded-false.sh +0 -30
- data/t/t0017-trust-x-forwarded-true.sh +0 -30
- data/test/unit/test_http_parser_xftrust.rb +0 -38
- data/test/unit/test_sni_hostnames.rb +0 -47
@@ -4,12 +4,6 @@ require 'socket'
|
|
4
4
|
|
5
5
|
module Unicorn
|
6
6
|
module SocketHelper
|
7
|
-
# :stopdoc:
|
8
|
-
include Socket::Constants
|
9
|
-
|
10
|
-
# prevents IO objects in here from being GC-ed
|
11
|
-
# kill this when we drop 1.8 support
|
12
|
-
IO_PURGATORY = []
|
13
7
|
|
14
8
|
# internal interface, only used by Rainbows!/Zbatery
|
15
9
|
DEFAULTS = {
|
@@ -22,7 +16,7 @@ module Unicorn
|
|
22
16
|
:tcp_defer_accept => 1,
|
23
17
|
|
24
18
|
# FreeBSD, we need to override this to 'dataready' if we
|
25
|
-
# eventually
|
19
|
+
# eventually support non-HTTP/1.x
|
26
20
|
:accept_filter => 'httpready',
|
27
21
|
|
28
22
|
# same default value as Mongrel
|
@@ -32,76 +26,47 @@ module Unicorn
|
|
32
26
|
:tcp_nopush => nil,
|
33
27
|
:tcp_nodelay => true,
|
34
28
|
}
|
35
|
-
#:startdoc:
|
36
29
|
|
37
30
|
# configure platform-specific options (only tested on Linux 2.6 so far)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
TCP_DEFER_ACCEPT = 9 unless defined?(TCP_DEFER_ACCEPT)
|
42
|
-
|
43
|
-
# do not send out partial frames (Linux)
|
44
|
-
TCP_CORK = 3 unless defined?(TCP_CORK)
|
45
|
-
|
46
|
-
# Linux got SO_REUSEPORT in 3.9, BSDs have had it for ages
|
47
|
-
unless defined?(SO_REUSEPORT)
|
48
|
-
if RUBY_PLATFORM =~ /(?:alpha|mips|parisc|sparc)/
|
49
|
-
SO_REUSEPORT = 0x0200 # untested
|
50
|
-
else
|
51
|
-
SO_REUSEPORT = 15 # only tested on x86_64 and i686
|
52
|
-
end
|
53
|
-
end
|
54
|
-
when /freebsd/
|
55
|
-
# do not send out partial frames (FreeBSD)
|
56
|
-
TCP_NOPUSH = 4 unless defined?(TCP_NOPUSH)
|
57
|
-
|
58
|
-
def accf_arg(af_name)
|
59
|
-
[ af_name, nil ].pack('a16a240')
|
60
|
-
end if defined?(SO_ACCEPTFILTER)
|
61
|
-
end
|
62
|
-
|
63
|
-
def prevent_autoclose(io)
|
64
|
-
if io.respond_to?(:autoclose=)
|
65
|
-
io.autoclose = false
|
66
|
-
else
|
67
|
-
IO_PURGATORY << io
|
68
|
-
end
|
69
|
-
end
|
31
|
+
def accf_arg(af_name)
|
32
|
+
[ af_name, nil ].pack('a16a240')
|
33
|
+
end if RUBY_PLATFORM =~ /freebsd/ && Socket.const_defined?(:SO_ACCEPTFILTER)
|
70
34
|
|
71
35
|
def set_tcp_sockopt(sock, opt)
|
72
36
|
# just in case, even LANs can break sometimes. Linux sysadmins
|
73
37
|
# can lower net.ipv4.tcp_keepalive_* sysctl knobs to very low values.
|
74
|
-
|
38
|
+
Socket.const_defined?(:SO_KEEPALIVE) and
|
39
|
+
sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 1)
|
75
40
|
|
76
|
-
if
|
41
|
+
if Socket.const_defined?(:TCP_NODELAY)
|
77
42
|
val = opt[:tcp_nodelay]
|
78
|
-
val = DEFAULTS[:tcp_nodelay] if nil
|
79
|
-
sock.setsockopt(IPPROTO_TCP, TCP_NODELAY, val ? 1 : 0)
|
43
|
+
val = DEFAULTS[:tcp_nodelay] if val.nil?
|
44
|
+
sock.setsockopt(:IPPROTO_TCP, :TCP_NODELAY, val ? 1 : 0)
|
80
45
|
end
|
81
46
|
|
82
47
|
val = opt[:tcp_nopush]
|
83
48
|
unless val.nil?
|
84
|
-
if
|
85
|
-
sock.setsockopt(IPPROTO_TCP, TCP_CORK, val)
|
86
|
-
elsif
|
87
|
-
sock.setsockopt(IPPROTO_TCP, TCP_NOPUSH, val)
|
49
|
+
if Socket.const_defined?(:TCP_CORK) # Linux
|
50
|
+
sock.setsockopt(:IPPROTO_TCP, :TCP_CORK, val)
|
51
|
+
elsif Socket.const_defined?(:TCP_NOPUSH) # FreeBSD
|
52
|
+
sock.setsockopt(:IPPROTO_TCP, :TCP_NOPUSH, val)
|
88
53
|
end
|
89
54
|
end
|
90
55
|
|
91
|
-
# No good reason to ever have deferred accepts off
|
92
|
-
# (except maybe benchmarking)
|
93
|
-
if
|
56
|
+
# No good reason to ever have deferred accepts off in single-threaded
|
57
|
+
# servers (except maybe benchmarking)
|
58
|
+
if Socket.const_defined?(:TCP_DEFER_ACCEPT)
|
94
59
|
# this differs from nginx, since nginx doesn't allow us to
|
95
60
|
# configure the the timeout...
|
96
61
|
seconds = opt[:tcp_defer_accept]
|
97
62
|
seconds = DEFAULTS[:tcp_defer_accept] if [true,nil].include?(seconds)
|
98
63
|
seconds = 0 unless seconds # nil/false means disable this
|
99
|
-
sock.setsockopt(
|
64
|
+
sock.setsockopt(:IPPROTO_TCP, :TCP_DEFER_ACCEPT, seconds)
|
100
65
|
elsif respond_to?(:accf_arg)
|
101
66
|
name = opt[:accept_filter]
|
102
|
-
name = DEFAULTS[:accept_filter] if nil
|
67
|
+
name = DEFAULTS[:accept_filter] if name.nil?
|
103
68
|
begin
|
104
|
-
sock.setsockopt(SOL_SOCKET, SO_ACCEPTFILTER, accf_arg(name))
|
69
|
+
sock.setsockopt(:SOL_SOCKET, :SO_ACCEPTFILTER, accf_arg(name))
|
105
70
|
rescue => e
|
106
71
|
logger.error("#{sock_name(sock)} " \
|
107
72
|
"failed to set accept_filter=#{name} (#{e.inspect})")
|
@@ -114,10 +79,11 @@ module Unicorn
|
|
114
79
|
|
115
80
|
TCPSocket === sock and set_tcp_sockopt(sock, opt)
|
116
81
|
|
117
|
-
|
82
|
+
rcvbuf, sndbuf = opt.values_at(:rcvbuf, :sndbuf)
|
83
|
+
if rcvbuf || sndbuf
|
118
84
|
log_buffer_sizes(sock, "before: ")
|
119
|
-
sock.setsockopt(SOL_SOCKET, SO_RCVBUF,
|
120
|
-
sock.setsockopt(SOL_SOCKET, SO_SNDBUF,
|
85
|
+
sock.setsockopt(:SOL_SOCKET, :SO_RCVBUF, rcvbuf) if rcvbuf
|
86
|
+
sock.setsockopt(:SOL_SOCKET, :SO_SNDBUF, sndbuf) if sndbuf
|
121
87
|
log_buffer_sizes(sock, " after: ")
|
122
88
|
end
|
123
89
|
sock.listen(opt[:backlog])
|
@@ -126,8 +92,8 @@ module Unicorn
|
|
126
92
|
end
|
127
93
|
|
128
94
|
def log_buffer_sizes(sock, pfx = '')
|
129
|
-
rcvbuf = sock.getsockopt(SOL_SOCKET, SO_RCVBUF).
|
130
|
-
sndbuf = sock.getsockopt(SOL_SOCKET, SO_SNDBUF).
|
95
|
+
rcvbuf = sock.getsockopt(:SOL_SOCKET, :SO_RCVBUF).int
|
96
|
+
sndbuf = sock.getsockopt(:SOL_SOCKET, :SO_SNDBUF).int
|
131
97
|
logger.info "#{pfx}#{sock_name(sock)} rcvbuf=#{rcvbuf} sndbuf=#{sndbuf}"
|
132
98
|
end
|
133
99
|
|
@@ -172,25 +138,25 @@ module Unicorn
|
|
172
138
|
|
173
139
|
def new_tcp_server(addr, port, opt)
|
174
140
|
# n.b. we set FD_CLOEXEC in the workers
|
175
|
-
sock = Socket.new(opt[:ipv6] ? AF_INET6 : AF_INET, SOCK_STREAM
|
141
|
+
sock = Socket.new(opt[:ipv6] ? :AF_INET6 : :AF_INET, :SOCK_STREAM)
|
176
142
|
if opt.key?(:ipv6only)
|
177
|
-
|
143
|
+
Socket.const_defined?(:IPV6_V6ONLY) or
|
178
144
|
abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS"
|
179
|
-
sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0)
|
145
|
+
sock.setsockopt(:IPPROTO_IPV6, :IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0)
|
180
146
|
end
|
181
|
-
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
182
|
-
if
|
183
|
-
sock.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
|
147
|
+
sock.setsockopt(:SOL_SOCKET, :SO_REUSEADDR, 1)
|
148
|
+
if Socket.const_defined?(:SO_REUSEPORT) && opt[:reuseport]
|
149
|
+
sock.setsockopt(:SOL_SOCKET, :SO_REUSEPORT, 1)
|
184
150
|
end
|
185
151
|
sock.bind(Socket.pack_sockaddr_in(port, addr))
|
186
|
-
|
152
|
+
sock.autoclose = false
|
187
153
|
Kgio::TCPServer.for_fd(sock.fileno)
|
188
154
|
end
|
189
155
|
|
190
156
|
# returns rfc2732-style (e.g. "[::1]:666") addresses for IPv6
|
191
157
|
def tcp_name(sock)
|
192
158
|
port, addr = Socket.unpack_sockaddr_in(sock.getsockname)
|
193
|
-
|
159
|
+
addr.include?(':') ? "[#{addr}]:#{port}" : "#{addr}:#{port}"
|
194
160
|
end
|
195
161
|
module_function :tcp_name
|
196
162
|
|
data/lib/unicorn/tee_input.rb
CHANGED
@@ -28,13 +28,20 @@ class Unicorn::TeeInput < Unicorn::StreamInput
|
|
28
28
|
@@client_body_buffer_size
|
29
29
|
end
|
30
30
|
|
31
|
+
# for Rack::TempfileReaper in rack 1.6+
|
32
|
+
def new_tmpio # :nodoc:
|
33
|
+
tmpio = Unicorn::TmpIO.new
|
34
|
+
(@parser.env['rack.tempfiles'] ||= []) << tmpio
|
35
|
+
tmpio
|
36
|
+
end
|
37
|
+
|
31
38
|
# Initializes a new TeeInput object. You normally do not have to call
|
32
39
|
# this unless you are writing an HTTP server.
|
33
40
|
def initialize(socket, request)
|
34
41
|
@len = request.content_length
|
35
42
|
super
|
36
43
|
@tmp = @len && @len <= @@client_body_buffer_size ?
|
37
|
-
StringIO.new("") :
|
44
|
+
StringIO.new("") : new_tmpio
|
38
45
|
end
|
39
46
|
|
40
47
|
# :call-seq:
|
data/lib/unicorn/tmpio.rb
CHANGED
data/lib/unicorn/util.rb
CHANGED
data/lib/unicorn/worker.rb
CHANGED
@@ -11,7 +11,6 @@ require "raindrops"
|
|
11
11
|
class Unicorn::Worker
|
12
12
|
# :stopdoc:
|
13
13
|
attr_accessor :nr, :switched
|
14
|
-
attr_writer :tmp
|
15
14
|
attr_reader :to_io # IO.select-compatible
|
16
15
|
|
17
16
|
PER_DROP = Raindrops::PAGE_SIZE / Raindrops::SIZE
|
@@ -23,7 +22,7 @@ class Unicorn::Worker
|
|
23
22
|
@offset = nr % PER_DROP
|
24
23
|
@raindrop[@offset] = 0
|
25
24
|
@nr = nr
|
26
|
-
@
|
25
|
+
@switched = false
|
27
26
|
@to_io, @master = Unicorn.pipe
|
28
27
|
end
|
29
28
|
|
@@ -101,18 +100,8 @@ class Unicorn::Worker
|
|
101
100
|
@raindrop[@offset]
|
102
101
|
end
|
103
102
|
|
104
|
-
# only exists for compatibility
|
105
|
-
def tmp # :nodoc:
|
106
|
-
@tmp ||= begin
|
107
|
-
tmp = Unicorn::TmpIO.new
|
108
|
-
tmp.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
109
|
-
tmp
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
103
|
# called in both the master (reaping worker) and worker (SIGQUIT handler)
|
114
104
|
def close # :nodoc:
|
115
|
-
@tmp.close if @tmp
|
116
105
|
@master.close if @master
|
117
106
|
@to_io.close if @to_io
|
118
107
|
end
|
@@ -141,7 +130,6 @@ class Unicorn::Worker
|
|
141
130
|
uid = Etc.getpwnam(user).uid
|
142
131
|
gid = Etc.getgrnam(group).gid if group
|
143
132
|
Unicorn::Util.chown_logs(uid, gid)
|
144
|
-
@tmp.chown(uid, gid) if @tmp
|
145
133
|
if gid && Process.egid != gid
|
146
134
|
Process.initgroups(user, gid)
|
147
135
|
Process::GID.change_privilege(gid)
|
data/t/GNUmakefile
CHANGED
@@ -17,11 +17,7 @@ endif
|
|
17
17
|
RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
|
18
18
|
export RUBY_ENGINE
|
19
19
|
|
20
|
-
|
21
|
-
$(isolate_libs): ../script/isolate_for_tests
|
22
|
-
@cd .. && $(RUBY) script/isolate_for_tests
|
23
|
-
-include $(isolate_libs)
|
24
|
-
MYLIBS := $(RUBYLIB):$(ISOLATE_LIBS)
|
20
|
+
MYLIBS := $(RUBYLIB)
|
25
21
|
|
26
22
|
T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
|
27
23
|
|
data/t/README
CHANGED
@@ -10,7 +10,7 @@ comfortable writing integration tests with.
|
|
10
10
|
|
11
11
|
== Requirements
|
12
12
|
|
13
|
-
* {Ruby 1.
|
13
|
+
* {Ruby 1.9.3+}[https://www.ruby-lang.org/] (duh!)
|
14
14
|
* {GNU make}[http://www.gnu.org/software/make/]
|
15
15
|
* {socat}[http://www.dest-unreach.org/socat/]
|
16
16
|
* {curl}[http://curl.haxx.se/]
|
data/t/t0002-parser-error.sh
CHANGED
@@ -42,7 +42,7 @@ t_begin "send a huge Request URI (REQUEST_PATH > (12 * 1024))" && {
|
|
42
42
|
}
|
43
43
|
|
44
44
|
t_begin "response should be a 414 (REQUEST_PATH)" && {
|
45
|
-
grep -F 'HTTP/1.1 414
|
45
|
+
grep -F 'HTTP/1.1 414 ' $tmp
|
46
46
|
}
|
47
47
|
|
48
48
|
t_begin "send a huge Request URI (QUERY_STRING > (10 * 1024))" && {
|
@@ -63,7 +63,7 @@ t_begin "send a huge Request URI (QUERY_STRING > (10 * 1024))" && {
|
|
63
63
|
}
|
64
64
|
|
65
65
|
t_begin "response should be a 414 (QUERY_STRING)" && {
|
66
|
-
grep -F 'HTTP/1.1 414
|
66
|
+
grep -F 'HTTP/1.1 414 ' $tmp
|
67
67
|
}
|
68
68
|
|
69
69
|
t_begin "send a huge Request URI (FRAGMENT > 1024)" && {
|
@@ -84,7 +84,7 @@ t_begin "send a huge Request URI (FRAGMENT > 1024)" && {
|
|
84
84
|
}
|
85
85
|
|
86
86
|
t_begin "response should be a 414 (FRAGMENT)" && {
|
87
|
-
grep -F 'HTTP/1.1 414
|
87
|
+
grep -F 'HTTP/1.1 414 ' $tmp
|
88
88
|
}
|
89
89
|
|
90
90
|
t_begin "server stderr should be clean" && check_stderr
|
data/test/exec/test_exec.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
|
3
|
-
# Copyright (c) 2005 Zed A. Shaw
|
3
|
+
# Copyright (c) 2005 Zed A. Shaw
|
4
4
|
# You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
|
5
5
|
# the GPLv2+ (GPLv3+ preferred)
|
6
6
|
#
|
7
|
-
# Additional work donated by contributors. See
|
7
|
+
# Additional work donated by contributors. See git history
|
8
8
|
# for more information.
|
9
9
|
|
10
10
|
STDIN.sync = STDOUT.sync = STDERR.sync = true # buffering makes debugging hard
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
|
3
|
-
# Copyright (c) 2005 Zed A. Shaw
|
3
|
+
# Copyright (c) 2005 Zed A. Shaw
|
4
4
|
# You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
|
5
5
|
# the GPLv2+ (GPLv3+ preferred)
|
6
6
|
#
|
7
|
-
# Additional work donated by contributors. See
|
7
|
+
# Additional work donated by contributors. See git history
|
8
8
|
# for more information.
|
9
9
|
|
10
|
-
require 'test/test_helper'
|
10
|
+
require './test/test_helper'
|
11
11
|
|
12
12
|
include Unicorn
|
13
13
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
|
3
|
-
require 'test/test_helper'
|
3
|
+
require './test/test_helper'
|
4
4
|
require 'digest/md5'
|
5
5
|
|
6
6
|
include Unicorn
|
@@ -8,10 +8,15 @@ include Unicorn
|
|
8
8
|
class HttpParserNgTest < Test::Unit::TestCase
|
9
9
|
|
10
10
|
def setup
|
11
|
-
HttpParser.keepalive_requests = HttpParser::KEEPALIVE_REQUESTS_DEFAULT
|
12
11
|
@parser = HttpParser.new
|
13
12
|
end
|
14
13
|
|
14
|
+
def test_parser_max_len
|
15
|
+
assert_raises(RangeError) do
|
16
|
+
HttpParser.max_header_len = 0xffffffff + 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
15
20
|
def test_next_clear
|
16
21
|
r = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
|
17
22
|
@parser.buf << r
|
@@ -29,25 +34,6 @@ class HttpParserNgTest < Test::Unit::TestCase
|
|
29
34
|
assert_equal false, @parser.response_start_sent
|
30
35
|
end
|
31
36
|
|
32
|
-
def test_keepalive_requests_default_constant
|
33
|
-
assert_kind_of Integer, HttpParser::KEEPALIVE_REQUESTS_DEFAULT
|
34
|
-
assert HttpParser::KEEPALIVE_REQUESTS_DEFAULT >= 0
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_keepalive_requests_setting
|
38
|
-
HttpParser.keepalive_requests = 0
|
39
|
-
assert_equal 0, HttpParser.keepalive_requests
|
40
|
-
HttpParser.keepalive_requests = nil
|
41
|
-
assert HttpParser.keepalive_requests >= 0xffffffff
|
42
|
-
HttpParser.keepalive_requests = 1
|
43
|
-
assert_equal 1, HttpParser.keepalive_requests
|
44
|
-
HttpParser.keepalive_requests = 666
|
45
|
-
assert_equal 666, HttpParser.keepalive_requests
|
46
|
-
|
47
|
-
assert_raises(TypeError) { HttpParser.keepalive_requests = "666" }
|
48
|
-
assert_raises(TypeError) { HttpParser.keepalive_requests = [] }
|
49
|
-
end
|
50
|
-
|
51
37
|
def test_connection_TE
|
52
38
|
@parser.buf << "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: TE\r\n"
|
53
39
|
@parser.buf << "TE: trailers\r\n\r\n"
|
@@ -71,41 +57,11 @@ class HttpParserNgTest < Test::Unit::TestCase
|
|
71
57
|
"REQUEST_METHOD" => "GET",
|
72
58
|
"QUERY_STRING" => ""
|
73
59
|
}.freeze
|
74
|
-
|
60
|
+
100.times do |nr|
|
75
61
|
@parser.buf << req
|
76
62
|
assert_equal expect, @parser.parse
|
77
63
|
assert @parser.next?
|
78
64
|
end
|
79
|
-
@parser.buf << req
|
80
|
-
assert_equal expect, @parser.parse
|
81
|
-
assert ! @parser.next?
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_fewer_keepalive_requests_with_next?
|
85
|
-
HttpParser.keepalive_requests = 5
|
86
|
-
@parser = HttpParser.new
|
87
|
-
req = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".freeze
|
88
|
-
expect = {
|
89
|
-
"SERVER_NAME" => "example.com",
|
90
|
-
"HTTP_HOST" => "example.com",
|
91
|
-
"rack.url_scheme" => "http",
|
92
|
-
"REQUEST_PATH" => "/",
|
93
|
-
"SERVER_PROTOCOL" => "HTTP/1.1",
|
94
|
-
"PATH_INFO" => "/",
|
95
|
-
"HTTP_VERSION" => "HTTP/1.1",
|
96
|
-
"REQUEST_URI" => "/",
|
97
|
-
"SERVER_PORT" => "80",
|
98
|
-
"REQUEST_METHOD" => "GET",
|
99
|
-
"QUERY_STRING" => ""
|
100
|
-
}.freeze
|
101
|
-
5.times do |nr|
|
102
|
-
@parser.buf << req
|
103
|
-
assert_equal expect, @parser.parse
|
104
|
-
assert @parser.next?
|
105
|
-
end
|
106
|
-
@parser.buf << req
|
107
|
-
assert_equal expect, @parser.parse
|
108
|
-
assert ! @parser.next?
|
109
65
|
end
|
110
66
|
|
111
67
|
def test_default_keepalive_is_off
|
@@ -663,69 +619,4 @@ class HttpParserNgTest < Test::Unit::TestCase
|
|
663
619
|
assert_equal expect, env2
|
664
620
|
assert_equal "", @parser.buf
|
665
621
|
end
|
666
|
-
|
667
|
-
def test_keepalive_requests_disabled
|
668
|
-
req = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".freeze
|
669
|
-
expect = {
|
670
|
-
"SERVER_NAME" => "example.com",
|
671
|
-
"HTTP_HOST" => "example.com",
|
672
|
-
"rack.url_scheme" => "http",
|
673
|
-
"REQUEST_PATH" => "/",
|
674
|
-
"SERVER_PROTOCOL" => "HTTP/1.1",
|
675
|
-
"PATH_INFO" => "/",
|
676
|
-
"HTTP_VERSION" => "HTTP/1.1",
|
677
|
-
"REQUEST_URI" => "/",
|
678
|
-
"SERVER_PORT" => "80",
|
679
|
-
"REQUEST_METHOD" => "GET",
|
680
|
-
"QUERY_STRING" => ""
|
681
|
-
}.freeze
|
682
|
-
HttpParser.keepalive_requests = 0
|
683
|
-
@parser = HttpParser.new
|
684
|
-
@parser.buf << req
|
685
|
-
assert_equal expect, @parser.parse
|
686
|
-
assert ! @parser.next?
|
687
|
-
end
|
688
|
-
|
689
|
-
def test_chunk_only
|
690
|
-
tmp = ""
|
691
|
-
assert_equal @parser, @parser.dechunk!
|
692
|
-
assert_nil @parser.filter_body(tmp, "6\r\n")
|
693
|
-
assert_equal "", tmp
|
694
|
-
assert_nil @parser.filter_body(tmp, "abcdef")
|
695
|
-
assert_equal "abcdef", tmp
|
696
|
-
assert_nil @parser.filter_body(tmp, "\r\n")
|
697
|
-
assert_equal "", tmp
|
698
|
-
src = "0\r\n\r\n"
|
699
|
-
assert_equal src.object_id, @parser.filter_body(tmp, src).object_id
|
700
|
-
assert_equal "", tmp
|
701
|
-
end
|
702
|
-
|
703
|
-
def test_chunk_only_bad_align
|
704
|
-
tmp = ""
|
705
|
-
assert_equal @parser, @parser.dechunk!
|
706
|
-
assert_nil @parser.filter_body(tmp, "6\r\na")
|
707
|
-
assert_equal "a", tmp
|
708
|
-
assert_nil @parser.filter_body(tmp, "bcde")
|
709
|
-
assert_equal "bcde", tmp
|
710
|
-
assert_nil @parser.filter_body(tmp, "f\r")
|
711
|
-
assert_equal "f", tmp
|
712
|
-
src = "\n0\r\n\r\n"
|
713
|
-
assert_equal src.object_id, @parser.filter_body(tmp, src).object_id
|
714
|
-
assert_equal "", tmp
|
715
|
-
end
|
716
|
-
|
717
|
-
def test_chunk_only_reset_ok
|
718
|
-
tmp = ""
|
719
|
-
assert_equal @parser, @parser.dechunk!
|
720
|
-
src = "1\r\na\r\n0\r\n\r\n"
|
721
|
-
assert_nil @parser.filter_body(tmp, src)
|
722
|
-
assert_equal "a", tmp
|
723
|
-
assert_equal src.object_id, @parser.filter_body(tmp, src).object_id
|
724
|
-
|
725
|
-
assert_equal @parser, @parser.dechunk!
|
726
|
-
src = "0\r\n\r\n"
|
727
|
-
assert_equal src.object_id, @parser.filter_body(tmp, src).object_id
|
728
|
-
assert_equal "", tmp
|
729
|
-
assert_equal src, @parser.filter_body(tmp, src)
|
730
|
-
end
|
731
622
|
end
|