thin 1.2.5 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ == 1.2.6 Crazy Delicious
2
+ * Make work with Rails 3 out-of-the-box.
3
+ * Auto-detect and load config.ru files on start. Makes Rails 3 work.
4
+ * Fix signals being ignored under 1.9 when daemonized.
5
+
1
6
  == 1.2.5 This Is Not A Web Server
2
7
  * Add rolling restart support (--onebyone option) [sikachu]
3
8
  * Force external_encoding of request's body to ASCII_8BIT [jeremyz]
@@ -8,6 +8,7 @@ module Rack
8
8
  # NOTE: If a framework has a file that is not unique, make sure to place
9
9
  # it at the end.
10
10
  ADAPTERS = [
11
+ [:rack, 'config.ru'],
11
12
  [:rails, 'config/environment.rb'],
12
13
  [:ramaze, 'start.rb'],
13
14
  [:halcyon, 'runner.ru'],
@@ -29,9 +30,20 @@ module Rack
29
30
  raise AdapterNotFound, "No adapter found for #{dir}"
30
31
  end
31
32
 
33
+ # Load a Rack application from a Rack config file (.ru).
34
+ def self.load(config)
35
+ rackup_code = ::File.read(config)
36
+ eval("Rack::Builder.new {( #{rackup_code}\n )}.to_app", TOPLEVEL_BINDING, config)
37
+ end
38
+
32
39
  # Loads an adapter identified by +name+ using +options+ hash.
33
40
  def self.for(name, options={})
41
+ ENV['RACK_ENV'] = options[:environment]
42
+
34
43
  case name.to_sym
44
+ when :rack
45
+ return load(::File.join(options[:chdir], "config.ru"))
46
+
35
47
  when :rails
36
48
  return Rails.new(options.merge(:root => options[:chdir]))
37
49
 
@@ -3,44 +3,44 @@ require 'timeout'
3
3
  require 'stringio'
4
4
  require 'time'
5
5
  require 'forwardable'
6
-
7
6
  require 'openssl'
8
7
  require 'eventmachine'
9
-
10
- require 'thin/version'
11
- require 'thin/statuses'
8
+ require 'rack'
12
9
 
13
10
  module Thin
14
- autoload :Command, 'thin/command'
15
- autoload :Connection, 'thin/connection'
16
- autoload :Daemonizable, 'thin/daemonizing'
17
- autoload :Logging, 'thin/logging'
18
- autoload :Headers, 'thin/headers'
19
- autoload :Request, 'thin/request'
20
- autoload :Response, 'thin/response'
21
- autoload :Runner, 'thin/runner'
22
- autoload :Server, 'thin/server'
23
- autoload :Stats, 'thin/stats'
11
+ ROOT = File.expand_path(File.dirname(__FILE__))
12
+
13
+ autoload :Command, "#{ROOT}/thin/command"
14
+ autoload :Connection, "#{ROOT}/thin/connection"
15
+ autoload :Daemonizable, "#{ROOT}/thin/daemonizing"
16
+ autoload :Logging, "#{ROOT}/thin/logging"
17
+ autoload :Headers, "#{ROOT}/thin/headers"
18
+ autoload :Request, "#{ROOT}/thin/request"
19
+ autoload :Response, "#{ROOT}/thin/response"
20
+ autoload :Runner, "#{ROOT}/thin/runner"
21
+ autoload :Server, "#{ROOT}/thin/server"
22
+ autoload :Stats, "#{ROOT}/thin/stats"
24
23
 
25
24
  module Backends
26
- autoload :Base, 'thin/backends/base'
27
- autoload :SwiftiplyClient, 'thin/backends/swiftiply_client'
28
- autoload :TcpServer, 'thin/backends/tcp_server'
29
- autoload :UnixServer, 'thin/backends/unix_server'
25
+ autoload :Base, "#{ROOT}/thin/backends/base"
26
+ autoload :SwiftiplyClient, "#{ROOT}/thin/backends/swiftiply_client"
27
+ autoload :TcpServer, "#{ROOT}/thin/backends/tcp_server"
28
+ autoload :UnixServer, "#{ROOT}/thin/backends/unix_server"
30
29
  end
31
30
 
32
31
  module Controllers
33
- autoload :Cluster, 'thin/controllers/cluster'
34
- autoload :Controller, 'thin/controllers/controller'
35
- autoload :Service, 'thin/controllers/service'
32
+ autoload :Cluster, "#{ROOT}/thin/controllers/cluster"
33
+ autoload :Controller, "#{ROOT}/thin/controllers/controller"
34
+ autoload :Service, "#{ROOT}/thin/controllers/service"
36
35
  end
37
36
  end
38
37
 
39
- require 'rack'
40
- require 'rack/adapter/loader'
38
+ require "#{Thin::ROOT}/thin/version"
39
+ require "#{Thin::ROOT}/thin/statuses"
40
+ require "#{Thin::ROOT}/rack/adapter/loader"
41
41
 
42
42
  module Rack
43
43
  module Adapter
44
- autoload :Rails, 'rack/adapter/rails'
44
+ autoload :Rails, "#{Thin::ROOT}/rack/adapter/rails"
45
45
  end
46
46
  end
@@ -172,8 +172,7 @@ module Thin
172
172
  Kernel.load(@options[:rackup])
173
173
  Object.const_get(File.basename(@options[:rackup], '.rb').capitalize.to_sym)
174
174
  when /\.ru$/
175
- rackup_code = File.read(@options[:rackup])
176
- eval("Rack::Builder.new {( #{rackup_code}\n )}.to_app", TOPLEVEL_BINDING, @options[:rackup])
175
+ Rack::Adapter.load(@options[:rackup])
177
176
  else
178
177
  raise "Invalid rackup file. please specify either a .ru or .rb file"
179
178
  end
@@ -36,18 +36,21 @@ module Thin
36
36
  def daemonize
37
37
  raise PlatformNotSupported, 'Daemonizing is not supported on Windows' if Thin.win?
38
38
  raise ArgumentError, 'You must specify a pid_file to daemonize' unless @pid_file
39
-
39
+
40
40
  remove_stale_pid_file
41
41
 
42
42
  pwd = Dir.pwd # Current directory is changed during daemonization, so store it
43
43
 
44
+ # HACK we need to create the directory before daemonization to prevent a bug under 1.9
45
+ # ignoring all signals when the directory is created after daemonization.
46
+ FileUtils.mkdir_p File.dirname(@pid_file)
47
+
44
48
  Daemonize.daemonize(File.expand_path(@log_file), name)
45
49
 
46
50
  Dir.chdir(pwd)
47
51
 
48
52
  write_pid_file
49
53
 
50
- trap('HUP') { restart }
51
54
  at_exit do
52
55
  log ">> Exiting!"
53
56
  remove_pid_file
@@ -153,7 +156,6 @@ module Thin
153
156
 
154
157
  def write_pid_file
155
158
  log ">> Writing PID to #{@pid_file}"
156
- FileUtils.mkdir_p File.dirname(@pid_file)
157
159
  open(@pid_file,"w") { |f| f.write(Process.pid) }
158
160
  File.chmod(0644, @pid_file)
159
161
  end
@@ -1,4 +1,4 @@
1
- require 'thin_parser'
1
+ require "#{Thin::ROOT}/thin_parser"
2
2
  require 'tempfile'
3
3
 
4
4
  module Thin
@@ -16,7 +16,7 @@ module Thin
16
16
 
17
17
  INITIAL_BODY = ''
18
18
  # Force external_encoding of request's body to ASCII_8BIT
19
- INITIAL_BODY.encode!(Encoding::ASCII_8BIT) if INITIAL_BODY.respond_to?(:encode)
19
+ INITIAL_BODY.encode!(Encoding::ASCII_8BIT) if INITIAL_BODY.respond_to?(:encode!)
20
20
 
21
21
  # Freeze some HTTP header names & values
22
22
  SERVER_SOFTWARE = 'SERVER_SOFTWARE'.freeze
@@ -208,11 +208,12 @@ module Thin
208
208
  protected
209
209
  # Register signals:
210
210
  # * INT calls +stop+ to shutdown gracefully.
211
- # * TERM calls <tt>stop!</tt> to force shutdown.
211
+ # * TERM calls <tt>stop!</tt> to force shutdown.
212
212
  def setup_signals
213
213
  trap('QUIT') { stop } unless Thin.win?
214
214
  trap('INT') { stop! }
215
215
  trap('TERM') { stop! }
216
+ trap('HUP') { restart }
216
217
  end
217
218
 
218
219
  def select_backend(host, port, options)
@@ -6,11 +6,11 @@ module Thin
6
6
  module VERSION #:nodoc:
7
7
  MAJOR = 1
8
8
  MINOR = 2
9
- TINY = 5
9
+ TINY = 6
10
10
 
11
11
  STRING = [MAJOR, MINOR, TINY].join('.')
12
12
 
13
- CODENAME = "This Is Not A Web Server".freeze
13
+ CODENAME = "Crazy Delicious".freeze
14
14
 
15
15
  RACK = [1, 0].freeze # Rack protocol version
16
16
  end
@@ -2,9 +2,18 @@ require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe Rack::Adapter do
4
4
  before do
5
+ @config_ru_path = File.dirname(__FILE__) + '/../../example'
5
6
  @rails_path = File.dirname(__FILE__) + '/../rails_app'
6
7
  end
7
8
 
9
+ it "should load Rack app from config" do
10
+ Rack::Adapter.load(@config_ru_path + '/config.ru').class.should == Proc
11
+ end
12
+
13
+ it "should guess Rack app from dir" do
14
+ Rack::Adapter.guess(@config_ru_path).should == :rack
15
+ end
16
+
8
17
  it "should guess rails app from dir" do
9
18
  Rack::Adapter.guess(@rails_path).should == :rails
10
19
  end
@@ -13,6 +22,10 @@ describe Rack::Adapter do
13
22
  proc { Rack::Adapter.guess('.') }.should raise_error(Rack::AdapterNotFound)
14
23
  end
15
24
 
25
+ it "should load Rack adapter" do
26
+ Rack::Adapter.for(:rack, :chdir => @config_ru_path).class.should == Proc
27
+ end
28
+
16
29
  it "should load Rails adapter" do
17
30
  Rack::Adapter::Rails.should_receive(:new)
18
31
  Rack::Adapter.for(:rails, :chdir => @rails_path)
@@ -44,6 +44,7 @@ describe Request, 'processing' do
44
44
  end
45
45
 
46
46
  it "should set body external encoding to ASCII_8BIT" do
47
+ pending("Ruby 1.9 compatible implementations only") unless StringIO.instance_methods.include? :external_encoding
47
48
  Request.new.body.external_encoding.should == Encoding::ASCII_8BIT
48
49
  end
49
50
  end
@@ -12,6 +12,10 @@ describe Server do
12
12
  end
13
13
 
14
14
  it "should set lower maximum_connections size when too large" do
15
+ # root users under Linux will not have a limitation on maximum
16
+ # connections, so we cannot really run this test under that
17
+ # condition.
18
+ pending("only for non-root users") if Process.euid == 0
15
19
  @server.maximum_connections = 100_000
16
20
  @server.config
17
21
  @server.maximum_connections.should < 100_000
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: 1.2.5
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-Andre Cournoyer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-13 00:00:00 -05:00
12
+ date: 2010-02-25 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency