public
Rubygem
Description: A very fast & simple Ruby web server
Homepage: http://code.macournoyer.com/thin/
Clone URL: git://github.com/macournoyer/thin.git
Click here to lend your support to: thin and make a donation at www.pledgie.com !
* Make Server.new arguments more flexible, can now specify any of host, port, 
app or hash options.
* Add --backend option to specified which backend to use, closes #55
macournoyer (author)
Thu Apr 03 20:45:53 -0700 2008
commit  01dece1c2b32d9b12d1d2ee64aa78917f2ddaae1
tree    da0a6446dbb2d7819fa9e2b8e4101fda7de374ec
parent  97d1b9edf01c8f6418ed0b82be168b6efd92b940
...
1
 
 
2
3
4
...
1
2
3
4
5
6
0
@@ -1,4 +1,6 @@
0
 == 0.8.0 Dodgy Dentist release
0
+ * Make Server.new arguments more flexible, can now specify any of host, port, app or hash options.
0
+ * Add --backend option to specified which backend to use, closes #55
0
  * Serve static file only on GET and HEAD requests in Rails adapter, fixes #58
0
  * Add threaded option to run server in threaded mode, calling the application in a
0
    thread allowing for concurrency in the Rack adapter, closes #46
...
6
7
8
9
 
10
11
12
 
13
14
15
...
6
7
8
 
9
10
11
 
12
13
14
15
0
@@ -6,10 +6,10 @@ module Thin
0
       
0
       attr_accessor :host, :port
0
       
0
-      def initialize(host, port, key=nil)
0
+      def initialize(host, port, options={})
0
         @host = host
0
         @port = port.to_i
0
-        @key  = key || ''
0
+        @key  = options[:swiftiply].to_s
0
         super()
0
       end
0
 
...
37
38
39
 
 
40
41
42
43
44
45
46
...
37
38
39
40
41
42
43
 
 
44
45
46
0
@@ -37,10 +37,10 @@ module Thin
0
       def start
0
         # Select proper backend
0
         server = case
0
+        when @options.has_key?(:backend)
0
+          Server.new(@options[:address], @options[:port], :backend => eval(@options[:backend], TOPLEVEL_BINDING))
0
         when @options.has_key?(:socket)
0
           Server.new(@options[:socket])
0
-        when @options.has_key?(:swiftiply)
0
-          Server.new(Backends::SwiftiplyClient.new(@options[:address], @options[:port], @options[:swiftiply]))
0
         else
0
           Server.new(@options[:address], @options[:port])
0
         end
...
64
65
66
 
67
68
69
...
64
65
66
67
68
69
70
0
@@ -64,6 +64,7 @@ module Thin
0
         opts.on("-y", "--swiftiply [KEY]", "Run using swiftiply")                       { |key| @options[:swiftiply] = key }
0
         opts.on("-A", "--adapter NAME", "Rack adapter to use " +                       
0
                                         "(default: auto-detected)")                     { |name| @options[:adapter] = name }
0
+        opts.on("-b", "--backend CLASS", "Backend to use, full classname")              { |name| @options[:backend] = name }
0
         opts.on("-c", "--chdir DIR", "Change to dir before starting")                   { |dir| @options[:chdir] = File.expand_path(dir) }
0
         opts.on("-r", "--rackup FILE", "Load a Rack config file instead of " +
0
                                        "Rails adapter")                                 { |file| @options[:rackup] = file }
...
52
53
54
 
55
56
57
...
84
85
86
87
88
89
90
91
92
93
94
95
 
 
 
 
 
 
 
 
 
 
 
96
97
 
 
 
98
99
100
101
102
103
...
200
201
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
204
205
...
52
53
54
55
56
57
58
...
85
86
87
 
 
 
 
 
 
 
 
 
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
 
106
107
108
...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
0
@@ -52,6 +52,7 @@ module Thin
0
     
0
     # Default values
0
     DEFAULT_TIMEOUT                        = 30 #sec
0
+    DEFAULT_HOST                           = '0.0.0.0'
0
     DEFAULT_PORT                           = 3000
0
     DEFAULT_MAXIMUM_CONNECTIONS            = 1024
0
     DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS = 512
0
@@ -84,20 +85,24 @@ module Thin
0
     # UNIX domain socket on which the server is listening for connections.
0
     def_delegator :backend, :socket
0
     
0
-    def initialize(host_or_socket_or_backend, port=DEFAULT_PORT, app=nil, &block)
0
-      # Try to intelligently select which backend to use.
0
-      @backend = case
0
-      when host_or_socket_or_backend.is_a?(Backends::Base)
0
-        host_or_socket_or_backend
0
-      when host_or_socket_or_backend.include?('/')
0
-        Backends::UnixServer.new(host_or_socket_or_backend)
0
-      else
0
-        Backends::TcpServer.new(host_or_socket_or_backend, port.to_i)
0
+    def initialize(*args, &block)
0
+      host, port, options = DEFAULT_HOST, DEFAULT_PORT, {}
0
+      
0
+      args.each do |arg|
0
+        case arg
0
+        when String then host    = arg
0
+        when Fixnum then port    = arg
0
+        when Hash   then options = arg
0
+        else
0
+          @app = arg if arg.respond_to?(:call)
0
+        end
0
       end
