thin 1.2.3-x86-mswin32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of thin might be problematic. Click here for more details.
- data/CHANGELOG +263 -0
- data/COPYING +18 -0
- data/README +69 -0
- data/Rakefile +36 -0
- data/benchmark/abc +51 -0
- data/benchmark/benchmarker.rb +80 -0
- data/benchmark/runner +82 -0
- data/bin/thin +6 -0
- data/example/adapter.rb +32 -0
- data/example/async_app.ru +126 -0
- data/example/async_chat.ru +247 -0
- data/example/async_tailer.ru +100 -0
- data/example/config.ru +22 -0
- data/example/monit_sockets +20 -0
- data/example/monit_unixsock +20 -0
- data/example/myapp.rb +1 -0
- data/example/ramaze.ru +12 -0
- data/example/thin.god +80 -0
- data/example/thin_solaris_smf.erb +36 -0
- data/example/thin_solaris_smf.readme.txt +150 -0
- data/example/vlad.rake +64 -0
- data/ext/thin_parser/common.rl +55 -0
- data/ext/thin_parser/ext_help.h +14 -0
- data/ext/thin_parser/extconf.rb +6 -0
- data/ext/thin_parser/parser.c +452 -0
- data/ext/thin_parser/parser.h +49 -0
- data/ext/thin_parser/parser.rl +157 -0
- data/ext/thin_parser/thin.c +433 -0
- data/lib/rack/adapter/loader.rb +79 -0
- data/lib/rack/adapter/rails.rb +181 -0
- data/lib/thin.rb +46 -0
- data/lib/thin/backends/base.rb +141 -0
- data/lib/thin/backends/swiftiply_client.rb +56 -0
- data/lib/thin/backends/tcp_server.rb +29 -0
- data/lib/thin/backends/unix_server.rb +51 -0
- data/lib/thin/command.rb +53 -0
- data/lib/thin/connection.rb +222 -0
- data/lib/thin/controllers/cluster.rb +127 -0
- data/lib/thin/controllers/controller.rb +183 -0
- data/lib/thin/controllers/service.rb +75 -0
- data/lib/thin/controllers/service.sh.erb +39 -0
- data/lib/thin/daemonizing.rb +174 -0
- data/lib/thin/headers.rb +39 -0
- data/lib/thin/logging.rb +54 -0
- data/lib/thin/request.rb +153 -0
- data/lib/thin/response.rb +101 -0
- data/lib/thin/runner.rb +209 -0
- data/lib/thin/server.rb +247 -0
- data/lib/thin/stats.html.erb +216 -0
- data/lib/thin/stats.rb +52 -0
- data/lib/thin/statuses.rb +43 -0
- data/lib/thin/version.rb +32 -0
- data/lib/thin_parser.so +0 -0
- data/spec/backends/swiftiply_client_spec.rb +66 -0
- data/spec/backends/tcp_server_spec.rb +33 -0
- data/spec/backends/unix_server_spec.rb +37 -0
- data/spec/command_spec.rb +25 -0
- data/spec/configs/cluster.yml +9 -0
- data/spec/configs/single.yml +9 -0
- data/spec/connection_spec.rb +106 -0
- data/spec/controllers/cluster_spec.rb +235 -0
- data/spec/controllers/controller_spec.rb +129 -0
- data/spec/controllers/service_spec.rb +50 -0
- data/spec/daemonizing_spec.rb +192 -0
- data/spec/headers_spec.rb +40 -0
- data/spec/logging_spec.rb +46 -0
- data/spec/perf/request_perf_spec.rb +50 -0
- data/spec/perf/response_perf_spec.rb +19 -0
- data/spec/perf/server_perf_spec.rb +39 -0
- data/spec/rack/loader_spec.rb +29 -0
- data/spec/rack/rails_adapter_spec.rb +106 -0
- data/spec/rails_app/app/controllers/application.rb +10 -0
- data/spec/rails_app/app/controllers/simple_controller.rb +19 -0
- data/spec/rails_app/app/helpers/application_helper.rb +3 -0
- data/spec/rails_app/app/views/simple/index.html.erb +15 -0
- data/spec/rails_app/config/boot.rb +109 -0
- data/spec/rails_app/config/environment.rb +64 -0
- data/spec/rails_app/config/environments/development.rb +18 -0
- data/spec/rails_app/config/environments/production.rb +19 -0
- data/spec/rails_app/config/environments/test.rb +22 -0
- data/spec/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_app/config/routes.rb +35 -0
- data/spec/rails_app/public/404.html +30 -0
- data/spec/rails_app/public/422.html +30 -0
- data/spec/rails_app/public/500.html +30 -0
- data/spec/rails_app/public/dispatch.cgi +10 -0
- data/spec/rails_app/public/dispatch.fcgi +24 -0
- data/spec/rails_app/public/dispatch.rb +10 -0
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/public/images/rails.png +0 -0
- data/spec/rails_app/public/index.html +277 -0
- data/spec/rails_app/public/javascripts/application.js +2 -0
- data/spec/rails_app/public/javascripts/controls.js +963 -0
- data/spec/rails_app/public/javascripts/dragdrop.js +972 -0
- data/spec/rails_app/public/javascripts/effects.js +1120 -0
- data/spec/rails_app/public/javascripts/prototype.js +4225 -0
- data/spec/rails_app/public/robots.txt +5 -0
- data/spec/rails_app/script/about +3 -0
- data/spec/rails_app/script/console +3 -0
- data/spec/rails_app/script/destroy +3 -0
- data/spec/rails_app/script/generate +3 -0
- data/spec/rails_app/script/performance/benchmarker +3 -0
- data/spec/rails_app/script/performance/profiler +3 -0
- data/spec/rails_app/script/performance/request +3 -0
- data/spec/rails_app/script/plugin +3 -0
- data/spec/rails_app/script/process/inspector +3 -0
- data/spec/rails_app/script/process/reaper +3 -0
- data/spec/rails_app/script/process/spawner +3 -0
- data/spec/rails_app/script/runner +3 -0
- data/spec/rails_app/script/server +3 -0
- data/spec/request/mongrel_spec.rb +39 -0
- data/spec/request/parser_spec.rb +215 -0
- data/spec/request/persistent_spec.rb +35 -0
- data/spec/request/processing_spec.rb +45 -0
- data/spec/response_spec.rb +91 -0
- data/spec/runner_spec.rb +168 -0
- data/spec/server/builder_spec.rb +44 -0
- data/spec/server/pipelining_spec.rb +110 -0
- data/spec/server/robustness_spec.rb +34 -0
- data/spec/server/stopping_spec.rb +55 -0
- data/spec/server/swiftiply.yml +6 -0
- data/spec/server/swiftiply_spec.rb +32 -0
- data/spec/server/tcp_spec.rb +57 -0
- data/spec/server/threaded_spec.rb +27 -0
- data/spec/server/unix_socket_spec.rb +26 -0
- data/spec/server_spec.rb +96 -0
- data/spec/spec_helper.rb +219 -0
- data/tasks/announce.rake +22 -0
- data/tasks/deploy.rake +13 -0
- data/tasks/email.erb +30 -0
- data/tasks/gem.rake +74 -0
- data/tasks/rdoc.rake +25 -0
- data/tasks/site.rake +15 -0
- data/tasks/spec.rake +49 -0
- data/tasks/stats.rake +28 -0
- metadata +246 -0
data/spec/runner_spec.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Runner do
|
4
|
+
it "should parse options" do
|
5
|
+
runner = Runner.new(%w(start --pid test.pid --port 5000 -o 3000))
|
6
|
+
|
7
|
+
runner.options[:pid].should == 'test.pid'
|
8
|
+
runner.options[:port].should == 5000
|
9
|
+
runner.options[:only].should == 3000
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should parse specified command" do
|
13
|
+
Runner.new(%w(start)).command.should == 'start'
|
14
|
+
Runner.new(%w(stop)).command.should == 'stop'
|
15
|
+
Runner.new(%w(restart)).command.should == 'restart'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should abort on unknow command" do
|
19
|
+
runner = Runner.new(%w(poop))
|
20
|
+
|
21
|
+
runner.should_receive(:abort)
|
22
|
+
runner.run!
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should exit on empty command" do
|
26
|
+
runner = Runner.new([])
|
27
|
+
|
28
|
+
runner.should_receive(:exit).with(1)
|
29
|
+
|
30
|
+
silence_stream(STDOUT) do
|
31
|
+
runner.run!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should use Controller when controlling a single server" do
|
36
|
+
runner = Runner.new(%w(start))
|
37
|
+
|
38
|
+
controller = mock('controller')
|
39
|
+
controller.should_receive(:start)
|
40
|
+
Controllers::Controller.should_receive(:new).and_return(controller)
|
41
|
+
|
42
|
+
runner.run!
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should use Cluster controller when controlling multiple servers" do
|
46
|
+
runner = Runner.new(%w(start --servers 3))
|
47
|
+
|
48
|
+
controller = mock('cluster')
|
49
|
+
controller.should_receive(:start)
|
50
|
+
Controllers::Cluster.should_receive(:new).and_return(controller)
|
51
|
+
|
52
|
+
runner.run!
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should default to single server controller" do
|
56
|
+
Runner.new(%w(start)).should_not be_a_cluster
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should consider as a cluster with :servers option" do
|
60
|
+
Runner.new(%w(start --servers 3)).should be_a_cluster
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should consider as a cluster with :only option" do
|
64
|
+
Runner.new(%w(start --only 3000)).should be_a_cluster
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should warn when require a rack config file" do
|
68
|
+
STDERR.stub!(:write)
|
69
|
+
STDERR.should_receive(:write).with(/WARNING:/)
|
70
|
+
|
71
|
+
runner = Runner.new(%w(start -r config.ru))
|
72
|
+
runner.run! rescue nil
|
73
|
+
|
74
|
+
runner.options[:rackup].should == 'config.ru'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should require file" do
|
78
|
+
runner = Runner.new(%w(start -r unexisting))
|
79
|
+
proc { runner.run! }.should raise_error(LoadError)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should remember requires" do
|
83
|
+
runner = Runner.new(%w(start -r rubygems -r thin))
|
84
|
+
runner.options[:require].should == %w(rubygems thin)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should remember debug options" do
|
88
|
+
runner = Runner.new(%w(start -D -V))
|
89
|
+
runner.options[:debug].should be_true
|
90
|
+
runner.options[:trace].should be_true
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should default debug and trace to false" do
|
94
|
+
runner = Runner.new(%w(start))
|
95
|
+
runner.options[:debug].should_not be_true
|
96
|
+
runner.options[:trace].should_not be_true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe Runner, 'with config file' do
|
101
|
+
before do
|
102
|
+
@runner = Runner.new(%w(start --config spec/configs/cluster.yml))
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should load options from file with :config option" do
|
106
|
+
@runner.send :load_options_from_config_file!
|
107
|
+
|
108
|
+
@runner.options[:environment].should == 'production'
|
109
|
+
@runner.options[:chdir].should == 'spec/rails_app'
|
110
|
+
@runner.options[:port].should == 5000
|
111
|
+
@runner.options[:servers].should == 3
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should change directory after loading config" do
|
115
|
+
@orig_dir = Dir.pwd
|
116
|
+
|
117
|
+
controller = mock('controller')
|
118
|
+
controller.should_receive(:respond_to?).with('start').and_return(true)
|
119
|
+
controller.should_receive(:start)
|
120
|
+
Controllers::Cluster.should_receive(:new).and_return(controller)
|
121
|
+
expected_dir = File.expand_path('spec/rails_app')
|
122
|
+
|
123
|
+
begin
|
124
|
+
silence_stream(STDERR) do
|
125
|
+
@runner.run!
|
126
|
+
end
|
127
|
+
|
128
|
+
Dir.pwd.should == expected_dir
|
129
|
+
|
130
|
+
ensure
|
131
|
+
# any other spec using relative paths should work as expected
|
132
|
+
Dir.chdir(@orig_dir)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe Runner, "service" do
|
138
|
+
before do
|
139
|
+
Thin.stub!(:linux?).and_return(true)
|
140
|
+
|
141
|
+
@controller = mock('service')
|
142
|
+
Controllers::Service.stub!(:new).and_return(@controller)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should use Service controller when controlling all servers" do
|
146
|
+
runner = Runner.new(%w(start --all))
|
147
|
+
|
148
|
+
@controller.should_receive(:start)
|
149
|
+
|
150
|
+
runner.run!
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should call install with arguments" do
|
154
|
+
runner = Runner.new(%w(install /etc/cool))
|
155
|
+
|
156
|
+
@controller.should_receive(:install).with('/etc/cool')
|
157
|
+
|
158
|
+
runner.run!
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should call install without arguments" do
|
162
|
+
runner = Runner.new(%w(install))
|
163
|
+
|
164
|
+
@controller.should_receive(:install).with()
|
165
|
+
|
166
|
+
runner.run!
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Server, 'app builder' do
|
4
|
+
it "should build app from constructor" do
|
5
|
+
app = proc {}
|
6
|
+
server = Server.new('0.0.0.0', 3000, app)
|
7
|
+
|
8
|
+
server.app.should == app
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should build app from builder block" do
|
12
|
+
server = Server.new '0.0.0.0', 3000 do
|
13
|
+
run(proc { |env| :works })
|
14
|
+
end
|
15
|
+
|
16
|
+
server.app.call({}).should == :works
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should use middlewares in builder block" do
|
20
|
+
server = Server.new '0.0.0.0', 3000 do
|
21
|
+
use Rack::ShowExceptions
|
22
|
+
run(proc { |env| :works })
|
23
|
+
end
|
24
|
+
|
25
|
+
server.app.class.should == Rack::ShowExceptions
|
26
|
+
server.app.call({}).should == :works
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should work with Rack url mapper" do
|
30
|
+
server = Server.new '0.0.0.0', 3000 do
|
31
|
+
map '/test' do
|
32
|
+
run(proc { |env| [200, {}, 'Found /test'] })
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
default_env = { 'SCRIPT_NAME' => '' }
|
37
|
+
|
38
|
+
server.app.call(default_env.update('PATH_INFO' => '/'))[0].should == 404
|
39
|
+
|
40
|
+
status, headers, body = server.app.call(default_env.update('PATH_INFO' => '/test'))
|
41
|
+
status.should == 200
|
42
|
+
body.should == 'Found /test'
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Server, "HTTP pipelining" do
|
4
|
+
before do
|
5
|
+
calls = 0
|
6
|
+
start_server do |env|
|
7
|
+
calls += 1
|
8
|
+
body = env['PATH_INFO'] + '-' + calls.to_s
|
9
|
+
[200, { 'Content-Type' => 'text/html' }, body]
|
10
|
+
end
|
11
|
+
@server.maximum_persistent_connections = 1024
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should pipeline request on same socket" do
|
15
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
16
|
+
socket.write "GET /first HTTP/1.1\r\nConnection: keep-alive\r\n\r\n"
|
17
|
+
socket.flush
|
18
|
+
socket.write "GET /second HTTP/1.1\r\nConnection: close\r\n\r\n"
|
19
|
+
socket.flush
|
20
|
+
response = socket.read
|
21
|
+
socket.close
|
22
|
+
|
23
|
+
wait_for_requests_to_complete!
|
24
|
+
|
25
|
+
response.should include('/first-1', '/second-2')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should pipeline requests by default on HTTP 1.1" do
|
29
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
30
|
+
socket.write "GET /first HTTP/1.1\r\n\r\n"
|
31
|
+
socket.flush
|
32
|
+
socket.write "GET /second HTTP/1.1\r\nConnection: close\r\n\r\n"
|
33
|
+
socket.flush
|
34
|
+
response = socket.read
|
35
|
+
socket.close
|
36
|
+
|
37
|
+
wait_for_requests_to_complete!
|
38
|
+
|
39
|
+
response.should include('/first-1', '/second-2')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should not pipeline request by default on HTTP 1.0" do
|
43
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
44
|
+
socket.write "GET /first HTTP/1.0\r\n\r\n"
|
45
|
+
socket.flush
|
46
|
+
socket.write "GET /second HTTP/1.0\r\nConnection: close\r\n\r\n"
|
47
|
+
response = socket.read
|
48
|
+
socket.close
|
49
|
+
|
50
|
+
wait_for_requests_to_complete!
|
51
|
+
|
52
|
+
response.should include('/first-1')
|
53
|
+
response.should_not include('/second-2')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not pipeline request on same socket when connection is closed" do
|
57
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
58
|
+
socket.write "GET /first HTTP/1.1\r\nConnection: close\r\n\r\n"
|
59
|
+
socket.flush
|
60
|
+
socket.write "GET /second HTTP/1.1\r\nConnection: close\r\n\r\n"
|
61
|
+
response = socket.read
|
62
|
+
socket.close
|
63
|
+
|
64
|
+
wait_for_requests_to_complete!
|
65
|
+
|
66
|
+
response.should include('/first-1')
|
67
|
+
response.should_not include('/second-2')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not allow more persistent connection then maximum" do
|
71
|
+
@server.maximum_persistent_connections = 1
|
72
|
+
|
73
|
+
socket1 = TCPSocket.new('0.0.0.0', 3333)
|
74
|
+
socket1.write "GET / HTTP/1.1\r\n\r\n"
|
75
|
+
socket1.flush
|
76
|
+
socket2 = TCPSocket.new('0.0.0.0', 3333)
|
77
|
+
socket2.write "GET / HTTP/1.1\r\n\r\n"
|
78
|
+
socket2.flush
|
79
|
+
|
80
|
+
@server.backend.persistent_connection_count.should == 1
|
81
|
+
@server.backend.size.should == 2
|
82
|
+
|
83
|
+
socket1.close
|
84
|
+
socket2.close
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should decrement persistent connection on close" do
|
88
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
89
|
+
socket.write "GET / HTTP/1.1\r\n\r\n"
|
90
|
+
socket.flush
|
91
|
+
|
92
|
+
@server.backend.persistent_connection_count.should == 1
|
93
|
+
|
94
|
+
socket.write "GET / HTTP/1.1\r\nConnection: close\r\n\r\n"
|
95
|
+
socket.close
|
96
|
+
|
97
|
+
wait_for_requests_to_complete!
|
98
|
+
|
99
|
+
@server.backend.persistent_connection_count.should == 0
|
100
|
+
end
|
101
|
+
|
102
|
+
after do
|
103
|
+
stop_server
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
def wait_for_requests_to_complete!
|
108
|
+
sleep 0.1 until @server.backend.size == 0
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Server, 'robustness' do
|
4
|
+
before do
|
5
|
+
start_server do |env|
|
6
|
+
body = 'hello!'
|
7
|
+
[200, { 'Content-Type' => 'text/html' }, body]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not crash when header too large" do
|
12
|
+
100.times do
|
13
|
+
begin
|
14
|
+
socket = TCPSocket.new(DEFAULT_TEST_ADDRESS, DEFAULT_TEST_PORT)
|
15
|
+
socket.write("GET / HTTP/1.1\r\n")
|
16
|
+
socket.write("Host: localhost\r\n")
|
17
|
+
socket.write("Connection: close\r\n")
|
18
|
+
10000.times do
|
19
|
+
socket.write("X-Foo: #{'x' * 100}\r\n")
|
20
|
+
socket.flush
|
21
|
+
end
|
22
|
+
socket.write("\r\n")
|
23
|
+
socket.read
|
24
|
+
socket.close
|
25
|
+
rescue Errno::EPIPE, Errno::ECONNRESET
|
26
|
+
# Ignore.
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
stop_server
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Server, "stopping" do
|
4
|
+
before do
|
5
|
+
start_server do |env|
|
6
|
+
[200, { 'Content-Type' => 'text/html' }, ['ok']]
|
7
|
+
end
|
8
|
+
@done = false
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should wait for current requests before soft stopping" do
|
12
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
13
|
+
socket.write("GET / HTTP/1.1")
|
14
|
+
EventMachine.next_tick do
|
15
|
+
@server.stop # Stop the server in the middle of a request
|
16
|
+
socket.write("\r\n\r\n")
|
17
|
+
@done = true
|
18
|
+
end
|
19
|
+
|
20
|
+
timeout(2) do
|
21
|
+
Thread.pass until @done
|
22
|
+
end
|
23
|
+
|
24
|
+
out = socket.read
|
25
|
+
socket.close
|
26
|
+
|
27
|
+
out.should_not be_empty
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should not accept new requests when soft stopping" do
|
31
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
32
|
+
socket.write("GET / HTTP/1.1")
|
33
|
+
@server.stop # Stop the server in the middle of a request
|
34
|
+
|
35
|
+
EventMachine.next_tick do
|
36
|
+
proc { get('/') }.should raise_error(Errno::ECONNRESET)
|
37
|
+
end
|
38
|
+
|
39
|
+
socket.close
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should drop current requests when hard stopping" do
|
43
|
+
socket = TCPSocket.new('0.0.0.0', 3333)
|
44
|
+
socket.write("GET / HTTP/1.1")
|
45
|
+
@server.stop! # Force stop the server in the middle of a request
|
46
|
+
|
47
|
+
EventMachine.next_tick do
|
48
|
+
socket.should be_closed
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
after do
|
53
|
+
stop_server
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
if SWIFTIPLY_PATH.empty?
|
4
|
+
warn "Ignoring Server on Swiftiply specs, gem install swiftiply to run"
|
5
|
+
else
|
6
|
+
describe Server, 'on Swiftiply' do
|
7
|
+
before do
|
8
|
+
@swiftiply = fork do
|
9
|
+
exec "#{SWIFTIPLY_PATH} -c #{File.dirname(__FILE__)}/swiftiply.yml"
|
10
|
+
end
|
11
|
+
wait_for_socket('0.0.0.0', 3333)
|
12
|
+
sleep 2 # HACK ooh boy, I wish I knew how to make those specs more stable...
|
13
|
+
start_server('0.0.0.0', 5555, :backend => Backends::SwiftiplyClient, :wait_for_socket => false) do |env|
|
14
|
+
body = env.inspect + env['rack.input'].read
|
15
|
+
[200, { 'Content-Type' => 'text/html' }, body]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should GET from Net::HTTP' do
|
20
|
+
Net::HTTP.get(URI.parse("http://0.0.0.0:3333/?cthis")).should include('cthis')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should POST from Net::HTTP' do
|
24
|
+
Net::HTTP.post_form(URI.parse("http://0.0.0.0:3333/"), :arg => 'pirate').body.should include('arg=pirate')
|
25
|
+
end
|
26
|
+
|
27
|
+
after do
|
28
|
+
stop_server
|
29
|
+
Process.kill(9, @swiftiply)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|