thin 1.8.2 → 2.0.0.pre
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/.gitignore +9 -0
- data/CHANGELOG +29 -116
- data/Gemfile +8 -0
- data/README.md +44 -78
- data/Rakefile +28 -18
- data/bin/thin +4 -4
- data/examples/async.ru +21 -0
- data/examples/thin.conf.rb +39 -0
- data/lib/thin/async.rb +108 -0
- data/lib/thin/backends/prefork.rb +44 -0
- data/lib/thin/backends/single_process.rb +28 -0
- data/lib/thin/chunked_body.rb +28 -0
- data/lib/thin/configurator.rb +118 -0
- data/lib/thin/connection.rb +246 -172
- data/lib/thin/listener.rb +114 -0
- data/lib/thin/request.rb +94 -76
- data/lib/thin/response.rb +112 -45
- data/lib/thin/runner.rb +134 -197
- data/lib/thin/server.rb +203 -252
- data/lib/thin/system.rb +49 -0
- data/lib/thin/version.rb +12 -27
- data/lib/thin.rb +2 -44
- data/man/index.txt +3 -0
- data/man/thin-conf.5.ronn +121 -0
- data/man/thin.1.ronn +105 -0
- data/site/.gitignore +2 -0
- data/site/README.md +21 -0
- data/site/Rakefile +20 -0
- data/site/config.ru +4 -0
- data/site/public/images/grid.png +0 -0
- data/site/public/javascripts/dd_belatedpng.js +13 -0
- data/site/public/javascripts/modernizr-1.6.min.js +30 -0
- data/site/public/man/thin-conf.5.html +220 -0
- data/site/public/man/thin.1.html +177 -0
- data/site/site/assets/javascripts/main.coffee +2 -0
- data/site/site/assets/stylesheets/_config.scss +55 -0
- data/site/site/assets/stylesheets/main.scss +24 -0
- data/site/site/helpers.rb +17 -0
- data/site/site/layouts/base.erb +55 -0
- data/site/site/layouts/default.erb +17 -0
- data/site/site/pages/about.md +5 -0
- data/site/site/pages/index.erb +10 -0
- data/site/site/partials/.gitkeep +0 -0
- data/test/fixtures/big.txt +1 -0
- data/test/fixtures/small.txt +1 -0
- data/test/fixtures/thin.conf.rb +15 -0
- data/test/integration/async_test.rb +35 -0
- data/test/integration/big_request_test.rb +30 -0
- data/test/integration/config.ru +57 -0
- data/test/integration/daemonize_test.rb +26 -0
- data/test/integration/env_test.rb +44 -0
- data/test/integration/error_test.rb +37 -0
- data/test/integration/file_sending_test.rb +24 -0
- data/test/integration/keep_alive_test.rb +35 -0
- data/test/integration/robustness_test.rb +37 -0
- data/test/integration/single_process_test.rb +15 -0
- data/test/integration/socket_family_test.rb +38 -0
- data/test/integration/worker_test.rb +22 -0
- data/test/test_helper.rb +195 -0
- data/test/unit/configurator_test.rb +43 -0
- data/test/unit/connection_test.rb +94 -0
- data/test/unit/listener_test.rb +74 -0
- data/test/unit/request_test.rb +74 -0
- data/test/unit/response_test.rb +90 -0
- data/test/unit/server_test.rb +29 -0
- data/test/unit/system_test.rb +17 -0
- data/thin.gemspec +26 -0
- data/v2.todo +21 -0
- metadata +138 -93
- checksums.yaml +0 -7
- data/example/adapter.rb +0 -32
- data/example/async_app.ru +0 -126
- data/example/async_chat.ru +0 -247
- data/example/async_tailer.ru +0 -100
- data/example/config.ru +0 -22
- data/example/monit_sockets +0 -20
- data/example/monit_unixsock +0 -20
- data/example/myapp.rb +0 -1
- data/example/ramaze.ru +0 -12
- data/example/thin.god +0 -80
- data/example/thin_solaris_smf.erb +0 -36
- data/example/thin_solaris_smf.readme.txt +0 -150
- data/example/vlad.rake +0 -72
- data/ext/thin_parser/common.rl +0 -59
- data/ext/thin_parser/ext_help.h +0 -14
- data/ext/thin_parser/extconf.rb +0 -6
- data/ext/thin_parser/parser.c +0 -1447
- data/ext/thin_parser/parser.h +0 -49
- data/ext/thin_parser/parser.rl +0 -152
- data/ext/thin_parser/thin.c +0 -435
- data/lib/rack/adapter/loader.rb +0 -75
- data/lib/rack/adapter/rails.rb +0 -178
- data/lib/rack/handler/thin.rb +0 -38
- data/lib/thin/backends/base.rb +0 -169
- data/lib/thin/backends/swiftiply_client.rb +0 -66
- data/lib/thin/backends/tcp_server.rb +0 -34
- data/lib/thin/backends/unix_server.rb +0 -56
- data/lib/thin/command.rb +0 -53
- data/lib/thin/controllers/cluster.rb +0 -178
- data/lib/thin/controllers/controller.rb +0 -189
- data/lib/thin/controllers/service.rb +0 -76
- data/lib/thin/controllers/service.sh.erb +0 -39
- data/lib/thin/daemonizing.rb +0 -199
- data/lib/thin/headers.rb +0 -47
- data/lib/thin/logging.rb +0 -174
- data/lib/thin/stats.html.erb +0 -216
- data/lib/thin/stats.rb +0 -52
- data/lib/thin/statuses.rb +0 -48
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'thin/response'
|
3
|
+
|
4
|
+
class ResponseTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@response = Thin::Response.new
|
7
|
+
@response.headers['Content-Type'] = 'text/html'
|
8
|
+
@response.headers['Content-Length'] = '0'
|
9
|
+
@response.body = ''
|
10
|
+
@response.finish
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_initialize_with_values
|
14
|
+
@response = Thin::Response.new(201, {"Content-Type" => "text/plain"}, ["hi"])
|
15
|
+
assert_equal 201, @response.status
|
16
|
+
assert_match "Content-Type: text/plain", @response.headers.to_s
|
17
|
+
assert_equal ["hi"], @response.body
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_output_headers
|
21
|
+
assert_match "Content-Type: text/html", @response.headers.to_s
|
22
|
+
assert_match "Content-Length: 0", @response.headers.to_s
|
23
|
+
assert_match "Connection: close", @response.headers.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_include_server_name_header
|
27
|
+
assert_match "Server: thin", @response.headers.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_output_head
|
31
|
+
assert_match /^HTTP\/1.1 200 OK/, @response.head
|
32
|
+
assert_match /\r\n\r\n$/, @response.head
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_allow_duplicates_on_some_headers
|
36
|
+
@response.headers['Set-Cookie'] = 'mium=7'
|
37
|
+
@response.headers['Set-Cookie'] = 'hi=there'
|
38
|
+
|
39
|
+
assert_match "Set-Cookie: mium=7", @response.head
|
40
|
+
assert_match "Set-Cookie: hi=there", @response.head
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_parse_simple_header_values
|
44
|
+
@response.headers = {
|
45
|
+
'Host' => 'localhost'
|
46
|
+
}
|
47
|
+
|
48
|
+
assert_match "Host: localhost", @response.head
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_parse_multiline_header_values_in_several_headers
|
52
|
+
@response.headers = {
|
53
|
+
'Set-Cookie' => "mium=7\nhi=there"
|
54
|
+
}
|
55
|
+
|
56
|
+
assert_match "Set-Cookie: mium=7", @response.head
|
57
|
+
assert_match "Set-Cookie: hi=there", @response.head
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_ignore__nil_headers
|
61
|
+
@response.headers = nil
|
62
|
+
@response.headers = { 'Host' => 'localhost' }
|
63
|
+
@response.headers = { 'Set-Cookie' => nil }
|
64
|
+
assert_no_match /Set-Cookie/, @response.head
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_body
|
68
|
+
@response.body = ['<html>', '</html>']
|
69
|
+
|
70
|
+
out = ''
|
71
|
+
@response.each { |l| out << l }
|
72
|
+
assert_match /\r\n\r\n<html><\/html>$/, out
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_string_body
|
76
|
+
@response.body = '<html></html>'
|
77
|
+
|
78
|
+
out = ''
|
79
|
+
@response.each { |l| out << l }
|
80
|
+
assert_match /\r\n\r\n<html><\/html>$/, out
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_close
|
84
|
+
@response.close
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_async
|
88
|
+
assert Thin::Response.new(*Thin::Response::ASYNC).async?
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ServerTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
app = proc { |env| [200, {}, ["ok"]] }
|
6
|
+
@server = Thin::Server.new { app }
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_pick_prefork_backend_if_any_workers
|
10
|
+
@server.worker_processes = 1
|
11
|
+
assert_kind_of Thin::Backends::Prefork, @server.backend
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_pick_single_process_backend_if_no_workers
|
15
|
+
@server.worker_processes = 0
|
16
|
+
assert_kind_of Thin::Backends::SingleProcess, @server.backend
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_cant_daemonize_single_process
|
20
|
+
@server.worker_processes = 0
|
21
|
+
assert_raise(NotImplementedError) do
|
22
|
+
silence_streams { @server.start(true) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_do_not_preload_app
|
27
|
+
Thin::Server.new { fail "Should not load app before starting" }
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SystemTest < Test::Unit::TestCase
|
4
|
+
def test_processor_count
|
5
|
+
assert_not_equal 0, Thin::System.processor_count
|
6
|
+
end
|
7
|
+
|
8
|
+
if Thin::System.java? || Thin::System.win?
|
9
|
+
def test_should_not_support_fork
|
10
|
+
assert ! Thin::System.supports_fork?
|
11
|
+
end
|
12
|
+
else
|
13
|
+
def test_should_support_fork
|
14
|
+
assert Thin::System.supports_fork?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/thin.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "thin/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "thin"
|
7
|
+
s.version = Thin::VERSION::STRING
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Marc-Andre Cournoyer"]
|
10
|
+
s.email = ["thin@macournoyer.com"]
|
11
|
+
s.homepage = "http://code.macournoyer.com/thin"
|
12
|
+
s.summary = %q{A thin and fast web server}
|
13
|
+
s.description = %q{Thin is a Rack based, high performance web server}
|
14
|
+
|
15
|
+
s.rubyforge_project = "thin"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency "eventmachine-le", "~> 1.1.0"
|
23
|
+
s.add_dependency "http_parser.rb", "~> 0.5.3"
|
24
|
+
s.add_dependency "preforker", "~> 0.1.1"
|
25
|
+
s.add_dependency "rack", "~> 1.4"
|
26
|
+
end
|
data/v2.todo
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
x prefork
|
2
|
+
x listen on UNIX sockets
|
3
|
+
x Config
|
4
|
+
x Async
|
5
|
+
x Preload app
|
6
|
+
x Fast file serving with streaming
|
7
|
+
x Keep-alive
|
8
|
+
x Limit # of keep-alive requests
|
9
|
+
- Pipelining?
|
10
|
+
x Transfer-Encoding: chunked
|
11
|
+
- Use Logger
|
12
|
+
- Rotate logs on USR1 signal
|
13
|
+
- Zero downtime restart on USR2 signal
|
14
|
+
x Threading
|
15
|
+
- Change user:group after bind
|
16
|
+
- SSL
|
17
|
+
- Graceful stop
|
18
|
+
- Daemonizing
|
19
|
+
|
20
|
+
Optimizations:
|
21
|
+
- Stock 200 OK response (store in frozen const)
|
metadata
CHANGED
@@ -1,156 +1,201 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre
|
5
|
+
prerelease: 6
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Marc-Andre Cournoyer
|
8
|
-
autorequire:
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2012-08-10 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: eventmachine-le
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- -
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1'
|
20
|
-
- - "<"
|
19
|
+
- - ~>
|
21
20
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
21
|
+
version: 1.1.0
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '1'
|
30
|
-
- - "<"
|
27
|
+
- - ~>
|
31
28
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
29
|
+
version: 1.1.0
|
33
30
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
31
|
+
name: http_parser.rb
|
35
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
36
34
|
requirements:
|
37
|
-
- -
|
35
|
+
- - ~>
|
38
36
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: 1.0.4
|
37
|
+
version: 0.5.3
|
43
38
|
type: :runtime
|
44
39
|
prerelease: false
|
45
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
46
42
|
requirements:
|
47
|
-
- -
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '1.0'
|
50
|
-
- - ">="
|
43
|
+
- - ~>
|
51
44
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
45
|
+
version: 0.5.3
|
53
46
|
- !ruby/object:Gem::Dependency
|
54
|
-
name:
|
47
|
+
name: preforker
|
55
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
56
50
|
requirements:
|
57
|
-
- -
|
51
|
+
- - ~>
|
58
52
|
- !ruby/object:Gem::Version
|
59
|
-
version:
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 1.0.9
|
53
|
+
version: 0.1.1
|
63
54
|
type: :runtime
|
64
55
|
prerelease: false
|
65
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
70
|
-
|
61
|
+
version: 0.1.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rack
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.4'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
71
76
|
- !ruby/object:Gem::Version
|
72
|
-
version: 1.
|
73
|
-
description:
|
74
|
-
email:
|
77
|
+
version: '1.4'
|
78
|
+
description: Thin is a Rack based, high performance web server
|
79
|
+
email:
|
80
|
+
- thin@macournoyer.com
|
75
81
|
executables:
|
76
82
|
- thin
|
77
|
-
extensions:
|
78
|
-
- ext/thin_parser/extconf.rb
|
83
|
+
extensions: []
|
79
84
|
extra_rdoc_files: []
|
80
85
|
files:
|
86
|
+
- .gitignore
|
81
87
|
- CHANGELOG
|
88
|
+
- Gemfile
|
82
89
|
- README.md
|
83
90
|
- Rakefile
|
84
91
|
- bin/thin
|
85
|
-
-
|
86
|
-
-
|
87
|
-
- example/async_chat.ru
|
88
|
-
- example/async_tailer.ru
|
89
|
-
- example/config.ru
|
90
|
-
- example/monit_sockets
|
91
|
-
- example/monit_unixsock
|
92
|
-
- example/myapp.rb
|
93
|
-
- example/ramaze.ru
|
94
|
-
- example/thin.god
|
95
|
-
- example/thin_solaris_smf.erb
|
96
|
-
- example/thin_solaris_smf.readme.txt
|
97
|
-
- example/vlad.rake
|
98
|
-
- ext/thin_parser/common.rl
|
99
|
-
- ext/thin_parser/ext_help.h
|
100
|
-
- ext/thin_parser/extconf.rb
|
101
|
-
- ext/thin_parser/parser.c
|
102
|
-
- ext/thin_parser/parser.h
|
103
|
-
- ext/thin_parser/parser.rl
|
104
|
-
- ext/thin_parser/thin.c
|
105
|
-
- lib/rack/adapter/loader.rb
|
106
|
-
- lib/rack/adapter/rails.rb
|
107
|
-
- lib/rack/handler/thin.rb
|
92
|
+
- examples/async.ru
|
93
|
+
- examples/thin.conf.rb
|
108
94
|
- lib/thin.rb
|
109
|
-
- lib/thin/
|
110
|
-
- lib/thin/backends/
|
111
|
-
- lib/thin/backends/
|
112
|
-
- lib/thin/
|
113
|
-
- lib/thin/
|
95
|
+
- lib/thin/async.rb
|
96
|
+
- lib/thin/backends/prefork.rb
|
97
|
+
- lib/thin/backends/single_process.rb
|
98
|
+
- lib/thin/chunked_body.rb
|
99
|
+
- lib/thin/configurator.rb
|
114
100
|
- lib/thin/connection.rb
|
115
|
-
- lib/thin/
|
116
|
-
- lib/thin/controllers/controller.rb
|
117
|
-
- lib/thin/controllers/service.rb
|
118
|
-
- lib/thin/controllers/service.sh.erb
|
119
|
-
- lib/thin/daemonizing.rb
|
120
|
-
- lib/thin/headers.rb
|
121
|
-
- lib/thin/logging.rb
|
101
|
+
- lib/thin/listener.rb
|
122
102
|
- lib/thin/request.rb
|
123
103
|
- lib/thin/response.rb
|
124
104
|
- lib/thin/runner.rb
|
125
105
|
- lib/thin/server.rb
|
126
|
-
- lib/thin/
|
127
|
-
- lib/thin/stats.rb
|
128
|
-
- lib/thin/statuses.rb
|
106
|
+
- lib/thin/system.rb
|
129
107
|
- lib/thin/version.rb
|
130
|
-
|
131
|
-
|
132
|
-
-
|
133
|
-
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
108
|
+
- man/index.txt
|
109
|
+
- man/thin-conf.5.ronn
|
110
|
+
- man/thin.1.ronn
|
111
|
+
- site/.gitignore
|
112
|
+
- site/README.md
|
113
|
+
- site/Rakefile
|
114
|
+
- site/config.ru
|
115
|
+
- site/public/images/grid.png
|
116
|
+
- site/public/javascripts/dd_belatedpng.js
|
117
|
+
- site/public/javascripts/modernizr-1.6.min.js
|
118
|
+
- site/public/man/thin-conf.5.html
|
119
|
+
- site/public/man/thin.1.html
|
120
|
+
- site/site/assets/javascripts/main.coffee
|
121
|
+
- site/site/assets/stylesheets/_config.scss
|
122
|
+
- site/site/assets/stylesheets/main.scss
|
123
|
+
- site/site/helpers.rb
|
124
|
+
- site/site/layouts/base.erb
|
125
|
+
- site/site/layouts/default.erb
|
126
|
+
- site/site/pages/about.md
|
127
|
+
- site/site/pages/index.erb
|
128
|
+
- site/site/partials/.gitkeep
|
129
|
+
- test/fixtures/big.txt
|
130
|
+
- test/fixtures/small.txt
|
131
|
+
- test/fixtures/thin.conf.rb
|
132
|
+
- test/integration/async_test.rb
|
133
|
+
- test/integration/big_request_test.rb
|
134
|
+
- test/integration/config.ru
|
135
|
+
- test/integration/daemonize_test.rb
|
136
|
+
- test/integration/env_test.rb
|
137
|
+
- test/integration/error_test.rb
|
138
|
+
- test/integration/file_sending_test.rb
|
139
|
+
- test/integration/keep_alive_test.rb
|
140
|
+
- test/integration/robustness_test.rb
|
141
|
+
- test/integration/single_process_test.rb
|
142
|
+
- test/integration/socket_family_test.rb
|
143
|
+
- test/integration/worker_test.rb
|
144
|
+
- test/test_helper.rb
|
145
|
+
- test/unit/configurator_test.rb
|
146
|
+
- test/unit/connection_test.rb
|
147
|
+
- test/unit/listener_test.rb
|
148
|
+
- test/unit/request_test.rb
|
149
|
+
- test/unit/response_test.rb
|
150
|
+
- test/unit/server_test.rb
|
151
|
+
- test/unit/system_test.rb
|
152
|
+
- thin.gemspec
|
153
|
+
- v2.todo
|
154
|
+
homepage: http://code.macournoyer.com/thin
|
155
|
+
licenses: []
|
156
|
+
post_install_message:
|
138
157
|
rdoc_options: []
|
139
158
|
require_paths:
|
140
159
|
- lib
|
141
160
|
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
142
162
|
requirements:
|
143
|
-
- -
|
163
|
+
- - ! '>='
|
144
164
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
165
|
+
version: '0'
|
146
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
147
168
|
requirements:
|
148
|
-
- -
|
169
|
+
- - ! '>'
|
149
170
|
- !ruby/object:Gem::Version
|
150
|
-
version:
|
171
|
+
version: 1.3.1
|
151
172
|
requirements: []
|
152
|
-
|
153
|
-
|
154
|
-
|
173
|
+
rubyforge_project: thin
|
174
|
+
rubygems_version: 1.8.24
|
175
|
+
signing_key:
|
176
|
+
specification_version: 3
|
155
177
|
summary: A thin and fast web server
|
156
|
-
test_files:
|
178
|
+
test_files:
|
179
|
+
- test/fixtures/big.txt
|
180
|
+
- test/fixtures/small.txt
|
181
|
+
- test/fixtures/thin.conf.rb
|
182
|
+
- test/integration/async_test.rb
|
183
|
+
- test/integration/big_request_test.rb
|
184
|
+
- test/integration/config.ru
|
185
|
+
- test/integration/daemonize_test.rb
|
186
|
+
- test/integration/env_test.rb
|
187
|
+
- test/integration/error_test.rb
|
188
|
+
- test/integration/file_sending_test.rb
|
189
|
+
- test/integration/keep_alive_test.rb
|
190
|
+
- test/integration/robustness_test.rb
|
191
|
+
- test/integration/single_process_test.rb
|
192
|
+
- test/integration/socket_family_test.rb
|
193
|
+
- test/integration/worker_test.rb
|
194
|
+
- test/test_helper.rb
|
195
|
+
- test/unit/configurator_test.rb
|
196
|
+
- test/unit/connection_test.rb
|
197
|
+
- test/unit/listener_test.rb
|
198
|
+
- test/unit/request_test.rb
|
199
|
+
- test/unit/response_test.rb
|
200
|
+
- test/unit/server_test.rb
|
201
|
+
- test/unit/system_test.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA256:
|
3
|
-
metadata.gz: 32913c8b29b57b8f15fcd7cffb49db757989a225794e089ced01e53354c3cd90
|
4
|
-
data.tar.gz: f232efe452f20785ea8e71422a53147205ffd65ddbba90b8ba12e5b340c3b466
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 2cf9f7764e73b4086d1a11156bcd1aa67e6e3cabc32076e404971f866e3d4f28b536375773d03bf54e8237d3755cb70399c421044cb7cb577801f2f1deefe4d8
|
7
|
-
data.tar.gz: ed2643e1bc850bea3bd868150cd5c6b198b440b585a99def2099c35122d7a663c928c508f7441c4d708df6c878296b0e5cafcf9ebcfe70ef6ac6a1ca645111fe
|
data/example/adapter.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# Run with: ruby adapter.rb
|
2
|
-
# Then browse to http://localhost:3000/test
|
3
|
-
# and http://localhost:3000/files/adapter.rb
|
4
|
-
require 'thin'
|
5
|
-
|
6
|
-
class SimpleAdapter
|
7
|
-
def call(env)
|
8
|
-
body = ["hello!"]
|
9
|
-
[
|
10
|
-
200,
|
11
|
-
{ 'Content-Type' => 'text/plain' },
|
12
|
-
body
|
13
|
-
]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
Thin::Server.start('0.0.0.0', 3000) do
|
18
|
-
use Rack::CommonLogger
|
19
|
-
map '/test' do
|
20
|
-
run SimpleAdapter.new
|
21
|
-
end
|
22
|
-
map '/files' do
|
23
|
-
run Rack::File.new('.')
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# You could also start the server like this:
|
28
|
-
#
|
29
|
-
# app = Rack::URLMap.new('/test' => SimpleAdapter.new,
|
30
|
-
# '/files' => Rack::File.new('.'))
|
31
|
-
# Thin::Server.start('0.0.0.0', 3000, app)
|
32
|
-
#
|
data/example/async_app.ru
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
#!/usr/bin/env rackup -s thin
|
2
|
-
#
|
3
|
-
# async_app.ru
|
4
|
-
# raggi/thin
|
5
|
-
#
|
6
|
-
# A second demo app for async rack + thin app processing!
|
7
|
-
# Now using http status code 100 instead.
|
8
|
-
#
|
9
|
-
# Created by James Tucker on 2008-06-17.
|
10
|
-
# Copyright 2008 James Tucker <raggi@rubyforge.org>.
|
11
|
-
#
|
12
|
-
#--
|
13
|
-
# Benchmark Results:
|
14
|
-
#
|
15
|
-
# raggi@mbk:~$ ab -c 100 -n 500 http://127.0.0.1:3000/
|
16
|
-
# This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
17
|
-
# Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
18
|
-
# Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
19
|
-
#
|
20
|
-
# Benchmarking 127.0.0.1 (be patient)
|
21
|
-
# Completed 100 requests
|
22
|
-
# Completed 200 requests
|
23
|
-
# Completed 300 requests
|
24
|
-
# Completed 400 requests
|
25
|
-
# Finished 500 requests
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# Server Software: thin
|
29
|
-
# Server Hostname: 127.0.0.1
|
30
|
-
# Server Port: 3000
|
31
|
-
#
|
32
|
-
# Document Path: /
|
33
|
-
# Document Length: 12 bytes
|
34
|
-
#
|
35
|
-
# Concurrency Level: 100
|
36
|
-
# Time taken for tests: 5.263089 seconds
|
37
|
-
# Complete requests: 500
|
38
|
-
# Failed requests: 0
|
39
|
-
# Write errors: 0
|
40
|
-
# Total transferred: 47000 bytes
|
41
|
-
# HTML transferred: 6000 bytes
|
42
|
-
# Requests per second: 95.00 [#/sec] (mean)
|
43
|
-
# Time per request: 1052.618 [ms] (mean)
|
44
|
-
# Time per request: 10.526 [ms] (mean, across all concurrent requests)
|
45
|
-
# Transfer rate: 8.55 [Kbytes/sec] received
|
46
|
-
#
|
47
|
-
# Connection Times (ms)
|
48
|
-
# min mean[+/-sd] median max
|
49
|
-
# Connect: 0 3 2.2 3 8
|
50
|
-
# Processing: 1042 1046 3.1 1046 1053
|
51
|
-
# Waiting: 1037 1042 3.6 1041 1050
|
52
|
-
# Total: 1045 1049 3.1 1049 1057
|
53
|
-
#
|
54
|
-
# Percentage of the requests served within a certain time (ms)
|
55
|
-
# 50% 1049
|
56
|
-
# 66% 1051
|
57
|
-
# 75% 1053
|
58
|
-
# 80% 1053
|
59
|
-
# 90% 1054
|
60
|
-
# 95% 1054
|
61
|
-
# 98% 1056
|
62
|
-
# 99% 1057
|
63
|
-
# 100% 1057 (longest request)
|
64
|
-
|
65
|
-
class DeferrableBody
|
66
|
-
include EventMachine::Deferrable
|
67
|
-
|
68
|
-
def call(body)
|
69
|
-
body.each do |chunk|
|
70
|
-
@body_callback.call(chunk)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def each &blk
|
75
|
-
@body_callback = blk
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
class AsyncApp
|
81
|
-
|
82
|
-
# This is a template async response. N.B. Can't use string for body on 1.9
|
83
|
-
AsyncResponse = [-1, {}, []].freeze
|
84
|
-
|
85
|
-
def call(env)
|
86
|
-
|
87
|
-
body = DeferrableBody.new
|
88
|
-
|
89
|
-
# Get the headers out there asap, let the client know we're alive...
|
90
|
-
EventMachine::next_tick { env['async.callback'].call [200, {'Content-Type' => 'text/plain'}, body] }
|
91
|
-
|
92
|
-
# Semi-emulate a long db request, instead of a timer, in reality we'd be
|
93
|
-
# waiting for the response data. Whilst this happens, other connections
|
94
|
-
# can be serviced.
|
95
|
-
# This could be any callback based thing though, a deferrable waiting on
|
96
|
-
# IO data, a db request, an http request, an smtp send, whatever.
|
97
|
-
EventMachine::add_timer(1) {
|
98
|
-
body.call ["Woah, async!\n"]
|
99
|
-
|
100
|
-
EventMachine::next_tick {
|
101
|
-
# This could actually happen any time, you could spawn off to new
|
102
|
-
# threads, pause as a good looking lady walks by, whatever.
|
103
|
-
# Just shows off how we can defer chunks of data in the body, you can
|
104
|
-
# even call this many times.
|
105
|
-
body.call ["Cheers then!"]
|
106
|
-
body.succeed
|
107
|
-
}
|
108
|
-
}
|
109
|
-
|
110
|
-
# throw :async # Still works for supporting non-async frameworks...
|
111
|
-
|
112
|
-
AsyncResponse # May end up in Rack :-)
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
# The additions to env for async.connection and async.callback absolutely
|
118
|
-
# destroy the speed of the request if Lint is doing it's checks on env.
|
119
|
-
# It is also important to note that an async response will not pass through
|
120
|
-
# any further middleware, as the async response notification has been passed
|
121
|
-
# right up to the webserver, and the callback goes directly there too.
|
122
|
-
# Middleware could possibly catch :async, and also provide a different
|
123
|
-
# async.connection and async.callback.
|
124
|
-
|
125
|
-
# use Rack::Lint
|
126
|
-
run AsyncApp.new
|