thin 1.6.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []