rainbows 0.91.1 → 0.92.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +1 -1
- data/.gitignore +1 -0
- data/.manifest +13 -4
- data/ChangeLog +237 -219
- data/DEPLOY +13 -13
- data/Documentation/comparison.haml +1 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +18 -7
- data/NEWS +29 -0
- data/README +5 -4
- data/Rakefile +7 -0
- data/SIGNALS +5 -1
- data/TODO +2 -5
- data/config/.gitignore +1 -0
- data/config/isolate.rb +25 -0
- data/lib/rainbows/base.rb +32 -8
- data/lib/rainbows/const.rb +3 -2
- data/lib/rainbows/ev_core.rb +42 -2
- data/lib/rainbows/event_machine.rb +48 -5
- data/lib/rainbows/fiber/base.rb +4 -2
- data/lib/rainbows/fiber/rev.rb +1 -1
- data/lib/rainbows/http_response.rb +21 -20
- data/lib/rainbows/http_server.rb +13 -6
- data/lib/rainbows/max_body.rb +82 -0
- data/lib/rainbows/rev/deferred_response.rb +10 -11
- data/lib/rainbows/revactor.rb +38 -4
- data/lib/rainbows/tee_input.rb +17 -0
- data/lib/rainbows.rb +26 -2
- data/local.mk.sample +13 -23
- data/rainbows.gemspec +2 -2
- data/t/app_deferred.ru +23 -0
- data/t/async_examples/async_app.ru +8 -8
- data/t/rack-fiber_pool/app.ru +5 -0
- data/t/{t0100-rack-input-hammer.sh → t0100-rack-input-hammer-chunked.sh} +1 -1
- data/t/t0100-rack-input-hammer-content-length.sh +50 -0
- data/t/t0103-rack-input-limit.sh +60 -0
- data/t/t0104-rack-input-limit-tiny.sh +62 -0
- data/t/t0105-rack-input-limit-bigger.sh +105 -0
- data/t/t0401-em-async-tailer.sh +1 -1
- data/t/t0600-rack-fiber_pool.sh +49 -0
- data/t/t0700-app-deferred.sh +45 -0
- data/t/test-lib.sh +1 -0
- metadata +22 -10
- data/lib/rainbows/event_machine_defer.rb +0 -59
- data/lib/rainbows/revactor/tee_input.rb +0 -52
- data/t/simple-http_EventMachineDefer.ru +0 -11
@@ -0,0 +1,105 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
|
4
|
+
t_plan 10 "rack.input client_max_body_size bigger"
|
5
|
+
|
6
|
+
t_begin "setup and startup" && {
|
7
|
+
rtmpfiles curl_out curl_err cmbs_config
|
8
|
+
rainbows_setup $model
|
9
|
+
sed -e 's/client_max_body_size.*/client_max_body_size 10485760/' \
|
10
|
+
< $unicorn_config > $cmbs_config
|
11
|
+
rainbows -D sha1-random-size.ru -c $cmbs_config
|
12
|
+
rainbows_wait_start
|
13
|
+
}
|
14
|
+
|
15
|
+
t_begin "stops a regular request" && {
|
16
|
+
rm -f $ok
|
17
|
+
dd if=/dev/zero bs=102485761 count=1 of=$tmp
|
18
|
+
curl -vsSf -T $tmp -H Expect: \
|
19
|
+
http://$listen/ > $curl_out 2> $curl_err || > $ok
|
20
|
+
dbgcat curl_err
|
21
|
+
dbgcat curl_out
|
22
|
+
test -e $ok
|
23
|
+
}
|
24
|
+
|
25
|
+
t_begin "stops a large chunked request" && {
|
26
|
+
rm -f $ok
|
27
|
+
dd if=/dev/zero bs=102485761 count=1 | \
|
28
|
+
curl -vsSf -T- -H Expect: \
|
29
|
+
http://$listen/ > $curl_out 2> $curl_err || > $ok
|
30
|
+
dbgcat curl_err
|
31
|
+
dbgcat curl_out
|
32
|
+
test -e $ok
|
33
|
+
}
|
34
|
+
|
35
|
+
t_begin "small size sha1 chunked ok" && {
|
36
|
+
blob_sha1=b376885ac8452b6cbf9ced81b1080bfd570d9b91
|
37
|
+
rm -f $ok
|
38
|
+
dd if=/dev/zero bs=256 count=1 | \
|
39
|
+
curl -vsSf -T- -H Expect: \
|
40
|
+
http://$listen/ > $curl_out 2> $curl_err
|
41
|
+
dbgcat curl_err
|
42
|
+
dbgcat curl_out
|
43
|
+
test "$(cat $curl_out)" = $blob_sha1
|
44
|
+
}
|
45
|
+
|
46
|
+
t_begin "small size sha1 content-length ok" && {
|
47
|
+
blob_sha1=b376885ac8452b6cbf9ced81b1080bfd570d9b91
|
48
|
+
rm -f $ok
|
49
|
+
dd if=/dev/zero bs=256 count=1 of=$tmp
|
50
|
+
curl -vsSf -T $tmp -H Expect: \
|
51
|
+
http://$listen/ > $curl_out 2> $curl_err
|
52
|
+
dbgcat curl_err
|
53
|
+
dbgcat curl_out
|
54
|
+
test "$(cat $curl_out)" = $blob_sha1
|
55
|
+
}
|
56
|
+
|
57
|
+
t_begin "right size sha1 chunked ok" && {
|
58
|
+
blob_sha1=8c206a1a87599f532ce68675536f0b1546900d7a
|
59
|
+
rm -f $ok
|
60
|
+
dd if=/dev/zero bs=10485760 count=1 | \
|
61
|
+
curl -vsSf -T- -H Expect: \
|
62
|
+
http://$listen/ > $curl_out 2> $curl_err
|
63
|
+
dbgcat curl_err
|
64
|
+
dbgcat curl_out
|
65
|
+
test "$(cat $curl_out)" = $blob_sha1
|
66
|
+
}
|
67
|
+
|
68
|
+
t_begin "right size sha1 content-length ok" && {
|
69
|
+
blob_sha1=8c206a1a87599f532ce68675536f0b1546900d7a
|
70
|
+
rm -f $ok
|
71
|
+
dd if=/dev/zero bs=10485760 count=1 of=$tmp
|
72
|
+
curl -vsSf -T $tmp -H Expect: \
|
73
|
+
http://$listen/ > $curl_out 2> $curl_err
|
74
|
+
dbgcat curl_err
|
75
|
+
dbgcat curl_out
|
76
|
+
test "$(cat $curl_out)" = $blob_sha1
|
77
|
+
}
|
78
|
+
|
79
|
+
t_begin "default size sha1 chunked ok" && {
|
80
|
+
blob_sha1=3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3
|
81
|
+
rm -f $ok
|
82
|
+
dd if=/dev/zero bs=1048576 count=1 | \
|
83
|
+
curl -vsSf -T- -H Expect: \
|
84
|
+
http://$listen/ > $curl_out 2> $curl_err
|
85
|
+
dbgcat curl_err
|
86
|
+
dbgcat curl_out
|
87
|
+
test "$(cat $curl_out)" = $blob_sha1
|
88
|
+
}
|
89
|
+
|
90
|
+
t_begin "default size sha1 content-length ok" && {
|
91
|
+
blob_sha1=3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3
|
92
|
+
rm -f $ok
|
93
|
+
dd if=/dev/zero bs=1048576 count=1 of=$tmp
|
94
|
+
curl -vsSf -T $tmp -H Expect: \
|
95
|
+
http://$listen/ > $curl_out 2> $curl_err
|
96
|
+
dbgcat curl_err
|
97
|
+
dbgcat curl_out
|
98
|
+
test "$(cat $curl_out)" = $blob_sha1
|
99
|
+
}
|
100
|
+
|
101
|
+
t_begin "shutdown" && {
|
102
|
+
kill $rainbows_pid
|
103
|
+
}
|
104
|
+
|
105
|
+
t_done
|
data/t/t0401-em-async-tailer.sh
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
case $model in
|
4
|
+
EventMachine) ;;
|
5
|
+
*)
|
6
|
+
t_info "skipping $T since it's not compatible with $model"
|
7
|
+
exit 0
|
8
|
+
;;
|
9
|
+
esac
|
10
|
+
|
11
|
+
require_check rack/fiber_pool Rack::FiberPool
|
12
|
+
|
13
|
+
t_plan 7 "basic test with rack-fiber_pool gem"
|
14
|
+
|
15
|
+
CONFIG_RU=rack-fiber_pool/app.ru
|
16
|
+
|
17
|
+
t_begin "setup and start" && {
|
18
|
+
rainbows_setup
|
19
|
+
rtmpfiles curl_err curl_out
|
20
|
+
|
21
|
+
rainbows -D -c $unicorn_config $CONFIG_RU
|
22
|
+
rainbows_wait_start
|
23
|
+
}
|
24
|
+
|
25
|
+
t_begin "send requests off in parallel" && {
|
26
|
+
curl --no-buffer -sSf http://$listen/ >> $curl_out 2>> $curl_err &
|
27
|
+
curl --no-buffer -sSf http://$listen/ >> $curl_out 2>> $curl_err &
|
28
|
+
curl --no-buffer -sSf http://$listen/ >> $curl_out 2>> $curl_err &
|
29
|
+
}
|
30
|
+
|
31
|
+
t_begin "wait for curl terminations" && {
|
32
|
+
wait
|
33
|
+
}
|
34
|
+
|
35
|
+
t_begin "termination signal sent" && {
|
36
|
+
kill $rainbows_pid
|
37
|
+
}
|
38
|
+
|
39
|
+
t_begin "no errors from curl" && {
|
40
|
+
test ! -s $curl_err
|
41
|
+
}
|
42
|
+
|
43
|
+
t_begin "no errors in stderr" && check_stderr
|
44
|
+
|
45
|
+
t_begin "ensure we hit 3 separate fibers" && {
|
46
|
+
test x3 = x"$(sort < $curl_out | uniq | wc -l)"
|
47
|
+
}
|
48
|
+
|
49
|
+
t_done
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
case $model in
|
4
|
+
EventMachine) ;;
|
5
|
+
*)
|
6
|
+
t_info "skipping $T since it's not compatible with $model"
|
7
|
+
exit 0
|
8
|
+
;;
|
9
|
+
esac
|
10
|
+
|
11
|
+
t_plan 5 "basic test for app.deferred? usage"
|
12
|
+
|
13
|
+
CONFIG_RU=app_deferred.ru
|
14
|
+
|
15
|
+
t_begin "setup and start" && {
|
16
|
+
rainbows_setup
|
17
|
+
rtmpfiles deferred_err deferred_out sync_err sync_out
|
18
|
+
rainbows -D -c $unicorn_config $CONFIG_RU
|
19
|
+
rainbows_wait_start
|
20
|
+
}
|
21
|
+
|
22
|
+
t_begin "synchronous requests run in the same thread" && {
|
23
|
+
curl --no-buffer -sSf http://$listen/ >> $sync_out 2>> $sync_err &
|
24
|
+
curl --no-buffer -sSf http://$listen/ >> $sync_out 2>> $sync_err &
|
25
|
+
curl --no-buffer -sSf http://$listen/ >> $sync_out 2>> $sync_err &
|
26
|
+
wait
|
27
|
+
test ! -s $sync_err
|
28
|
+
test 3 -eq "$(wc -l < $sync_out)"
|
29
|
+
test 1 -eq "$(uniq < $sync_out | wc -l)"
|
30
|
+
}
|
31
|
+
|
32
|
+
t_begin "deferred requests run in a different thread" && {
|
33
|
+
curl -sSf http://$listen/deferred >> $deferred_out 2>> $deferred_err
|
34
|
+
test ! -s $deferred_err
|
35
|
+
sync_thread="$(uniq < $sync_out)"
|
36
|
+
test x"$(uniq < $deferred_out)" != x"$sync_thread"
|
37
|
+
}
|
38
|
+
|
39
|
+
t_begin "termination signal sent" && {
|
40
|
+
kill $rainbows_pid
|
41
|
+
}
|
42
|
+
|
43
|
+
t_begin "no errors in stderr" && check_stderr
|
44
|
+
|
45
|
+
t_done
|
data/t/test-lib.sh
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rainbows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.92.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rainbows! hackers
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-04
|
12
|
+
date: 2010-05-04 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -18,12 +18,15 @@ dependencies:
|
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
|
-
- -
|
21
|
+
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 0.97.1
|
24
|
+
- - <
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.0
|
24
27
|
version:
|
25
28
|
description: |-
|
26
|
-
Rainbows! is an HTTP server for sleepy Rack applications. It is based on
|
29
|
+
\Rainbows! is an HTTP server for sleepy Rack applications. It is based on
|
27
30
|
Unicorn, but designed to handle applications that expect long
|
28
31
|
request/response times and/or slow clients. For Rack applications not
|
29
32
|
heavily bound by slow external network dependencies, consider Unicorn
|
@@ -46,7 +49,6 @@ extra_rdoc_files:
|
|
46
49
|
- lib/rainbows/error.rb
|
47
50
|
- lib/rainbows/ev_core.rb
|
48
51
|
- lib/rainbows/event_machine.rb
|
49
|
-
- lib/rainbows/event_machine_defer.rb
|
50
52
|
- lib/rainbows/fiber.rb
|
51
53
|
- lib/rainbows/fiber/base.rb
|
52
54
|
- lib/rainbows/fiber/io.rb
|
@@ -56,6 +58,7 @@ extra_rdoc_files:
|
|
56
58
|
- lib/rainbows/fiber_spawn.rb
|
57
59
|
- lib/rainbows/http_response.rb
|
58
60
|
- lib/rainbows/http_server.rb
|
61
|
+
- lib/rainbows/max_body.rb
|
59
62
|
- lib/rainbows/never_block.rb
|
60
63
|
- lib/rainbows/never_block/event_machine.rb
|
61
64
|
- lib/rainbows/rev.rb
|
@@ -69,7 +72,7 @@ extra_rdoc_files:
|
|
69
72
|
- lib/rainbows/rev_thread_pool.rb
|
70
73
|
- lib/rainbows/rev_thread_spawn.rb
|
71
74
|
- lib/rainbows/revactor.rb
|
72
|
-
- lib/rainbows/
|
75
|
+
- lib/rainbows/tee_input.rb
|
73
76
|
- lib/rainbows/thread_pool.rb
|
74
77
|
- lib/rainbows/thread_spawn.rb
|
75
78
|
- LICENSE
|
@@ -105,6 +108,8 @@ files:
|
|
105
108
|
- TODO
|
106
109
|
- TUNING
|
107
110
|
- bin/rainbows
|
111
|
+
- config/.gitignore
|
112
|
+
- config/isolate.rb
|
108
113
|
- lib/rainbows.rb
|
109
114
|
- lib/rainbows/actor_spawn.rb
|
110
115
|
- lib/rainbows/app_pool.rb
|
@@ -114,7 +119,6 @@ files:
|
|
114
119
|
- lib/rainbows/error.rb
|
115
120
|
- lib/rainbows/ev_core.rb
|
116
121
|
- lib/rainbows/event_machine.rb
|
117
|
-
- lib/rainbows/event_machine_defer.rb
|
118
122
|
- lib/rainbows/fiber.rb
|
119
123
|
- lib/rainbows/fiber/base.rb
|
120
124
|
- lib/rainbows/fiber/io.rb
|
@@ -124,6 +128,7 @@ files:
|
|
124
128
|
- lib/rainbows/fiber_spawn.rb
|
125
129
|
- lib/rainbows/http_response.rb
|
126
130
|
- lib/rainbows/http_server.rb
|
131
|
+
- lib/rainbows/max_body.rb
|
127
132
|
- lib/rainbows/never_block.rb
|
128
133
|
- lib/rainbows/never_block/event_machine.rb
|
129
134
|
- lib/rainbows/rev.rb
|
@@ -137,7 +142,7 @@ files:
|
|
137
142
|
- lib/rainbows/rev_thread_pool.rb
|
138
143
|
- lib/rainbows/rev_thread_spawn.rb
|
139
144
|
- lib/rainbows/revactor.rb
|
140
|
-
- lib/rainbows/
|
145
|
+
- lib/rainbows/tee_input.rb
|
141
146
|
- lib/rainbows/thread_pool.rb
|
142
147
|
- lib/rainbows/thread_spawn.rb
|
143
148
|
- local.mk.sample
|
@@ -147,6 +152,7 @@ files:
|
|
147
152
|
- t/.gitignore
|
148
153
|
- t/GNUmakefile
|
149
154
|
- t/README
|
155
|
+
- t/app_deferred.ru
|
150
156
|
- t/async-response-no-autochunk.ru
|
151
157
|
- t/async-response.ru
|
152
158
|
- t/async_examples/README
|
@@ -166,11 +172,11 @@ files:
|
|
166
172
|
- t/heartbeat-timeout.ru
|
167
173
|
- t/large-file-response.ru
|
168
174
|
- t/my-tap-lib.sh
|
175
|
+
- t/rack-fiber_pool/app.ru
|
169
176
|
- t/sha1-random-size.ru
|
170
177
|
- t/sha1.ru
|
171
178
|
- t/simple-http_Base.ru
|
172
179
|
- t/simple-http_EventMachine.ru
|
173
|
-
- t/simple-http_EventMachineDefer.ru
|
174
180
|
- t/simple-http_FiberPool.ru
|
175
181
|
- t/simple-http_FiberSpawn.ru
|
176
182
|
- t/simple-http_NeverBlock.ru
|
@@ -200,15 +206,21 @@ files:
|
|
200
206
|
- t/t0012-spurious-wakeups-quiet.sh
|
201
207
|
- t/t0013-reload-bad-config.sh
|
202
208
|
- t/t0014-config-conflict.sh
|
203
|
-
- t/t0100-rack-input-hammer.sh
|
209
|
+
- t/t0100-rack-input-hammer-chunked.sh
|
210
|
+
- t/t0100-rack-input-hammer-content-length.sh
|
204
211
|
- t/t0101-rack-input-trailer.sh
|
205
212
|
- t/t0102-rack-input-short.sh
|
213
|
+
- t/t0103-rack-input-limit.sh
|
214
|
+
- t/t0104-rack-input-limit-tiny.sh
|
215
|
+
- t/t0105-rack-input-limit-bigger.sh
|
206
216
|
- t/t0200-async-response.sh
|
207
217
|
- t/t0201-async-response-no-autochunk.sh
|
208
218
|
- t/t0300-async_sinatra.sh
|
209
219
|
- t/t0400-em-async-app.sh
|
210
220
|
- t/t0401-em-async-tailer.sh
|
211
221
|
- t/t0500-cramp-streaming.sh
|
222
|
+
- t/t0600-rack-fiber_pool.sh
|
223
|
+
- t/t0700-app-deferred.sh
|
212
224
|
- t/t9000-rack-app-pool.sh
|
213
225
|
- t/t9000.ru
|
214
226
|
- t/test-lib.sh
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# -*- encoding: binary -*-
|
2
|
-
# :stopdoc:
|
3
|
-
# FIXME: fails many tests, experimental
|
4
|
-
require 'rainbows/event_machine'
|
5
|
-
|
6
|
-
module Rainbows
|
7
|
-
|
8
|
-
# This is currently highly experimental
|
9
|
-
module EventMachineDefer
|
10
|
-
include Rainbows::EventMachine
|
11
|
-
|
12
|
-
class Client < Rainbows::EventMachine::Client
|
13
|
-
undef_method :app_call
|
14
|
-
|
15
|
-
def defer_op
|
16
|
-
@env[RACK_INPUT] = @input
|
17
|
-
@env[REMOTE_ADDR] = @remote_addr
|
18
|
-
@env[ASYNC_CALLBACK] = method(:response_write)
|
19
|
-
catch(:async) { APP.call(@env.update(RACK_DEFAULTS)) }
|
20
|
-
rescue => e
|
21
|
-
handle_error(e)
|
22
|
-
nil
|
23
|
-
end
|
24
|
-
|
25
|
-
def defer_callback(response)
|
26
|
-
# too tricky to support pipelining with :async since the
|
27
|
-
# second (pipelined) request could be a stuck behind a
|
28
|
-
# long-running async response
|
29
|
-
(response.nil? || -1 == response.first) and return @state = :close
|
30
|
-
|
31
|
-
resume
|
32
|
-
|
33
|
-
alive = @hp.keepalive? && G.alive
|
34
|
-
out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if @hp.headers?
|
35
|
-
response_write(response, out, alive)
|
36
|
-
if alive
|
37
|
-
@env.clear
|
38
|
-
@hp.reset
|
39
|
-
@state = :headers
|
40
|
-
if @hp.headers(@env, @buf)
|
41
|
-
EM.next_tick(method(:app_call))
|
42
|
-
else
|
43
|
-
set_comm_inactivity_timeout(G.kato)
|
44
|
-
end
|
45
|
-
else
|
46
|
-
quit
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def app_call
|
51
|
-
pause
|
52
|
-
set_comm_inactivity_timeout(0)
|
53
|
-
# defer_callback(defer_op)
|
54
|
-
EM.defer(method(:defer_op), method(:defer_callback))
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# -*- encoding: binary -*-
|
2
|
-
require 'rainbows/revactor'
|
3
|
-
|
4
|
-
module Rainbows
|
5
|
-
module Revactor
|
6
|
-
|
7
|
-
# acts like tee(1) on an input input to provide a input-like stream
|
8
|
-
# while providing rewindable semantics through a File/StringIO
|
9
|
-
# backing store. On the first pass, the input is only read on demand
|
10
|
-
# so your Rack application can use input notification (upload progress
|
11
|
-
# and like). This should fully conform to the Rack::InputWrapper
|
12
|
-
# specification on the public API. This class is intended to be a
|
13
|
-
# strict interpretation of Rack::InputWrapper functionality and will
|
14
|
-
# not support any deviations from it.
|
15
|
-
class TeeInput < ::Unicorn::TeeInput
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
# tees off a +length+ chunk of data from the input into the IO
|
20
|
-
# backing store as well as returning it. +dst+ must be specified.
|
21
|
-
# returns nil if reading from the input returns nil
|
22
|
-
def tee(length, dst)
|
23
|
-
unless parser.body_eof?
|
24
|
-
if parser.filter_body(dst, buf << socket.read).nil?
|
25
|
-
tmp.write(dst)
|
26
|
-
diff = dst.size - length
|
27
|
-
if diff > 0
|
28
|
-
dst.replace(dst[0,length])
|
29
|
-
tmp.seek(-diff, IO::SEEK_CUR)
|
30
|
-
end
|
31
|
-
return dst
|
32
|
-
end
|
33
|
-
end
|
34
|
-
finalize_input
|
35
|
-
rescue => e
|
36
|
-
client_error(e)
|
37
|
-
end
|
38
|
-
|
39
|
-
def finalize_input
|
40
|
-
while parser.trailers(req, buf).nil?
|
41
|
-
# Don't worry about raising ClientShutdown here on EOFError, tee()
|
42
|
-
# will catch EOFError when app is processing it, otherwise in
|
43
|
-
# initialize we never get any chance to enter the app so the
|
44
|
-
# EOFError will just get trapped by Unicorn and not the Rack app
|
45
|
-
buf << socket.read
|
46
|
-
end
|
47
|
-
self.socket = nil
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
use Rack::ContentLength
|
2
|
-
use Rack::ContentType
|
3
|
-
run lambda { |env|
|
4
|
-
if env['rack.multithread'] == true &&
|
5
|
-
EM.reactor_running? &&
|
6
|
-
env['rainbows.model'] == :EventMachineDefer
|
7
|
-
[ 200, {}, [ env.inspect << "\n" ] ]
|
8
|
-
else
|
9
|
-
raise "incorrect parameters"
|
10
|
-
end
|
11
|
-
}
|