0
       
0
+      # Try to intelligently select which backend to use.
0
+      @backend = select_backend(host, port, options)
0
+      
0
       load_cgi_multipart_eof_fix
0
 
0
-      @app            = app
0
       @backend.server = self
0
       
0
       # Set defaults
0
@@ -200,6 +205,20 @@ module Thin
0
         trap('TERM') { stop! }
0
       end
0
       
0
+      def select_backend(host, port, options)
0
+        case
0
+        when options.has_key?(:backend)
0
+          raise ArgumentError, ":backend must be a class" unless options[:backend].is_a?(Class)
0
+          options[:backend].new(host, port, options)
0
+        when options.has_key?(:swiftiply)
0
+          Backends::SwiftiplyClient.new(host, port, options)
0
+        when host.include?('/')
0
+          Backends::UnixServer.new(host)
0
+        else
0
+          Backends::TcpServer.new(host, port)
0
+        end
0
+      end
0
+      
0
       # Taken from Mongrel cgi_multipart_eof_fix
0
       # Ruby 1.8.5 has a security bug in cgi.rb, we need to patch it.
0
       def load_cgi_multipart_eof_fix
...
2
3
4
5
 
 
6
7
 
8
9
10
...
2
3
4
 
5
6
7
 
8
9
10
11
0
@@ -2,9 +2,10 @@ require File.dirname(__FILE__) + '/../spec_helper'
0
 
0
 describe Server, 'app builder' do
0
   it "should build app from constructor" do
0
-    server = Server.new('0.0.0.0', 3000, :works)
0
+    app = proc {}
0
+    server = Server.new('0.0.0.0', 3000, app)
0
     
0
-    server.app.should == :works
0
+    server.app.should == app
0
   end
0
   
0
   it "should build app from builder block" do
...
10
11
12
13
 
14
15
16
...
10
11
12
 
13
14
15
16
0
@@ -10,7 +10,7 @@ else
0
       end
0
       wait_for_socket('0.0.0.0', 3333)
0
       sleep 2 # HACK ooh boy, I wish I knew how to make those specs more stable...
0
-      start_server(Backends::SwiftiplyClient.new('0.0.0.0', 5555, nil), nil, :wait_for_socket => false) do |env|
0
+      start_server('0.0.0.0', 5555, :backend => Backends::SwiftiplyClient, :wait_for_socket => false) do |env|
0
         body = env.inspect + env['rack.input'].read
0
         [200, { 'Content-Type' => 'text/html', 'Content-Length' => body.size.to_s }, body]
0
       end
...
25
26
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
29
...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
0
@@ -25,4 +25,59 @@ describe Server do
0
     @server.threaded = true
0
     @server.backend.should be_threaded
0
   end
0
+end
0
+
0
+describe Server, "initialization" do
0
+  it "should set host and port" do
0
+    server = Server.new('192.168.1.1', 8080)
0
+
0
+    server.host.should == '192.168.1.1'
0
+    server.port.should == 8080
0
+  end
0
+
0
+  it "should set socket" do
0
+    server = Server.new('/tmp/thin.sock')
0
+
0
+    server.socket.should == '/tmp/thin.sock'
0
+  end
0
+  
0
+  it "should set host, port and app" do
0
+    app = proc {}
0
+    server = Server.new('192.168.1.1', 8080, app)
0
+    
0
+    server.host.should_not be_nil
0
+    server.app.should == app
0
+  end
0
+
0
+  it "should set socket and app" do
0
+    app = proc {}
0
+    server = Server.new('/tmp/thin.sock', app)
0
+    
0
+    server.socket.should_not be_nil
0
+    server.app.should == app
0
+  end
0
+
0
+  it "should set socket, nil and app" do
0
+    app = proc {}
0
+    server = Server.new('/tmp/thin.sock', nil, app)
0
+    
0
+    server.socket.should_not be_nil
0
+    server.app.should == app
0
+  end
0
+  
0
+  it "should set host, port and backend" do
0
+    server = Server.new('192.168.1.1', 8080, :backend => Thin::Backends::SwiftiplyClient)
0
+    
0
+    server.host.should_not be_nil
0
+    server.backend.should be_kind_of(Thin::Backends::SwiftiplyClient)
0
+  end  
0
+
0
+  it "should set host, port, app and backend" do
0
+    app = proc {}
0
+    server = Server.new('192.168.1.1', 8080, app, :backend => Thin::Backends::SwiftiplyClient)
0
+    
0
+    server.host.should_not be_nil
0
+    server.app.should == app
0
+    server.backend.should be_kind_of(Thin::Backends::SwiftiplyClient)
0
+  end  
0
 end
0
\ No newline at end of file
...
143
144
145
146
 
147
148
149
...
143
144
145
 
146
147
148
149
0
@@ -143,7 +143,7 @@ module Helpers
0
   end
0
   
0
   def start_server(address=DEFAULT_TEST_ADDRESS, port=DEFAULT_TEST_PORT, options={}, &app)
0
-    @server = Thin::Server.new(address, port, app)
0
+    @server = Thin::Server.new(address, port, options, app)
0
     @server.threaded = options[:threaded]
0
     @server.timeout = 3
0
     

Comments