thin 0.5.2 → 0.5.3
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 +40 -0
- data/Rakefile +3 -9
- data/benchmark/previous.rb +14 -0
- data/benchmark/simple.rb +13 -0
- data/benchmark/utils.rb +51 -0
- data/bin/thin +5 -0
- data/lib/rack/adapter/rails.rb +5 -2
- data/lib/thin/daemonizing.rb +7 -1
- data/lib/thin/request.rb +1 -1
- data/lib/thin/version.rb +2 -2
- data/spec/rack_rails_spec.rb +20 -1
- metadata +29 -26
- data/lib/thin_parser.bundle +0 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
== 0.5.3 Purple Yogurt release
|
2
|
+
* win32 pre-compiled gem now available
|
3
|
+
* change rake task configuration to allow win32 gem build
|
4
|
+
* Add prefix option to thin script to mount app under a given path.
|
5
|
+
|
6
|
+
== 0.5.2 Cheezburger release
|
7
|
+
* Add cluster support through the -s option in the thin script, start 3 thins like this:
|
8
|
+
thin start -s3 -p3000
|
9
|
+
3 thin servers will be started on port 3000, 3001, 3002, also the port number will be
|
10
|
+
injected in the pid and log filenames.
|
11
|
+
* Fix IOError when writing to logger when starting server as a daemon.
|
12
|
+
* Really change directory when the -c option is specified.
|
13
|
+
* Add restart command to thin script.
|
14
|
+
* Fix typos in thin script usage message and expand chdir path.
|
15
|
+
* Rename thin script options to be the same as mongrel_rails script [thronedrk]:
|
16
|
+
-o --host => -a --address
|
17
|
+
--log-file => --log
|
18
|
+
--pid-file => --pid
|
19
|
+
--env => --environment
|
20
|
+
|
21
|
+
== 0.5.1 LOLCAT release
|
22
|
+
* Add URL rewriting to Rails adapter so that page caching works and / fetches index.html if present.
|
23
|
+
* Fix bug in multiline response header parsing.
|
24
|
+
* Add specs for the Rails adapter.
|
25
|
+
* Fix Set-Cookie headers in Rails adapter to handle multiple values correctly.
|
26
|
+
* Fix Ruby 1.9 incompatibility in Response#headers= and Rakefile.
|
27
|
+
* Fix parser to be Ruby 1.9 compatible [Aman Gupta]
|
28
|
+
* Set gemspec to use EventMachine version 0.8.1 as it's the latest one having precompiled windows binaries.
|
29
|
+
[Francis Cianfrocca].
|
30
|
+
* Add -D option to thin script to set debugging on.
|
31
|
+
* Output incoming data and response when debugging is on.
|
32
|
+
|
33
|
+
== 0.5.0
|
34
|
+
* Full rewrite to use EventMachine, Rack and Mongrel parser
|
35
|
+
|
36
|
+
== 0.4.1
|
37
|
+
* Fix Rails environment option not being used in thin script.
|
38
|
+
|
39
|
+
== 0.4.0
|
40
|
+
* First alphaish release as a gem.
|
data/Rakefile
CHANGED
@@ -1,17 +1,11 @@
|
|
1
1
|
RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
|
2
|
+
WIN = (PLATFORM =~ /mswin|cygwin/)
|
3
|
+
SUDO = (WIN ? "" : "sudo")
|
2
4
|
|
3
5
|
require 'rake'
|
4
6
|
require 'rake/clean'
|
5
7
|
require 'lib/thin'
|
8
|
+
|
6
9
|
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
7
10
|
|
8
11
|
task :default => [:compile, :spec]
|
9
|
-
|
10
|
-
task :install => :compile do
|
11
|
-
sh %{rake package}
|
12
|
-
sh %{sudo #{gem} install pkg/#{Thin::NAME}-#{Thin::VERSION::STRING}}
|
13
|
-
end
|
14
|
-
|
15
|
-
task :uninstall => :clean do
|
16
|
-
sh %{sudo #{gem} uninstall #{Thin::NAME}}
|
17
|
-
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Benchmark to compare Thin performance against
|
2
|
+
# previous Thin version (the one installed as a gem).
|
3
|
+
#
|
4
|
+
# Run with:
|
5
|
+
#
|
6
|
+
# ruby previous.rb [num of request]
|
7
|
+
#
|
8
|
+
require 'rubygems'
|
9
|
+
require 'rack'
|
10
|
+
require File.dirname(__FILE__) + '/utils'
|
11
|
+
|
12
|
+
request = (ARGV[0] || 1000).to_i # Number of request to send (ab -n option)
|
13
|
+
|
14
|
+
benchmark %w(current gem), request
|
data/benchmark/simple.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Simple benchmark to compare Thin performance against
|
2
|
+
# other webservers supported by Rack.
|
3
|
+
#
|
4
|
+
# Run with:
|
5
|
+
#
|
6
|
+
# ruby simple.rb [num of request]
|
7
|
+
#
|
8
|
+
require File.dirname(__FILE__) + '/../lib/thin'
|
9
|
+
require File.dirname(__FILE__) + '/utils'
|
10
|
+
|
11
|
+
request = (ARGV[0] || 1000).to_i # Number of request to send (ab -n option)
|
12
|
+
|
13
|
+
benchmark %w(WEBrick Mongrel EMongrel Thin), request
|
data/benchmark/utils.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rack/lobster'
|
2
|
+
|
3
|
+
def run(handler_name, n=1000, c=1)
|
4
|
+
server = fork do
|
5
|
+
[STDOUT, STDERR].each { |o| o.reopen "/dev/null" }
|
6
|
+
|
7
|
+
case handler_name
|
8
|
+
when 'EMongrel'
|
9
|
+
require 'swiftcore/evented_mongrel'
|
10
|
+
handler_name = 'Mongrel'
|
11
|
+
|
12
|
+
when 'gem' # Load the current Thin gem
|
13
|
+
require 'thin'
|
14
|
+
handler_name = 'Thin'
|
15
|
+
|
16
|
+
when 'current' # Load the current Thin version under /lib
|
17
|
+
require File.dirname(__FILE__) + '/../lib/thin'
|
18
|
+
handler_name = 'Thin'
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
app = Rack::Lobster.new
|
23
|
+
|
24
|
+
handler = Rack::Handler.const_get(handler_name)
|
25
|
+
handler.run app, :Host => '0.0.0.0', :Port => 7000
|
26
|
+
end
|
27
|
+
|
28
|
+
sleep 2
|
29
|
+
|
30
|
+
out = `nice -n20 ab -c #{c} -n #{n} http://127.0.0.1:7000/ 2> /dev/null`
|
31
|
+
|
32
|
+
Process.kill('SIGKILL', server)
|
33
|
+
Process.wait
|
34
|
+
|
35
|
+
if requests = out.match(/^Requests.+?(\d+\.\d+)/)
|
36
|
+
failed = out.match(/^Failed requests.+?(\d+)$/)[1]
|
37
|
+
"#{requests[1].to_s.ljust(9)} #{failed}"
|
38
|
+
else
|
39
|
+
'ERROR'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def benchmark(servers, request, concurrency_levels=[1, 10, 100])
|
44
|
+
puts 'server request concurrency req/s failures'
|
45
|
+
puts '=' * 53
|
46
|
+
concurrency_levels.each do |c|
|
47
|
+
servers.each do |server|
|
48
|
+
puts "#{server.ljust(8)} #{request} #{c.to_s.ljust(4)} #{run(server, request, c)}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/bin/thin
CHANGED
@@ -43,6 +43,7 @@ opts = OptionParser.new do |opts|
|
|
43
43
|
"(default: #{options[:timeout]})") { |sec| options[:timeout] = sec.to_i }
|
44
44
|
opts.on("-u", "--user NAME", "User to run daemon as (use with -g)") { |user| options[:user] = user }
|
45
45
|
opts.on("-g", "--group NAME", "Group to run daemon as (use with -u)") { |group| options[:group] = group }
|
46
|
+
opts.on( "--prefix PATH", "Mount the app under PATH (start with /)") { |path| options[:prefix] = path }
|
46
47
|
|
47
48
|
opts.separator ""
|
48
49
|
opts.separator "Common options:"
|
@@ -77,6 +78,10 @@ def start(options)
|
|
77
78
|
end
|
78
79
|
|
79
80
|
server.app = Rack::Adapter::Rails.new(options.merge(:root => options[:chdir]))
|
81
|
+
|
82
|
+
# If a prefix is required, wrap in Rack URL mapper
|
83
|
+
server.app = Rack::URLMap.new(options[:prefix] => server.app) if options[:prefix]
|
84
|
+
|
80
85
|
server.start!
|
81
86
|
end
|
82
87
|
end
|
data/lib/rack/adapter/rails.rb
CHANGED
@@ -14,8 +14,9 @@ module Rack
|
|
14
14
|
module Adapter
|
15
15
|
class Rails
|
16
16
|
def initialize(options={})
|
17
|
-
@root
|
18
|
-
@env
|
17
|
+
@root = options[:root] || Dir.pwd
|
18
|
+
@env = options[:environment] || 'development'
|
19
|
+
@prefix = options[:prefix]
|
19
20
|
|
20
21
|
load_application
|
21
22
|
|
@@ -27,6 +28,8 @@ module Rack
|
|
27
28
|
|
28
29
|
require "#{@root}/config/environment"
|
29
30
|
require 'dispatcher'
|
31
|
+
|
32
|
+
ActionController::AbstractRequest.relative_url_root = @prefix if @prefix
|
30
33
|
end
|
31
34
|
|
32
35
|
# TODO refactor this in File#can_serve?(path) ??
|
data/lib/thin/daemonizing.rb
CHANGED
@@ -31,6 +31,7 @@ module Thin
|
|
31
31
|
|
32
32
|
# Turns the current script into a daemon process that detaches from the console.
|
33
33
|
def daemonize
|
34
|
+
check_plateform_support
|
34
35
|
raise ArgumentError, 'You must specify a pid_file to deamonize' unless @pid_file
|
35
36
|
|
36
37
|
pwd = Dir.pwd # Current directory is changed during daemonization, so store it
|
@@ -49,6 +50,7 @@ module Thin
|
|
49
50
|
# Change privileges of the process
|
50
51
|
# to the specified user and group.
|
51
52
|
def change_privilege(user, group=user)
|
53
|
+
check_plateform_support
|
52
54
|
log ">> Changing process privilege to #{user}:#{group}"
|
53
55
|
|
54
56
|
uid, gid = Process.euid, Process.egid
|
@@ -92,10 +94,14 @@ module Thin
|
|
92
94
|
end
|
93
95
|
|
94
96
|
private
|
97
|
+
def check_plateform_support
|
98
|
+
raise RuntimeError, 'Daemonizing not supported on Windows' if RUBY_PLATFORM =~ /mswin/
|
99
|
+
end
|
100
|
+
|
95
101
|
def remove_pid_file
|
96
102
|
File.delete(@pid_file) if @pid_file && File.exists?(@pid_file)
|
97
103
|
end
|
98
|
-
|
104
|
+
|
99
105
|
def write_pid_file
|
100
106
|
log ">> Writing PID to #{@pid_file}"
|
101
107
|
FileUtils.mkdir_p File.dirname(@pid_file)
|
data/lib/thin/request.rb
CHANGED
@@ -52,7 +52,7 @@ module Thin
|
|
52
52
|
body << data
|
53
53
|
elsif @data.size > MAX_HEADER # Oho! very big header, must be a mean person
|
54
54
|
raise InvalidRequest, MAX_HEADER_MSG
|
55
|
-
else # Parse more header
|
55
|
+
else # Parse more header using the super parser
|
56
56
|
@nparsed = @parser.execute(@env, @data, @nparsed)
|
57
57
|
end
|
58
58
|
|
data/lib/thin/version.rb
CHANGED
data/spec/rack_rails_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rack/mock'
|
|
4
4
|
begin
|
5
5
|
gem 'rails', '= 2.0.2' # We could freeze Rails in the rails_app dir to remove this
|
6
6
|
|
7
|
-
|
7
|
+
describe Rack::Adapter::Rails do
|
8
8
|
before do
|
9
9
|
@rails_app_path = File.dirname(__FILE__) + '/rails_app'
|
10
10
|
@request = Rack::MockRequest.new(Rack::Adapter::Rails.new(:root => @rails_app_path))
|
@@ -67,6 +67,25 @@ begin
|
|
67
67
|
FileUtils.rm_rf @rails_app_path + '/public/simple'
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
describe Rack::Adapter::Rails, 'with prefix' do
|
72
|
+
before do
|
73
|
+
@rails_app_path = File.dirname(__FILE__) + '/rails_app'
|
74
|
+
@prefix = '/nowhere'
|
75
|
+
@request = Rack::MockRequest.new(
|
76
|
+
Rack::URLMap.new(
|
77
|
+
@prefix => Rack::Adapter::Rails.new(:root => @rails_app_path, :prefix => @prefix)))
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should handle simple GET request" do
|
81
|
+
res = @request.get("#{@prefix}/simple", :lint => true)
|
82
|
+
|
83
|
+
res.should be_ok
|
84
|
+
res["Content-Type"].should include("text/html")
|
85
|
+
|
86
|
+
res.body.should include('Simple#index')
|
87
|
+
end
|
88
|
+
end
|
70
89
|
|
71
90
|
rescue Gem::LoadError
|
72
91
|
warn 'Rails 2.0.2 is required to run the Rails adapter specs'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc-Andre Cournoyer
|
@@ -9,26 +9,26 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-01-
|
12
|
+
date: 2008-01-18 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: rack
|
17
17
|
version_requirement:
|
18
18
|
version_requirements: !ruby/object:Gem::Requirement
|
19
19
|
requirements:
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.2.0
|
23
23
|
version:
|
24
24
|
- !ruby/object:Gem::Dependency
|
25
|
-
name:
|
25
|
+
name: eventmachine
|
26
26
|
version_requirement:
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
29
|
- - ">="
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version: 0.
|
31
|
+
version: 0.8.1
|
32
32
|
version:
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: daemons
|
@@ -49,10 +49,33 @@ extra_rdoc_files: []
|
|
49
49
|
|
50
50
|
files:
|
51
51
|
- COPYING
|
52
|
+
- CHANGELOG
|
52
53
|
- README
|
53
54
|
- Rakefile
|
55
|
+
- benchmark/previous.rb
|
56
|
+
- benchmark/simple.rb
|
57
|
+
- benchmark/utils.rb
|
54
58
|
- bin/thin
|
55
59
|
- doc/benchmarks.txt
|
60
|
+
- example/config.ru
|
61
|
+
- example/thin.god
|
62
|
+
- lib/rack
|
63
|
+
- lib/rack/adapter
|
64
|
+
- lib/rack/adapter/rails.rb
|
65
|
+
- lib/rack/handler
|
66
|
+
- lib/rack/handler/thin.rb
|
67
|
+
- lib/thin
|
68
|
+
- lib/thin/cluster.rb
|
69
|
+
- lib/thin/connection.rb
|
70
|
+
- lib/thin/daemonizing.rb
|
71
|
+
- lib/thin/headers.rb
|
72
|
+
- lib/thin/logging.rb
|
73
|
+
- lib/thin/request.rb
|
74
|
+
- lib/thin/response.rb
|
75
|
+
- lib/thin/server.rb
|
76
|
+
- lib/thin/statuses.rb
|
77
|
+
- lib/thin/version.rb
|
78
|
+
- lib/thin.rb
|
56
79
|
- spec/cluster_spec.rb
|
57
80
|
- spec/daemonizing_spec.rb
|
58
81
|
- spec/headers_spec.rb
|
@@ -116,26 +139,6 @@ files:
|
|
116
139
|
- spec/response_spec.rb
|
117
140
|
- spec/server_spec.rb
|
118
141
|
- spec/spec_helper.rb
|
119
|
-
- lib/rack
|
120
|
-
- lib/rack/adapter
|
121
|
-
- lib/rack/adapter/rails.rb
|
122
|
-
- lib/rack/handler
|
123
|
-
- lib/rack/handler/thin.rb
|
124
|
-
- lib/thin
|
125
|
-
- lib/thin/cluster.rb
|
126
|
-
- lib/thin/connection.rb
|
127
|
-
- lib/thin/daemonizing.rb
|
128
|
-
- lib/thin/headers.rb
|
129
|
-
- lib/thin/logging.rb
|
130
|
-
- lib/thin/request.rb
|
131
|
-
- lib/thin/response.rb
|
132
|
-
- lib/thin/server.rb
|
133
|
-
- lib/thin/statuses.rb
|
134
|
-
- lib/thin/version.rb
|
135
|
-
- lib/thin.rb
|
136
|
-
- lib/thin_parser.bundle
|
137
|
-
- example/config.ru
|
138
|
-
- example/thin.god
|
139
142
|
- ext/thin_parser/ext_help.h
|
140
143
|
- ext/thin_parser/parser.h
|
141
144
|
- ext/thin_parser/parser.c
|
data/lib/thin_parser.bundle
DELETED
Binary file
|