thin 1.6.3 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a52ecc8925833038f1f9b6ac7b421032e9524d79
4
- data.tar.gz: 5270eac2bbf836f0574704b908c7db468e05d977
2
+ SHA256:
3
+ metadata.gz: 285d7efc73ff2e6e29a8789706c605cc2a2b5a1d25313a53d72954dd5a8adbe7
4
+ data.tar.gz: 24642b42692477ba60cb63cb0ffa49dcf63cc0634708a349d8fac94d08989b74
5
5
  SHA512:
6
- metadata.gz: 992772f4b87b8086f5a99323cefd7ec748b89148d58f2758c9e911b84f1bc72f5c8181460145f92660ba0def62d2c8fcb4a9d4aca7aa32eae98805ea316ec654
7
- data.tar.gz: 1617c532da78f8a0173e933dee24c03ac521cdbd41ef79e83fc2543a993dbccc1bd528638c0fac3668996cc1939c9e233f75f5fda78240460333cdabb23be2b1
6
+ metadata.gz: ab7de3338f8d8694ed44a04cf785e78a0ce85de874d7bde4d96c6801b1e85190a3cbd33d8fe16a32aedc09eab9f1caad4a37ce51dc5997c32b5550da6d2fcffc
7
+ data.tar.gz: 19c45bc3a6f403daffe6a6c66b89bca01c597edb5b8c6ada110834c52fac0f639746f9b51ce5a3ca42c8f2fa013c929929b64b3737819ce83e5dff257e8a328a
data/CHANGELOG CHANGED
@@ -1,3 +1,25 @@
1
+ == 1.7.2 Bachmanity
2
+ * Add config support for ssl_version and ssl_cipher_list [frameworked]
3
+
4
+ == 1.7.1 Muffin Mode
5
+ * Ruby 2.4 support (Fixnum deprecation) [nimish-mehta]
6
+ * Allow ERB templates in config files [markets]
7
+
8
+ == 1.7.0 Dunder Mifflin
9
+ * Rack 2 support
10
+ * Ensure Response body.close is called in the same thread
11
+ Fixes issues with ActiveRecord connection management [#307]
12
+ * Fix TCP/IP Backend reports incorrect port when asked to bind to 0 [meschbach]
13
+ * Work with ruby 2.3's --enable-frozen-string-literal [jeremyevans]
14
+
15
+ == 1.6.4 Gob Bluth
16
+ * Increase REQUEST_PATH to 2048 symbols [X2rdas]
17
+ * Fix warning in logger [tenderlove]
18
+ * Add :timeout option for Rack::Server.new [sugitak]
19
+ * When restarting, exit on a next tick so we can send response back to a client [rsamoilov]
20
+ * Check for empty PID files [z1dane]
21
+ * Update Event Machine version to 1.0.4, Ruby 2.2.0 fix [freemanoid]
22
+
1
23
  == 1.6.3 Protein Powder
2
24
  * Add HTTP 422 status code [rajcybage]
3
25
  * Add warning about EM reactor still running when stopping.
data/README.md CHANGED
@@ -1,35 +1,17 @@
1
- Thin
2
- ====
1
+ # Thin
3
2
 
4
- Tiny, fast & funny HTTP server
5
-
6
- Thin is a Ruby web server that glues together 3 of the best Ruby libraries in web history:
7
-
8
- * The Mongrel parser: the root of Mongrel speed and security
9
- * Event Machine: a network I/O library with extremely high scalability, performance and stability
10
- * Rack: a minimal interface between webservers and Ruby frameworks
11
-
12
- Which makes it, with all humility, the most secure, stable, fast and extensible Ruby web server
13
- bundled in an easy to use gem for your own pleasure.
14
-
15
- Site: http://code.macournoyer.com/thin/
16
- Group: http://groups.google.com/group/thin-ruby/topics
17
- Bugs: http://github.com/macournoyer/thin/issues
18
- Code: http://github.com/macournoyer/thin
19
- IRC: #thin on freenode
3
+ A small and fast Ruby web server
20
4
 
21
5
  ## Installation
22
6
 
23
- For the latest stable version:
24
-
25
- `gem install thin`
7
+ ```
8
+ gem install thin
9
+ ```
26
10
 
27
- Or from source:
11
+ Or add `thin` to your `Gemfile`:
28
12
 
29
- ```
30
- git clone git://github.com/macournoyer/thin.git
31
- cd thin
32
- rake install
13
+ ```ruby
14
+ gem 'thin'
33
15
  ```
34
16
 
35
17
  ## Usage
@@ -37,18 +19,30 @@ rake install
37
19
  A +thin+ script offers an easy way to start your Rack application:
38
20
 
39
21
  ```
40
- cd to/your/app
41
22
  thin start
42
23
  ```
43
24
 
44
- When using with Rails and Bundler, make sure to add `gem 'thin'`
45
- to your Gemfile.
25
+ Browse the `example` directory for sample applications.
26
+
27
+ ## Usage with Rails Action Cable
28
+
29
+ To use Thin with Action Cable, add the following to your `Gemfile`:
30
+
31
+ ```ruby
32
+ gem 'faye-websocket'
33
+ gem 'thin' # If not already done
34
+ ```
35
+
36
+ Create a `config/initializers/thin_action_cable.rb`:
46
37
 
47
- See example directory for samples.
38
+ ```ruby
39
+ Rails.application.config.action_cable.use_faye = true
40
+ Faye::WebSocket.load_adapter 'thin'
41
+ ```
48
42
 
49
- ### Command Line Examples
43
+ ### CLI
50
44
 
51
- Use a rackup file and bind to localhost port 8080:
45
+ Use a rackup (config.ru) file and bind to localhost port 8080:
52
46
 
53
47
  ```
54
48
  thin -R config.ru -a 127.0.0.1 -p 8080 start
@@ -60,11 +54,15 @@ Store the server process ID, log to a file and daemonize:
60
54
  thin -p 9292 -P tmp/pids/thin.pid -l logs/thin.log -d start
61
55
  ```
62
56
 
63
- Thin is quite flexible in that many options can be specified at the command line (see below for usage).
57
+ Thin is quite flexible in that many options can be specified at the command line (see `thin -h` for more).
64
58
 
65
59
  ### Configuration files
66
60
 
67
- You can create configuration files in yaml format and feed them to thin using `thin -C config.yml`. Here is an example config file:
61
+ You can create a configuration file using `thin config -C config/thin.yml`.
62
+
63
+ You can then use it with all commands, such as: `thin start -C config/thin.yml`.
64
+
65
+ Here is an example config file:
68
66
 
69
67
  ```yaml
70
68
  ---
@@ -87,79 +85,13 @@ chdir: /path/to/your/apps/root
87
85
  tag: a-name-to-show-up-in-ps aux
88
86
  ```
89
87
 
90
- ### Command Line Options
91
-
92
- This is the usage for the thin command which can be obtained by running `thin -h` at the command line.
93
-
94
- ```sh
95
- Usage: thin [options] start|stop|restart|config|install
96
-
97
- Server options:
98
- -a, --address HOST bind to HOST address (default: 0.0.0.0)
99
- -p, --port PORT use PORT (default: 3000)
100
- -S, --socket FILE bind to unix domain socket
101
- -y, --swiftiply [KEY] Run using swiftiply
102
- -A, --adapter NAME Rack adapter to use (default: autodetect)
103
- (rack, rails, ramaze, merb, file)
104
- -R, --rackup FILE Load a Rack config file instead of Rack adapter
105
- -c, --chdir DIR Change to dir before starting
106
- --stats PATH Mount the Stats adapter under PATH
107
-
108
- SSL options:
109
- --ssl Enables SSL
110
- --ssl-key-file PATH Path to private key
111
- --ssl-cert-file PATH Path to certificate
112
- --ssl-disable-verify Disables (optional) client cert requests
113
-
114
- Adapter options:
115
- -e, --environment ENV Framework environment (default: development)
116
- --prefix PATH Mount the app under PATH (start with /)
117
-
118
- Daemon options:
119
- -d, --daemonize Run daemonized in the background
120
- -l, --log FILE File to redirect output (default: /home/robert/log/thin.log)
121
- -P, --pid FILE File to store PID (default: tmp/pids/thin.pid)
122
- -u, --user NAME User to run daemon as (use with -g)
123
- -g, --group NAME Group to run daemon as (use with -u)
124
- --tag NAME Additional text to display in process listing
125
-
126
- Cluster options:
127
- -s, --servers NUM Number of servers to start
128
- -o, --only NUM Send command to only one server of the cluster
129
- -C, --config FILE Load options from config file
130
- --all [DIR] Send command to each config files in DIR
131
- -O, --onebyone Restart the cluster one by one (only works with restart command)
132
- -w, --wait NUM Maximum wait time for server to be started in seconds (use with -O)
133
-
134
- Tuning options:
135
- -b, --backend CLASS Backend to use, full classname
136
- -t, --timeout SEC Request or command timeout in sec (default: 30)
137
- -f, --force Force the execution of the command
138
- --max-conns NUM Maximum number of open file descriptors (default: 1024)
139
- Might require sudo to set higher than 1024
140
- --max-persistent-conns NUM Maximum number of persistent connections
141
- (default: 100)
142
- --threaded Call the Rack application in threads [experimental]
143
- --threadpool-size NUM Sets the size of the EventMachine threadpool.
144
- (default: 20)
145
- --no-epoll Disable the use of epoll
146
-
147
- Common options:
148
- -r, --require FILE require the library
149
- -q, --quiet Silence all logging
150
- -D, --debug Enable debug logging
151
- -V, --trace Set tracing on (log raw request/response)
152
- -h, --help Show this message
153
- -v, --version Show version
154
- ```
155
-
156
88
  ## License
157
89
 
158
90
  Ruby License, http://www.ruby-lang.org/en/LICENSE.txt.
159
91
 
160
92
  ## Credits
161
93
 
162
- The parser was stolen from Mongrel http://mongrel.rubyforge.org by Zed Shaw.
94
+ The parser was originally from Mongrel http://mongrel.rubyforge.org by Zed Shaw.
163
95
  Mongrel is copyright 2007 Zed A. Shaw and contributors. It is licensed under
164
96
  the Ruby license and the GPL2.
165
97
 
@@ -167,4 +99,4 @@ Thin is copyright Marc-Andre Cournoyer <macournoyer@gmail.com>
167
99
 
168
100
  Get help at http://groups.google.com/group/thin-ruby/
169
101
  Report bugs at https://github.com/macournoyer/thin/issues
170
- and major security issues directly to me macournoyer@gmail.com.
102
+ and major security issues directly to me at macournoyer@gmail.com.
File without changes
File without changes
@@ -1437,11 +1437,6 @@ int thin_http_parser_is_finished(http_parser *parser) {
1437
1437
 
1438
1438
  int thin_http_parser_finish(http_parser *parser)
1439
1439
  {
1440
- int cs = parser->cs;
1441
-
1442
-
1443
- parser->cs = cs;
1444
-
1445
1440
  if (thin_http_parser_has_error(parser) ) {
1446
1441
  return -1;
1447
1442
  } else if (thin_http_parser_is_finished(parser) ) {
@@ -38,11 +38,11 @@ typedef struct http_parser {
38
38
 
39
39
  } http_parser;
40
40
 
41
- int http_parser_init(http_parser *parser);
42
- int http_parser_finish(http_parser *parser);
43
- size_t http_parser_execute(http_parser *parser, const char *data, size_t len, size_t off);
44
- int http_parser_has_error(http_parser *parser);
45
- int http_parser_is_finished(http_parser *parser);
41
+ int thin_http_parser_init(http_parser *parser);
42
+ int thin_http_parser_finish(http_parser *parser);
43
+ size_t thin_http_parser_execute(http_parser *parser, const char *data, size_t len, size_t off);
44
+ int thin_http_parser_has_error(http_parser *parser);
45
+ int thin_http_parser_is_finished(http_parser *parser);
46
46
 
47
47
  #define http_parser_nread(parser) (parser)->nread
48
48
 
@@ -142,11 +142,6 @@ int thin_http_parser_is_finished(http_parser *parser) {
142
142
 
143
143
  int thin_http_parser_finish(http_parser *parser)
144
144
  {
145
- int cs = parser->cs;
146
-
147
-
148
- parser->cs = cs;
149
-
150
145
  if (thin_http_parser_has_error(parser) ) {
151
146
  return -1;
152
147
  } else if (thin_http_parser_is_finished(parser) ) {
@@ -67,7 +67,7 @@ DEF_MAX_LENGTH(FIELD_NAME, 256);
67
67
  DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024);
68
68
  DEF_MAX_LENGTH(REQUEST_URI, 1024 * 12);
69
69
  DEF_MAX_LENGTH(FRAGMENT, 1024); /* Don't know if this length is specified somewhere or not */
70
- DEF_MAX_LENGTH(REQUEST_PATH, 1024);
70
+ DEF_MAX_LENGTH(REQUEST_PATH, 2048);
71
71
  DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10));
72
72
  DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
73
73
 
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thin"
4
+ require "thin/server"
5
+ require "thin/logging"
6
+ require "thin/backends/tcp_server"
7
+
8
+ module Rack
9
+ module Handler
10
+ class Thin
11
+ def self.run(app, **options)
12
+ environment = ENV['RACK_ENV'] || 'development'
13
+ default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
14
+
15
+ host = options.delete(:Host) || default_host
16
+ port = options.delete(:Port) || 8080
17
+ args = [host, port, app, options]
18
+
19
+ server = ::Thin::Server.new(*args)
20
+ yield server if block_given?
21
+
22
+ server.start
23
+ end
24
+
25
+ def self.valid_options
26
+ environment = ENV['RACK_ENV'] || 'development'
27
+ default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
28
+
29
+ {
30
+ "Host=HOST" => "Hostname to listen on (default: #{default_host})",
31
+ "Port=PORT" => "Port to listen on (default: 8080)",
32
+ }
33
+ end
34
+ end
35
+
36
+ register :thin, ::Rack::Handler::Thin
37
+ end
38
+ end
@@ -3,7 +3,7 @@ module Thin
3
3
  # A Backend connects the server to the client. It handles:
4
4
  # * connection/disconnection to the server
5
5
  # * initialization of the connections
6
- # * manitoring of the active connections.
6
+ # * monitoring of the active connections.
7
7
  #
8
8
  # == Implementing your own backend
9
9
  # You can create your own minimal backend by inheriting this class and
@@ -51,9 +51,11 @@ module Thin
51
51
  @maximum_connections = Server::DEFAULT_MAXIMUM_CONNECTIONS
52
52
  @maximum_persistent_connections = Server::DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS
53
53
  @no_epoll = false
54
+ @running = false
54
55
  @ssl = nil
55
- @threaded = nil
56
56
  @started_reactor = false
57
+ @stopping = false
58
+ @threaded = nil
57
59
  end
58
60
 
59
61
  # Start the backend and connect it.
@@ -4,26 +4,31 @@ module Thin
4
4
  class TcpServer < Base
5
5
  # Address and port on which the server is listening for connections.
6
6
  attr_accessor :host, :port
7
-
7
+
8
8
  def initialize(host, port)
9
9
  @host = host
10
10
  @port = port
11
11
  super()
12
12
  end
13
-
13
+
14
14
  # Connect the server
15
15
  def connect
16
16
  @signature = EventMachine.start_server(@host, @port, Connection, &method(:initialize_connection))
17
+ binary_name = EventMachine.get_sockname( @signature )
18
+ port_name = Socket.unpack_sockaddr_in( binary_name )
19
+ @port = port_name[0]
20
+ @host = port_name[1]
21
+ @signature
17
22
  end
18
-
23
+
19
24
  # Stops the server
20
25
  def disconnect
21
26
  EventMachine.stop_server(@signature)
22
27
  end
23
-
28
+
24
29
  def to_s
25
30
  "#{@host}:#{@port}"
26
31
  end
27
32
  end
28
33
  end
29
- end
34
+ end
@@ -47,7 +47,7 @@ module Thin
47
47
  def process
48
48
  if threaded?
49
49
  @request.threaded = true
50
- EventMachine.defer(method(:pre_process), method(:post_process))
50
+ EventMachine.defer { post_process(pre_process) }
51
51
  else
52
52
  @request.threaded = false
53
53
  post_process(pre_process)
@@ -55,7 +55,7 @@ module Thin
55
55
  # ssl support
56
56
  if @options[:ssl]
57
57
  server.ssl = true
58
- server.ssl_options = { :private_key_file => @options[:ssl_key_file], :cert_chain_file => @options[:ssl_cert_file], :verify_peer => !@options[:ssl_disable_verify] }
58
+ server.ssl_options = { :private_key_file => @options[:ssl_key_file], :cert_chain_file => @options[:ssl_cert_file], :verify_peer => !@options[:ssl_disable_verify], :ssl_version => @options[:ssl_version], :cipher_list => @options[:ssl_cipher_list]}
59
59
  end
60
60
 
61
61
  # Detach the process, after this line the current process returns
@@ -61,6 +61,7 @@ module Thin
61
61
  private
62
62
  def run(command)
63
63
  Dir[config_path + '/*'].each do |config|
64
+ next if config.end_with?("~")
64
65
  log_info "[#{command}] #{config} ..."
65
66
  Command.run(command, :config => config, :daemonize => true)
66
67
  end
@@ -30,11 +30,17 @@ module Thin
30
30
  def self.included(base)
31
31
  base.extend ClassMethods
32
32
  end
33
-
33
+
34
34
  def pid
35
- File.exist?(pid_file) ? open(pid_file).read.to_i : nil
35
+ File.exist?(pid_file) && !File.zero?(pid_file) ? open(pid_file).read.to_i : nil
36
36
  end
37
-
37
+
38
+ def kill(timeout = 60)
39
+ if File.exist?(@pid_file)
40
+ self.class.kill(@pid_file, timeout)
41
+ end
42
+ end
43
+
38
44
  # Turns the current script into a daemon process that detaches from the console.
39
45
  def daemonize
40
46
  raise PlatformNotSupported, 'Daemonizing is not supported on Windows' if Thin.win?
@@ -78,6 +84,10 @@ module Thin
78
84
  Process.initgroups(user, target_gid)
79
85
  Process::GID.change_privilege(target_gid)
80
86
  Process::UID.change_privilege(target_uid)
87
+
88
+ # Correct environment variables
89
+ ENV.store('USER', user)
90
+ ENV.store('HOME', File.expand_path("~#{user}"))
81
91
  end
82
92
  rescue Errno::EPERM => e
83
93
  log_info "Couldn't change user and group to #{user}:#{group}: #{e}"
@@ -95,7 +105,7 @@ module Thin
95
105
  stop
96
106
  remove_pid_file
97
107
  @on_restart.call
98
- exit!
108
+ EM.next_tick { exit! }
99
109
  end
100
110
  end
101
111
 
@@ -116,14 +126,23 @@ module Thin
116
126
  def restart(pid_file)
117
127
  send_signal('HUP', pid_file)
118
128
  end
119
-
129
+
130
+ def monotonic_time
131
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
132
+ end
133
+
120
134
  # Send a +signal+ to the process which PID is stored in +pid_file+.
121
135
  def send_signal(signal, pid_file, timeout=60)
122
136
  if pid = read_pid_file(pid_file)
123
137
  Logging.log_info "Sending #{signal} signal to process #{pid} ... "
138
+
124
139
  Process.kill(signal, pid)
125
- Timeout.timeout(timeout) do
126
- sleep 0.1 while Process.running?(pid)
140
+
141
+ # This loop seems kind of racy to me...
142
+ started_at = monotonic_time
143
+ while Process.running?(pid)
144
+ sleep 0.1
145
+ raise Timeout::Error if (monotonic_time - started_at) > timeout
127
146
  end
128
147
  else
129
148
  raise PidFileNotFound, "Can't stop process, no PID found in #{pid_file}"
@@ -13,10 +13,12 @@ module Thin
13
13
  # Taken from ActiveSupport
14
14
  class SimpleFormatter < Logger::Formatter
15
15
  def call(severity, timestamp, progname, msg)
16
- "#{String === msg ? msg : msg.inspect}\n"
16
+ "#{timestamp} #{String === msg ? msg : msg.inspect}\n"
17
17
  end
18
18
  end
19
19
 
20
+ @trace_logger = nil
21
+
20
22
  class << self
21
23
  attr_reader :logger
22
24
  attr_reader :trace_logger
@@ -152,7 +154,10 @@ module Thin
152
154
 
153
155
  # Log a message at ERROR level (and maybe a backtrace)
154
156
  def log_error(msg, e=nil)
155
- log_msg = msg + ": #{e}\n\t" + e.backtrace.join("\n\t") + "\n" if e
157
+ log_msg = msg
158
+ if e
159
+ log_msg += ": #{e}\n\t" + e.backtrace.join("\n\t") + "\n"
160
+ end
156
161
  Logging.log_msg(log_msg, Logger::ERROR)
157
162
  end
158
163
  module_function :log_error
@@ -13,9 +13,9 @@ module Thin
13
13
  BODY_TMPFILE = 'thin-body'.freeze
14
14
  MAX_HEADER = 1024 * (80 + 32)
15
15
 
16
- INITIAL_BODY = ''
16
+ INITIAL_BODY = String.new
17
17
  # Force external_encoding of request's body to ASCII_8BIT
18
- INITIAL_BODY.encode!(Encoding::ASCII_8BIT) if INITIAL_BODY.respond_to?(:encode!)
18
+ INITIAL_BODY.encode!(Encoding::ASCII_8BIT) if INITIAL_BODY.respond_to?(:encode!) && defined?(Encoding::ASCII_8BIT)
19
19
 
20
20
  # Freeze some HTTP header names & values
21
21
  SERVER_SOFTWARE = 'SERVER_SOFTWARE'.freeze
@@ -52,7 +52,7 @@ module Thin
52
52
 
53
53
  def initialize
54
54
  @parser = Thin::HttpParser.new
55
- @data = ''
55
+ @data = String.new
56
56
  @nparsed = 0
57
57
  @body = StringIO.new(INITIAL_BODY.dup)
58
58
  @env = {
@@ -75,7 +75,9 @@ module Thin
75
75
  # Raises an +InvalidRequest+ if invalid.
76
76
  # Returns +true+ if the parsing is complete.
77
77
  def parse(data)
78
- if @parser.finished? # Header finished, can only be some more body
78
+ if data.size > 0 && finished? # headers and body already fully satisfied. more data is erroneous.
79
+ raise InvalidRequest, 'Content longer than specified'
80
+ elsif @parser.finished? # Header finished, can only be some more body
79
81
  @body << data
80
82
  else # Parse more header using the super parser
81
83
  @data << data
@@ -1,6 +1,7 @@
1
1
  require 'logger'
2
2
  require 'optparse'
3
3
  require 'yaml'
4
+ require 'erb'
4
5
 
5
6
  module Thin
6
7
  # CLI runner.
@@ -80,6 +81,8 @@ module Thin
80
81
  opts.on( "--ssl-key-file PATH", "Path to private key") { |path| @options[:ssl_key_file] = path }
81
82
  opts.on( "--ssl-cert-file PATH", "Path to certificate") { |path| @options[:ssl_cert_file] = path }
82
83
  opts.on( "--ssl-disable-verify", "Disables (optional) client cert requests") { @options[:ssl_disable_verify] = true }
84
+ opts.on( "--ssl-version VERSION", "TLSv1, TLSv1_1, TLSv1_2") { |version| @options[:ssl_version] = version }
85
+ opts.on( "--ssl-cipher-list STRING", "Example: HIGH:!ADH:!RC4:-MEDIUM:-LOW:-EXP:-CAMELLIA") { |cipher| @options[:ssl_cipher_list] = cipher }
83
86
 
84
87
  opts.separator ""
85
88
  opts.separator "Adapter options:"
@@ -219,7 +222,7 @@ module Thin
219
222
  private
220
223
  def load_options_from_config_file!
221
224
  if file = @options.delete(:config)
222
- YAML.load_file(file).each { |key, value| @options[key.to_sym] = value }
225
+ YAML.load(ERB.new(File.read(file)).result).each { |key, value| @options[key.to_sym] = value }
223
226
  end
224
227
  end
225
228
 
@@ -1,10 +1,10 @@
1
1
  module Thin
2
- # The uterly famous Thin HTTP server.
3
- # It listen for incoming request through a given +backend+
4
- # and forward all request to +app+.
2
+ # The utterly famous Thin HTTP server.
3
+ # It listens for incoming requests through a given +backend+
4
+ # and forwards all requests to +app+.
5
5
  #
6
6
  # == TCP server
7
- # Create a new TCP server on bound to <tt>host:port</tt> by specifiying +host+
7
+ # Create a new TCP server bound to <tt>host:port</tt> by specifiying +host+
8
8
  # and +port+ as the first 2 arguments.
9
9
  #
10
10
  # Thin::Server.start('0.0.0.0', 3000, app)
@@ -18,12 +18,12 @@ module Thin
18
18
  #
19
19
  # == Using a custom backend
20
20
  # You can implement your own way to connect the server to its client by creating your
21
- # own Backend class and pass it as the :backend option.
21
+ # own Backend class and passing it as the :backend option.
22
22
  #
23
23
  # Thin::Server.start('galaxy://faraway', 1345, app, :backend => Thin::Backends::MyFancyBackend)
24
24
  #
25
25
  # == Rack application (+app+)
26
- # All requests will be processed through +app+ that must be a valid Rack adapter.
26
+ # All requests will be processed through +app+, which must be a valid Rack adapter.
27
27
  # A valid Rack adapter (application) must respond to <tt>call(env#Hash)</tt> and
28
28
  # return an array of <tt>[status, headers, body]</tt>.
29
29
  #
@@ -76,10 +76,10 @@ module Thin
76
76
  # Maximum number of file or socket descriptors that the server may open.
77
77
  def_delegators :backend, :maximum_connections, :maximum_connections=
78
78
 
79
- # Maximum number of connection that can be persistent at the same time.
80
- # Most browser never close the connection so most of the time they are closed
81
- # when the timeout occur. If we don't control the number of persistent connection,
82
- # if would be very easy to overflow the server for a DoS attack.
79
+ # Maximum number of connections that can be persistent at the same time.
80
+ # Most browsers never close the connection so most of the time they are closed
81
+ # when the timeout occurs. If we don't control the number of persistent connections,
82
+ # it would be very easy to overflow the server for a DoS attack.
83
83
  def_delegators :backend, :maximum_persistent_connections, :maximum_persistent_connections=
84
84
 
85
85
  # Allow using threads in the backend.
@@ -104,9 +104,9 @@ module Thin
104
104
  # received in any order.
105
105
  args.each do |arg|
106
106
  case arg
107
- when Fixnum, /^\d+$/ then port = arg.to_i
108
- when String then host = arg
109
- when Hash then options = arg
107
+ when 0.class, /^\d+$/ then port = arg.to_i
108
+ when String then host = arg
109
+ when Hash then options = arg
110
110
  else
111
111
  @app = arg if arg.respond_to?(:call)
112
112
  end
@@ -125,7 +125,7 @@ module Thin
125
125
  # Set defaults
126
126
  @backend.maximum_connections = DEFAULT_MAXIMUM_CONNECTIONS
127
127
  @backend.maximum_persistent_connections = DEFAULT_MAXIMUM_PERSISTENT_CONNECTIONS
128
- @backend.timeout = DEFAULT_TIMEOUT
128
+ @backend.timeout = options[:timeout] || DEFAULT_TIMEOUT
129
129
 
130
130
  # Allow using Rack builder as a block
131
131
  @app = Rack::Builder.new(&block).to_app if block
@@ -166,7 +166,7 @@ module Thin
166
166
  # == Gracefull shutdown
167
167
  # Stops the server after processing all current connections.
168
168
  # As soon as this method is called, the server stops accepting
169
- # new requests and wait for all current connections to finish.
169
+ # new requests and waits for all current connections to finish.
170
170
  # Calling twice is the equivalent of calling <tt>stop!</tt>.
171
171
  def stop
172
172
  if running?
@@ -33,12 +33,16 @@ module Thin
33
33
  413 => 'Request Entity Too Large',
34
34
  414 => 'Request-URI Too Large',
35
35
  415 => 'Unsupported Media Type',
36
- 422 => 'Unprocessable Entity',
37
- 500 => 'Internal Server Error',
36
+ 422 => 'Unprocessable Entity',
37
+ 428 => 'Precondition Required',
38
+ 429 => 'Too Many Requests',
39
+ 431 => 'Request Header Fields Too Large',
40
+ 500 => 'Internal Server Error',
38
41
  501 => 'Not Implemented',
39
42
  502 => 'Bad Gateway',
40
43
  503 => 'Service Unavailable',
41
44
  504 => 'Gateway Time-out',
42
- 505 => 'HTTP Version not supported'
45
+ 505 => 'HTTP Version not supported',
46
+ 511 => 'Network Authentication Required'
43
47
  }
44
- end
48
+ end
@@ -1,22 +1,22 @@
1
- module Thin
1
+ module Thin
2
2
  # Raised when a feature is not supported on the
3
3
  # current platform.
4
4
  class PlatformNotSupported < RuntimeError; end
5
5
 
6
6
  module VERSION #:nodoc:
7
7
  MAJOR = 1
8
- MINOR = 6
9
- TINY = 3
8
+ MINOR = 8
9
+ TINY = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, TINY].join('.')
12
12
 
13
- CODENAME = "Protein Powder".freeze
13
+ CODENAME = "Possessed Pickle".freeze
14
14
 
15
15
  RACK = [1, 0].freeze # Rack protocol version
16
16
  end
17
17
 
18
18
  NAME = 'thin'.freeze
19
- SERVER = "#{NAME} #{VERSION::STRING} codename #{VERSION::CODENAME}".freeze
19
+ SERVER = "#{NAME} #{VERSION::STRING} codename #{VERSION::CODENAME}".freeze
20
20
 
21
21
  def self.win?
22
22
  RUBY_PLATFORM =~ /mswin|mingw/
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-Andre Cournoyer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-02 00:00:00.000000000 Z
11
+ date: 2020-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '1.0'
29
+ version: '1'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: eventmachine
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -31,6 +37,9 @@ dependencies:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
39
  version: '1.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.0.4
34
43
  type: :runtime
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,6 +47,9 @@ dependencies:
38
47
  - - "~>"
39
48
  - !ruby/object:Gem::Version
40
49
  version: '1.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.0.4
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: daemons
43
55
  requirement: !ruby/object:Gem::Requirement
@@ -58,7 +70,7 @@ dependencies:
58
70
  - - ">="
59
71
  - !ruby/object:Gem::Version
60
72
  version: 1.0.9
61
- description: A thin and fast web server
73
+ description:
62
74
  email: macournoyer@gmail.com
63
75
  executables:
64
76
  - thin
@@ -92,6 +104,7 @@ files:
92
104
  - ext/thin_parser/thin.c
93
105
  - lib/rack/adapter/loader.rb
94
106
  - lib/rack/adapter/rails.rb
107
+ - lib/rack/handler/thin.rb
95
108
  - lib/thin.rb
96
109
  - lib/thin/backends/base.rb
97
110
  - lib/thin/backends/swiftiply_client.rb
@@ -114,12 +127,14 @@ files:
114
127
  - lib/thin/stats.rb
115
128
  - lib/thin/statuses.rb
116
129
  - lib/thin/version.rb
117
- homepage: http://code.macournoyer.com/thin/
130
+ homepage: https://github.com/macournoyer/thin
118
131
  licenses:
119
- - GPLv2+
120
- - Ruby 1.8
121
- metadata: {}
122
- post_install_message:
132
+ - GPL-2.0+
133
+ - Ruby
134
+ metadata:
135
+ source_code_uri: https://github.com/macournoyer/thin
136
+ changelog_uri: https://github.com/macournoyer/thin/blob/master/CHANGELOG
137
+ post_install_message:
123
138
  rdoc_options: []
124
139
  require_paths:
125
140
  - lib
@@ -134,9 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
149
  - !ruby/object:Gem::Version
135
150
  version: '0'
136
151
  requirements: []
137
- rubyforge_project: thin
138
- rubygems_version: 2.2.2
139
- signing_key:
152
+ rubygems_version: 3.1.2
153
+ signing_key:
140
154
  specification_version: 4
141
155
  summary: A thin and fast web server
142
156
  test_files: []