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.

@@ -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
@@ -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
@@ -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
@@ -14,8 +14,9 @@ module Rack
14
14
  module Adapter
15
15
  class Rails
16
16
  def initialize(options={})
17
- @root = options[:root] || Dir.pwd
18
- @env = options[:environment] || 'development'
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) ??
@@ -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)
@@ -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
 
@@ -2,10 +2,10 @@ module Thin
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 5
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
 
9
- CODENAME = 'Cheezburger'
9
+ CODENAME = 'Purple Yogurt'
10
10
  end
11
11
  end
@@ -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
- context Rack::Adapter::Rails do
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.2
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 00:00:00 -05:00
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: eventmachine
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.8.1
22
+ version: 0.2.0
23
23
  version:
24
24
  - !ruby/object:Gem::Dependency
25
- name: rack
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.2.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
Binary file