rsense-server 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +14 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +1 -0
- data/README.md +51 -0
- data/Rakefile +9 -0
- data/bin/_rsense.rb +115 -0
- data/config/puma.rb +2 -0
- data/lib/rsense/server/code.rb +38 -0
- data/lib/rsense/server/command/completion_result.rb +11 -0
- data/lib/rsense/server/command/special_meth.rb +18 -0
- data/lib/rsense/server/command/type_inference_method.rb +24 -0
- data/lib/rsense/server/command.rb +239 -0
- data/lib/rsense/server/config.rb +70 -0
- data/lib/rsense/server/gem_path.rb +18 -0
- data/lib/rsense/server/listeners/find_definition_event_listener.rb +91 -0
- data/lib/rsense/server/listeners/where_event_listener.rb +39 -0
- data/lib/rsense/server/load_path.rb +62 -0
- data/lib/rsense/server/options.rb +85 -0
- data/lib/rsense/server/parser.rb +17 -0
- data/lib/rsense/server/path_info.rb +17 -0
- data/lib/rsense/server/project.rb +24 -0
- data/lib/rsense/server/version.rb +5 -0
- data/lib/rsense/server.rb +18 -0
- data/rsense-server.gemspec +35 -0
- data/spec/fixtures/config_fixture/.rsense +4 -0
- data/spec/fixtures/deeply/nested/thing.rb +0 -0
- data/spec/fixtures/find_def_sample.json +10 -0
- data/spec/fixtures/sample.json +10 -0
- data/spec/fixtures/test_gem/.gitignore +22 -0
- data/spec/fixtures/test_gem/Gemfile +4 -0
- data/spec/fixtures/test_gem/LICENSE.txt +22 -0
- data/spec/fixtures/test_gem/README.md +29 -0
- data/spec/fixtures/test_gem/Rakefile +2 -0
- data/spec/fixtures/test_gem/lib/sample/version.rb +3 -0
- data/spec/fixtures/test_gem/lib/sample.rb +16 -0
- data/spec/fixtures/test_gem/sample.gemspec +23 -0
- data/spec/fixtures/test_gem/test.json +10 -0
- data/spec/rsense/server/code_spec.rb +44 -0
- data/spec/rsense/server/command/special_meth_spec.rb +23 -0
- data/spec/rsense/server/command_spec.rb +108 -0
- data/spec/rsense/server/config_spec.rb +27 -0
- data/spec/rsense/server/gem_path_spec.rb +16 -0
- data/spec/rsense/server/load_path_spec.rb +63 -0
- data/spec/rsense/server/options_spec.rb +33 -0
- data/spec/rsense/server/path_info_spec.rb +11 -0
- data/spec/rsense/server/project_spec.rb +18 -0
- data/spec/rsense/server_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -0
- data/vendor/gems/puma-2.8.2-java/COPYING +55 -0
- data/vendor/gems/puma-2.8.2-java/DEPLOYMENT.md +92 -0
- data/vendor/gems/puma-2.8.2-java/Gemfile +17 -0
- data/vendor/gems/puma-2.8.2-java/History.txt +532 -0
- data/vendor/gems/puma-2.8.2-java/LICENSE +26 -0
- data/vendor/gems/puma-2.8.2-java/Manifest.txt +68 -0
- data/vendor/gems/puma-2.8.2-java/README.md +251 -0
- data/vendor/gems/puma-2.8.2-java/Rakefile +158 -0
- data/vendor/gems/puma-2.8.2-java/bin/puma +10 -0
- data/vendor/gems/puma-2.8.2-java/bin/puma-wild +17 -0
- data/vendor/gems/puma-2.8.2-java/bin/pumactl +12 -0
- data/vendor/gems/puma-2.8.2-java/docs/config.md +0 -0
- data/vendor/gems/puma-2.8.2-java/docs/nginx.md +80 -0
- data/vendor/gems/puma-2.8.2-java/docs/signals.md +42 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/PumaHttp11Service.java +17 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/ext_help.h +15 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/extconf.rb +8 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.c +1225 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.h +64 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.java.rl +161 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.rl +146 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser_common.rl +54 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/io_buffer.c +155 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/mini_ssl.c +195 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11.java +225 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11Parser.java +488 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/MiniSSL.java +289 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/puma_http11.c +491 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/accept_nonblock.rb +23 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/app/status.rb +59 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/binder.rb +298 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/capistrano.rb +86 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/cli.rb +587 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/client.rb +289 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/cluster.rb +389 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/compat.rb +18 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/configuration.rb +377 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/const.rb +165 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb +251 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/daemon_ext.rb +25 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/delegation.rb +11 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/detect.rb +4 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/events.rb +130 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/io_buffer.rb +7 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/java_io_buffer.rb +45 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/jruby_restart.rb +83 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/minissl.rb +148 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/null_io.rb +34 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/puma_http11.jar +0 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/rack_default.rb +7 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/rack_patch.rb +45 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/reactor.rb +183 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/runner.rb +146 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/server.rb +801 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/single.rb +102 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/tcp_logger.rb +32 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/thread_pool.rb +185 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/util.rb +9 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma.rb +14 -0
- data/vendor/gems/puma-2.8.2-java/lib/rack/handler/puma.rb +66 -0
- data/vendor/gems/puma-2.8.2-java/puma.gemspec +55 -0
- data/vendor/gems/puma-2.8.2-java/test/test_app_status.rb +92 -0
- data/vendor/gems/puma-2.8.2-java/test/test_cli.rb +173 -0
- data/vendor/gems/puma-2.8.2-java/test/test_config.rb +26 -0
- data/vendor/gems/puma-2.8.2-java/test/test_http10.rb +27 -0
- data/vendor/gems/puma-2.8.2-java/test/test_http11.rb +144 -0
- data/vendor/gems/puma-2.8.2-java/test/test_integration.rb +165 -0
- data/vendor/gems/puma-2.8.2-java/test/test_iobuffer.rb +38 -0
- data/vendor/gems/puma-2.8.2-java/test/test_minissl.rb +25 -0
- data/vendor/gems/puma-2.8.2-java/test/test_null_io.rb +31 -0
- data/vendor/gems/puma-2.8.2-java/test/test_persistent.rb +238 -0
- data/vendor/gems/puma-2.8.2-java/test/test_puma_server.rb +323 -0
- data/vendor/gems/puma-2.8.2-java/test/test_rack_handler.rb +10 -0
- data/vendor/gems/puma-2.8.2-java/test/test_rack_server.rb +141 -0
- data/vendor/gems/puma-2.8.2-java/test/test_tcp_rack.rb +42 -0
- data/vendor/gems/puma-2.8.2-java/test/test_thread_pool.rb +156 -0
- data/vendor/gems/puma-2.8.2-java/test/test_unix_socket.rb +39 -0
- data/vendor/gems/puma-2.8.2-java/test/test_ws.rb +89 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/README.md +9 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/README.md +54 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/puma +332 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/run-puma +3 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/README.md +61 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma-manager.conf +31 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma.conf +63 -0
- data/vendor/gems/puma-2.8.2-java/tools/trickletest.rb +45 -0
- metadata +389 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
require "rbconfig"
|
2
|
+
require 'test/unit'
|
3
|
+
require 'puma/cli'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
class TestCLI < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@environment = 'production'
|
9
|
+
@tmp_file = Tempfile.new("puma-test")
|
10
|
+
@tmp_path = @tmp_file.path
|
11
|
+
@tmp_file.close!
|
12
|
+
|
13
|
+
@tmp_path2 = "#{@tmp_path}2"
|
14
|
+
|
15
|
+
File.unlink @tmp_path if File.exist? @tmp_path
|
16
|
+
File.unlink @tmp_path2 if File.exist? @tmp_path2
|
17
|
+
|
18
|
+
@wait, @ready = IO.pipe
|
19
|
+
|
20
|
+
@events = Events.strings
|
21
|
+
@events.on_booted { @ready << "!" }
|
22
|
+
end
|
23
|
+
|
24
|
+
def wait_booted
|
25
|
+
@wait.sysread 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
File.unlink @tmp_path if File.exist? @tmp_path
|
30
|
+
File.unlink @tmp_path2 if File.exist? @tmp_path2
|
31
|
+
|
32
|
+
@wait.close
|
33
|
+
@ready.close
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_pid_file
|
37
|
+
cli = Puma::CLI.new ["--pidfile", @tmp_path]
|
38
|
+
cli.parse_options
|
39
|
+
cli.write_pid
|
40
|
+
|
41
|
+
assert_equal File.read(@tmp_path).strip.to_i, Process.pid
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_control_for_tcp
|
45
|
+
url = "tcp://127.0.0.1:9877/"
|
46
|
+
cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:9876",
|
47
|
+
"--control", url,
|
48
|
+
"--control-token", "",
|
49
|
+
"test/lobster.ru"], @events
|
50
|
+
|
51
|
+
cli.parse_options
|
52
|
+
|
53
|
+
thread_exception = nil
|
54
|
+
t = Thread.new do
|
55
|
+
begin
|
56
|
+
cli.run
|
57
|
+
rescue Exception => e
|
58
|
+
thread_exception = e
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
wait_booted
|
63
|
+
|
64
|
+
s = TCPSocket.new "127.0.0.1", 9877
|
65
|
+
s << "GET /stats HTTP/1.0\r\n\r\n"
|
66
|
+
body = s.read
|
67
|
+
assert_equal '{ "backlog": 0, "running": 0 }', body.split("\r\n").last
|
68
|
+
|
69
|
+
cli.stop
|
70
|
+
t.join
|
71
|
+
assert_equal nil, thread_exception
|
72
|
+
end
|
73
|
+
|
74
|
+
unless defined?(JRUBY_VERSION) || RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
|
75
|
+
def test_control
|
76
|
+
url = "unix://#{@tmp_path}"
|
77
|
+
|
78
|
+
cli = Puma::CLI.new ["-b", "unix://#{@tmp_path2}",
|
79
|
+
"--control", url,
|
80
|
+
"--control-token", "",
|
81
|
+
"test/lobster.ru"], @events
|
82
|
+
cli.parse_options
|
83
|
+
|
84
|
+
t = Thread.new { cli.run }
|
85
|
+
|
86
|
+
wait_booted
|
87
|
+
|
88
|
+
s = UNIXSocket.new @tmp_path
|
89
|
+
s << "GET /stats HTTP/1.0\r\n\r\n"
|
90
|
+
body = s.read
|
91
|
+
|
92
|
+
assert_equal '{ "backlog": 0, "running": 0 }', body.split("\r\n").last
|
93
|
+
|
94
|
+
cli.stop
|
95
|
+
t.join
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_control_stop
|
99
|
+
url = "unix://#{@tmp_path}"
|
100
|
+
|
101
|
+
cli = Puma::CLI.new ["-b", "unix://#{@tmp_path2}",
|
102
|
+
"--control", url,
|
103
|
+
"--control-token", "",
|
104
|
+
"test/lobster.ru"], @events
|
105
|
+
cli.parse_options
|
106
|
+
|
107
|
+
t = Thread.new { cli.run }
|
108
|
+
|
109
|
+
wait_booted
|
110
|
+
|
111
|
+
s = UNIXSocket.new @tmp_path
|
112
|
+
s << "GET /stop HTTP/1.0\r\n\r\n"
|
113
|
+
body = s.read
|
114
|
+
|
115
|
+
assert_equal '{ "status": "ok" }', body.split("\r\n").last
|
116
|
+
|
117
|
+
t.join
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_tmp_control
|
121
|
+
url = "tcp://127.0.0.1:8232"
|
122
|
+
cli = Puma::CLI.new ["--state", @tmp_path, "--control", "auto"]
|
123
|
+
cli.parse_options
|
124
|
+
cli.write_state
|
125
|
+
|
126
|
+
data = YAML.load File.read(@tmp_path)
|
127
|
+
|
128
|
+
assert_equal Process.pid, data["pid"]
|
129
|
+
|
130
|
+
url = data["config"].options[:control_url]
|
131
|
+
|
132
|
+
m = %r!unix://(.*)!.match(url)
|
133
|
+
|
134
|
+
assert m, "'#{url}' is not a URL"
|
135
|
+
end
|
136
|
+
end # JRUBY or Windows
|
137
|
+
|
138
|
+
def test_state
|
139
|
+
url = "tcp://127.0.0.1:8232"
|
140
|
+
cli = Puma::CLI.new ["--state", @tmp_path, "--control", url]
|
141
|
+
cli.parse_options
|
142
|
+
cli.write_state
|
143
|
+
|
144
|
+
data = YAML.load File.read(@tmp_path)
|
145
|
+
|
146
|
+
assert_equal Process.pid, data["pid"]
|
147
|
+
assert_equal url, data["config"].options[:control_url]
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_load_path
|
151
|
+
cli = Puma::CLI.new ["--include", 'foo/bar']
|
152
|
+
cli.parse_options
|
153
|
+
|
154
|
+
assert_equal 'foo/bar', $LOAD_PATH[0]
|
155
|
+
$LOAD_PATH.shift
|
156
|
+
|
157
|
+
cli = Puma::CLI.new ["--include", 'foo/bar:baz/qux']
|
158
|
+
cli.parse_options
|
159
|
+
|
160
|
+
assert_equal 'foo/bar', $LOAD_PATH[0]
|
161
|
+
$LOAD_PATH.shift
|
162
|
+
assert_equal 'baz/qux', $LOAD_PATH[0]
|
163
|
+
$LOAD_PATH.shift
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_environment
|
167
|
+
cli = Puma::CLI.new ["--environment", @environment]
|
168
|
+
cli.parse_options
|
169
|
+
cli.set_rack_environment
|
170
|
+
|
171
|
+
assert_equal ENV['RACK_ENV'], @environment
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'puma'
|
4
|
+
require 'puma/configuration'
|
5
|
+
|
6
|
+
class TestConfigFile < Test::Unit::TestCase
|
7
|
+
def test_app_from_app_DSL
|
8
|
+
opts = { :config_file => "test/config/app.rb" }
|
9
|
+
conf = Puma::Configuration.new opts
|
10
|
+
conf.load
|
11
|
+
|
12
|
+
app = conf.app
|
13
|
+
|
14
|
+
assert_equal [200, {}, ["embedded app"]], app.call({})
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_lowleve_error_handler_DSL
|
18
|
+
opts = { :config_file => "test/config/app.rb" }
|
19
|
+
conf = Puma::Configuration.new opts
|
20
|
+
conf.load
|
21
|
+
|
22
|
+
app = conf.options[:lowlevel_error_handler]
|
23
|
+
|
24
|
+
assert_equal [200, {}, ["error page"]], app.call({})
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test/testhelp'
|
2
|
+
|
3
|
+
class Http10ParserTest < Test::Unit::TestCase
|
4
|
+
include Puma
|
5
|
+
|
6
|
+
def test_parse_simple
|
7
|
+
parser = HttpParser.new
|
8
|
+
req = {}
|
9
|
+
http = "GET / HTTP/1.0\r\n\r\n"
|
10
|
+
nread = parser.execute(req, http, 0)
|
11
|
+
|
12
|
+
assert nread == http.length, "Failed to parse the full HTTP request"
|
13
|
+
assert parser.finished?, "Parser didn't finish"
|
14
|
+
assert !parser.error?, "Parser had error"
|
15
|
+
assert nread == parser.nread, "Number read returned from execute does not match"
|
16
|
+
|
17
|
+
assert_equal '/', req['REQUEST_PATH']
|
18
|
+
assert_equal 'HTTP/1.0', req['HTTP_VERSION']
|
19
|
+
assert_equal '/', req['REQUEST_URI']
|
20
|
+
assert_equal 'GET', req['REQUEST_METHOD']
|
21
|
+
assert_nil req['FRAGMENT']
|
22
|
+
assert_nil req['QUERY_STRING']
|
23
|
+
|
24
|
+
parser.reset
|
25
|
+
assert parser.nread == 0, "Number read after reset should be 0"
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# Copyright (c) 2011 Evan Phoenix
|
2
|
+
# Copyright (c) 2005 Zed A. Shaw
|
3
|
+
|
4
|
+
require 'testhelp'
|
5
|
+
|
6
|
+
include Puma
|
7
|
+
|
8
|
+
class Http11ParserTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def test_parse_simple
|
11
|
+
parser = HttpParser.new
|
12
|
+
req = {}
|
13
|
+
http = "GET / HTTP/1.1\r\n\r\n"
|
14
|
+
nread = parser.execute(req, http, 0)
|
15
|
+
|
16
|
+
assert nread == http.length, "Failed to parse the full HTTP request"
|
17
|
+
assert parser.finished?, "Parser didn't finish"
|
18
|
+
assert !parser.error?, "Parser had error"
|
19
|
+
assert nread == parser.nread, "Number read returned from execute does not match"
|
20
|
+
|
21
|
+
assert_equal '/', req['REQUEST_PATH']
|
22
|
+
assert_equal 'HTTP/1.1', req['HTTP_VERSION']
|
23
|
+
assert_equal '/', req['REQUEST_URI']
|
24
|
+
assert_equal 'GET', req['REQUEST_METHOD']
|
25
|
+
assert_nil req['FRAGMENT']
|
26
|
+
assert_nil req['QUERY_STRING']
|
27
|
+
|
28
|
+
parser.reset
|
29
|
+
assert parser.nread == 0, "Number read after reset should be 0"
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_parse_dumbfuck_headers
|
33
|
+
parser = HttpParser.new
|
34
|
+
req = {}
|
35
|
+
should_be_good = "GET / HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n"
|
36
|
+
nread = parser.execute(req, should_be_good, 0)
|
37
|
+
assert_equal should_be_good.length, nread
|
38
|
+
assert parser.finished?
|
39
|
+
assert !parser.error?
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_parse_error
|
43
|
+
parser = HttpParser.new
|
44
|
+
req = {}
|
45
|
+
bad_http = "GET / SsUTF/1.1"
|
46
|
+
|
47
|
+
error = false
|
48
|
+
begin
|
49
|
+
parser.execute(req, bad_http, 0)
|
50
|
+
rescue
|
51
|
+
error = true
|
52
|
+
end
|
53
|
+
|
54
|
+
assert error, "failed to throw exception"
|
55
|
+
assert !parser.finished?, "Parser shouldn't be finished"
|
56
|
+
assert parser.error?, "Parser SHOULD have error"
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_fragment_in_uri
|
60
|
+
parser = HttpParser.new
|
61
|
+
req = {}
|
62
|
+
get = "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n"
|
63
|
+
assert_nothing_raised do
|
64
|
+
parser.execute(req, get, 0)
|
65
|
+
end
|
66
|
+
assert parser.finished?
|
67
|
+
assert_equal '/forums/1/topics/2375?page=1', req['REQUEST_URI']
|
68
|
+
assert_equal 'posts-17408', req['FRAGMENT']
|
69
|
+
end
|
70
|
+
|
71
|
+
# lame random garbage maker
|
72
|
+
def rand_data(min, max, readable=true)
|
73
|
+
count = min + ((rand(max)+1) *10).to_i
|
74
|
+
res = count.to_s + "/"
|
75
|
+
|
76
|
+
if readable
|
77
|
+
res << Digest::SHA1.hexdigest(rand(count * 100).to_s) * (count / 40)
|
78
|
+
else
|
79
|
+
res << Digest::SHA1.digest(rand(count * 100).to_s) * (count / 20)
|
80
|
+
end
|
81
|
+
|
82
|
+
return res
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_max_uri_path_length
|
86
|
+
parser = HttpParser.new
|
87
|
+
req = {}
|
88
|
+
|
89
|
+
# Support URI path length to a max of 2048
|
90
|
+
path = "/" + rand_data(1000, 100)
|
91
|
+
http = "GET #{path} HTTP/1.1\r\n\r\n"
|
92
|
+
parser.execute(req, http, 0)
|
93
|
+
assert_equal path, req['REQUEST_PATH']
|
94
|
+
parser.reset
|
95
|
+
|
96
|
+
# Raise exception if URI path length > 2048
|
97
|
+
path = "/" + rand_data(2049, 100)
|
98
|
+
http = "GET #{path} HTTP/1.1\r\n\r\n"
|
99
|
+
assert_raises Puma::HttpParserError do
|
100
|
+
parser.execute(req, http, 0)
|
101
|
+
parser.reset
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_horrible_queries
|
106
|
+
parser = HttpParser.new
|
107
|
+
|
108
|
+
# then that large header names are caught
|
109
|
+
10.times do |c|
|
110
|
+
get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-#{rand_data(1024, 1024+(c*1024))}: Test\r\n\r\n"
|
111
|
+
assert_raises Puma::HttpParserError do
|
112
|
+
parser.execute({}, get, 0)
|
113
|
+
parser.reset
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# then that large mangled field values are caught
|
118
|
+
10.times do |c|
|
119
|
+
get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-Test: #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
|
120
|
+
assert_raises Puma::HttpParserError do
|
121
|
+
parser.execute({}, get, 0)
|
122
|
+
parser.reset
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# then large headers are rejected too
|
127
|
+
get = "GET /#{rand_data(10,120)} HTTP/1.1\r\n"
|
128
|
+
get << "X-Test: test\r\n" * (80 * 1024)
|
129
|
+
assert_raises Puma::HttpParserError do
|
130
|
+
parser.execute({}, get, 0)
|
131
|
+
parser.reset
|
132
|
+
end
|
133
|
+
|
134
|
+
# finally just that random garbage gets blocked all the time
|
135
|
+
10.times do |c|
|
136
|
+
get = "GET #{rand_data(1024, 1024+(c*1024), false)} #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
|
137
|
+
assert_raises Puma::HttpParserError do
|
138
|
+
parser.execute({}, get, 0)
|
139
|
+
parser.reset
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require "rbconfig"
|
2
|
+
require 'test/unit'
|
3
|
+
require 'socket'
|
4
|
+
require 'timeout'
|
5
|
+
require 'net/http'
|
6
|
+
require 'tempfile'
|
7
|
+
|
8
|
+
require 'puma/cli'
|
9
|
+
require 'puma/control_cli'
|
10
|
+
|
11
|
+
# These don't run on travis because they're too fragile
|
12
|
+
|
13
|
+
class TestIntegration < Test::Unit::TestCase
|
14
|
+
def setup
|
15
|
+
@state_path = "test/test_puma.state"
|
16
|
+
@bind_path = "test/test_server.sock"
|
17
|
+
@control_path = "test/test_control.sock"
|
18
|
+
@tcp_port = 9998
|
19
|
+
|
20
|
+
@server = nil
|
21
|
+
@script = nil
|
22
|
+
|
23
|
+
@wait, @ready = IO.pipe
|
24
|
+
|
25
|
+
@events = Puma::Events.strings
|
26
|
+
@events.on_booted { @ready << "!" }
|
27
|
+
end
|
28
|
+
|
29
|
+
def teardown
|
30
|
+
File.unlink @state_path rescue nil
|
31
|
+
File.unlink @bind_path rescue nil
|
32
|
+
File.unlink @control_path rescue nil
|
33
|
+
|
34
|
+
@wait.close
|
35
|
+
@ready.close
|
36
|
+
|
37
|
+
if @server
|
38
|
+
Process.kill "INT", @server.pid
|
39
|
+
begin
|
40
|
+
Process.wait @server.pid
|
41
|
+
rescue Errno::ECHILD
|
42
|
+
end
|
43
|
+
|
44
|
+
@server.close
|
45
|
+
end
|
46
|
+
|
47
|
+
if @script
|
48
|
+
@script.close!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def server(opts)
|
53
|
+
core = "#{Gem.ruby} -rubygems -Ilib bin/puma"
|
54
|
+
cmd = "#{core} --restart-cmd '#{core}' -b tcp://127.0.0.1:#{@tcp_port} #{opts}"
|
55
|
+
tf = Tempfile.new "puma-test"
|
56
|
+
tf.puts "exec #{cmd}"
|
57
|
+
tf.close
|
58
|
+
|
59
|
+
@script = tf
|
60
|
+
|
61
|
+
@server = IO.popen("sh #{tf.path}", "r")
|
62
|
+
|
63
|
+
true while @server.gets =~ /Ctrl-C/
|
64
|
+
|
65
|
+
sleep 1
|
66
|
+
|
67
|
+
@server
|
68
|
+
end
|
69
|
+
|
70
|
+
def signal(which)
|
71
|
+
Process.kill which, @server.pid
|
72
|
+
end
|
73
|
+
|
74
|
+
def wait_booted
|
75
|
+
@wait.sysread 1
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_stop_via_pumactl
|
79
|
+
if defined?(JRUBY_VERSION) || RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
|
80
|
+
assert true
|
81
|
+
return
|
82
|
+
end
|
83
|
+
|
84
|
+
cli = Puma::CLI.new %W!-q -S #{@state_path} -b unix://#{@bind_path} --control unix://#{@control_path} test/hello.ru!, @events
|
85
|
+
|
86
|
+
t = Thread.new do
|
87
|
+
cli.run
|
88
|
+
end
|
89
|
+
|
90
|
+
wait_booted
|
91
|
+
|
92
|
+
s = UNIXSocket.new @bind_path
|
93
|
+
s << "GET / HTTP/1.0\r\n\r\n"
|
94
|
+
assert_equal "Hello World", s.read.split("\r\n").last
|
95
|
+
|
96
|
+
sout = StringIO.new
|
97
|
+
|
98
|
+
ccli = Puma::ControlCLI.new %W!-S #{@state_path} stop!, sout
|
99
|
+
|
100
|
+
ccli.run
|
101
|
+
|
102
|
+
assert_kind_of Thread, t.join(1), "server didn't stop"
|
103
|
+
end
|
104
|
+
|
105
|
+
def notest_restart_closes_keepalive_sockets
|
106
|
+
server("-q test/hello.ru")
|
107
|
+
|
108
|
+
s = TCPSocket.new "localhost", @tcp_port
|
109
|
+
s << "GET / HTTP/1.1\r\n\r\n"
|
110
|
+
true until s.gets == "\r\n"
|
111
|
+
|
112
|
+
s.readpartial(20)
|
113
|
+
signal :USR2
|
114
|
+
|
115
|
+
true while @server.gets =~ /Ctrl-C/
|
116
|
+
sleep 1
|
117
|
+
|
118
|
+
s.write "GET / HTTP/1.1\r\n\r\n"
|
119
|
+
|
120
|
+
assert_raises Errno::ECONNRESET do
|
121
|
+
Timeout.timeout(2) do
|
122
|
+
raise Errno::ECONNRESET unless s.read(2)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
s = TCPSocket.new "localhost", @tcp_port
|
127
|
+
s << "GET / HTTP/1.0\r\n\r\n"
|
128
|
+
assert_equal "Hello World", s.read.split("\r\n").last
|
129
|
+
end
|
130
|
+
|
131
|
+
def notest_restart_closes_keepalive_sockets_workers
|
132
|
+
server("-q -w 2 test/hello.ru")
|
133
|
+
|
134
|
+
s = TCPSocket.new "localhost", @tcp_port
|
135
|
+
s << "GET / HTTP/1.1\r\n\r\n"
|
136
|
+
true until s.gets == "\r\n"
|
137
|
+
|
138
|
+
s.readpartial(20)
|
139
|
+
signal :USR2
|
140
|
+
|
141
|
+
true while @server.gets =~ /Ctrl-C/
|
142
|
+
sleep 1
|
143
|
+
|
144
|
+
s.write "GET / HTTP/1.1\r\n\r\n"
|
145
|
+
|
146
|
+
assert_raises Errno::ECONNRESET do
|
147
|
+
Timeout.timeout(2) do
|
148
|
+
raise Errno::ECONNRESET unless s.read(2)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
s = TCPSocket.new "localhost", @tcp_port
|
153
|
+
s << "GET / HTTP/1.0\r\n\r\n"
|
154
|
+
assert_equal "Hello World", s.read.split("\r\n").last
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_bad_query_string_outputs_400
|
158
|
+
server "-q test/hello.ru 2>&1"
|
159
|
+
|
160
|
+
s = TCPSocket.new "localhost", @tcp_port
|
161
|
+
s << "GET /?h=% HTTP/1.0\r\n\r\n"
|
162
|
+
data = s.read
|
163
|
+
assert_equal "HTTP/1.1 400 Bad Request\r\n\r\n", data
|
164
|
+
end
|
165
|
+
end unless ENV['TRAVIS']
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'puma/io_buffer'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestIOBuffer < Test::Unit::TestCase
|
5
|
+
attr_accessor :iobuf
|
6
|
+
def setup
|
7
|
+
self.iobuf = Puma::IOBuffer.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_initial_size
|
11
|
+
assert_equal 0, iobuf.used
|
12
|
+
assert iobuf.capacity > 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_append_op
|
16
|
+
iobuf << "abc"
|
17
|
+
assert_equal "abc", iobuf.to_s
|
18
|
+
iobuf << "123"
|
19
|
+
assert_equal "abc123", iobuf.to_s
|
20
|
+
assert_equal 6, iobuf.used
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_append
|
24
|
+
expected = "mary had a little lamb"
|
25
|
+
iobuf.append("mary", " ", "had ", "a little", " lamb")
|
26
|
+
assert_equal expected, iobuf.to_s
|
27
|
+
assert_equal expected.length, iobuf.used
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_reset
|
31
|
+
iobuf << "content"
|
32
|
+
assert_equal "content", iobuf.to_s
|
33
|
+
iobuf.reset
|
34
|
+
assert_equal 0, iobuf.used
|
35
|
+
assert_equal "", iobuf.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
unless defined? JRUBY_VERSION
|
4
|
+
|
5
|
+
require 'puma'
|
6
|
+
require 'puma/minissl'
|
7
|
+
|
8
|
+
class TestMiniSSL < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def test_raises_with_invalid_key_file
|
11
|
+
ctx = Puma::MiniSSL::Context.new
|
12
|
+
|
13
|
+
exception = assert_raise(ArgumentError) { ctx.key = "/no/such/key" }
|
14
|
+
assert_equal("No such key file '/no/such/key'", exception.message)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_raises_with_invalid_cert_file
|
18
|
+
ctx = Puma::MiniSSL::Context.new
|
19
|
+
|
20
|
+
exception = assert_raise(ArgumentError) { ctx.cert = "/no/such/cert" }
|
21
|
+
assert_equal("No such cert file '/no/such/cert'", exception.message)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'puma/null_io'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestNullIO < Test::Unit::TestCase
|
5
|
+
attr_accessor :nio
|
6
|
+
def setup
|
7
|
+
self.nio = Puma::NullIO.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_read_with_no_arguments
|
11
|
+
assert_equal "", nio.read
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_read_with_nil_length
|
15
|
+
assert_equal "", nio.read(nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_read_with_zero_length
|
19
|
+
assert_equal "", nio.read(0)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_read_with_positive_integer_length
|
23
|
+
assert_nil nio.read(1)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_read_with_length_and_buffer
|
27
|
+
buf = ""
|
28
|
+
assert_nil nio.read(1,buf)
|
29
|
+
assert_equal "", buf
|
30
|
+
end
|
31
|
+
end
|