Class: Thin::Server
Class Thin::Server < Object
(in files lib/thin/server.rb )The uterly famous Thin HTTP server. It listen for incoming request through a given backend and forward all request to app.
TCP server
Create a new TCP server on bound to host:port by specifiying host and port as the first 2 arguments.
Thin::Server.start('0.0.0.0', 3000, app)
UNIX domain server
Create a new UNIX domain socket bound to socket file by specifiying a filename as the first argument. Eg.: /tmp/thin.sock. If the first argument contains a / it will be assumed to be a UNIX socket.
Thin::Server.start('/tmp/thin.sock', app)
Using a custom backend
You can implement your own way to connect the server to its client by creating your own Backend class and pass it as the :backend option.
Thin::Server.start('galaxy://faraway', 1345, app, :backend => Thin::Backends::MyFancyBackend)
Rack application (app)
All requests will be processed through app that must be a valid Rack adapter. A valid Rack adapter (application) must respond to call(env#Hash) and return an array of [status, headers, body].
Building an app in place
If a block is passed, a Rack::Builder instance will be passed to build the app. So you can do cool stuff like this:
Thin::Server.start('0.0.0.0', 3000) do
use Rack::CommonLogger
use Rack::ShowExceptions
map "/lobster" do
use Rack::Lint
run Rack::Lobster.new
end
end
Controlling with signals
- QUIT: Gracefull shutdown (see Server#stop)
- INT and TERM: Force shutdown (see Server#stop!)
Disable signals by passing :signals => false
Includes
Methods
Public Class new(*args, &block)
[ show source ]
# File lib/thin/server.rb, line 91
91: def initialize(*args, &block)
92: host, port, options = DEFAULT_HOST, DEFAULT_PORT, {}
93:
94: # Guess each parameter by its type so they can be
95: # received in any order.
96: args.each do |arg|
97: case arg
98: when Fixnum, /^\d+$/ then port = arg.to_i
99: when String then host = arg
100: when Hash then options = arg
101: else
102: @app = arg if arg.respond_to?(:call)
103: end
104: end
105:
106: # Try to intelligently select which backend to use.
107: @backend = select_backend(host, port, options)
108:
109: load_cgi_multipart_eof_fix
110:
111: @backend.server = self
112:
113: # Set defaults
114: @backend.maximum_connections = DEFAULT_MAXIMUM_CONNECTIONS
115: @backend.maximum_persistent_connections = DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS
116: @backend.timeout = DEFAULT_TIMEOUT
117:
118: # Allow using Rack builder as a block
119: @app = Rack::Builder.new(&block).to_app if block
120:
121: # If in debug mode, wrap in logger adapter
122: @app = Rack::CommonLogger.new(@app) if Logging.debug?
123:
124: setup_signals unless options[:signals].class == FalseClass
125: end
Public Class start(*args, &block)
Lil’ shortcut to turn this:
Server.new(...).start
into this:
Server.start(...)
[ show source ]
# File lib/thin/server.rb, line 135
135: def self.start(*args, &block)
136: new(*args, &block).start!
137: end
Public Instance config()
Configure the server
The process might need to have superuser privilege to configure server with optimal options.
[ show source ]
# File lib/thin/server.rb, line 184
184: def config
185: @backend.config
186: end
Public Instance name()
Name of the server and type of backend used. This is also the name of the process in which Thin is running as a daemon.
[ show source ]
# File lib/thin/server.rb, line 190
190: def name
191: "thin server (#{@backend})"
192: end
Public Instance running?()
Return true if the server is running and ready to receive requests. Note that the server might still be running and return false when shuting down and waiting for active connections to complete.
[ show source ]
# File lib/thin/server.rb, line 198
198: def running?
199: @backend.running?
200: end
Public Instance start()
Start the server and listen for connections.
[ show source ]
# File lib/thin/server.rb, line 140
140: def start
141: raise ArgumentError, 'app required' unless @app
142:
143: log ">> Thin web server (v#{VERSION::STRING} codename #{VERSION::CODENAME})"
144: debug ">> Debugging ON"
145: trace ">> Tracing ON"
146:
147: log ">> Maximum connections set to #{@backend.maximum_connections}"
148: log ">> Listening on #{@backend}, CTRL+C to stop"
149:
150: @backend.start
151: end
Public Instance start!()
Alias for start
Public Instance stop()
Gracefull shutdown
Stops the server after processing all current connections. As soon as this method is called, the server stops accepting new requests and wait for all current connections to finish. Calling twice is the equivalent of calling stop!.
[ show source ]
# File lib/thin/server.rb, line 159
159: def stop
160: if running?
161: @backend.stop
162: unless @backend.empty?
163: log ">> Waiting for #{@backend.size} connection(s) to finish, " +
164: "can take up to #{timeout} sec, CTRL+C to stop now"
165: end
166: else
167: stop!
168: end
169: end
Public Instance stop!()
Force shutdown
Stops the server closing all current connections right away. This doesn‘t wait for connection to finish their work and send data. All current requests will be dropped.
[ show source ]
# File lib/thin/server.rb, line 175
175: def stop!
176: log ">> Stopping ..."
177:
178: @backend.stop!
179: end
Public Instance to_s()
Alias for name
Protected Instance load_cgi_multipart_eof_fix()
Taken from Mongrel cgi_multipart_eof_fix Ruby 1.8.5 has a security bug in cgi.rb, we need to patch it.
[ show source ]
# File lib/thin/server.rb, line 228
228: def load_cgi_multipart_eof_fix
229: version = RUBY_VERSION.split('.').map { |i| i.to_i }
230:
231: if version[0] <= 1 && version[1] <= 8 && version[2] <= 5 && RUBY_PLATFORM !~ /java/
232: begin
233: require 'cgi_multipart_eof_fix'
234: rescue LoadError
235: log "!! Ruby 1.8.5 is not secure please install cgi_multipart_eof_fix:"
236: log " gem install cgi_multipart_eof_fix"
237: end
238: end
239: end
Protected Instance select_backend(host, port, options)
[ show source ]
# File lib/thin/server.rb, line 212
212: def select_backend(host, port, options)
213: case
214: when options.has_key?(:backend)
215: raise ArgumentError, ":backend must be a class" unless options[:backend].is_a?(Class)
216: options[:backend].new(host, port, options)
217: when options.has_key?(:swiftiply)
218: Backends::SwiftiplyClient.new(host, port, options)
219: when host.include?('/')
220: Backends::UnixServer.new(host)
221: else
222: Backends::TcpServer.new(host, port)
223: end
224: end
Protected Instance setup_signals()
Register signals:
[ show source ]
# File lib/thin/server.rb, line 206
206: def setup_signals
207: trap('QUIT') { stop } unless Thin.win?
208: trap('INT') { stop! }
209: trap('TERM') { stop! }
210: end