thin 1.6.2 → 1.6.3
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 +4 -4
- data/CHANGELOG +36 -29
- data/README.md +115 -9
- data/lib/rack/adapter/rails.rb +40 -45
- data/lib/thin/backends/base.rb +4 -0
- data/lib/thin/backends/swiftiply_client.rb +10 -10
- data/lib/thin/controllers/controller.rb +1 -1
- data/lib/thin/request.rb +5 -5
- data/lib/thin/response.rb +1 -1
- data/lib/thin/runner.rb +1 -0
- data/lib/thin/server.rb +8 -2
- data/lib/thin/statuses.rb +2 -1
- data/lib/thin/version.rb +2 -2
- metadata +31 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a52ecc8925833038f1f9b6ac7b421032e9524d79
|
4
|
+
data.tar.gz: 5270eac2bbf836f0574704b908c7db468e05d977
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 992772f4b87b8086f5a99323cefd7ec748b89148d58f2758c9e911b84f1bc72f5c8181460145f92660ba0def62d2c8fcb4a9d4aca7aa32eae98805ea316ec654
|
7
|
+
data.tar.gz: 1617c532da78f8a0173e933dee24c03ac521cdbd41ef79e83fc2543a993dbccc1bd528638c0fac3668996cc1939c9e233f75f5fda78240460333cdabb23be2b1
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 1.6.3 Protein Powder
|
2
|
+
* Add HTTP 422 status code [rajcybage]
|
3
|
+
* Add warning about EM reactor still running when stopping.
|
4
|
+
* Remove version number from "Server" HTTP header. [benbasson]
|
5
|
+
* Adding `--ssl-disable-verify` to allow disabling of client cert requests when SSL enabled [brucek]
|
6
|
+
* Ensure Tempfiles created by a large request are closed and deleted. [Tonkpils]
|
7
|
+
|
1
8
|
== 1.6.2 Doc Brown
|
2
9
|
* No longer replace response's body on HEAD request. Ensuring body.close will be called.
|
3
10
|
* Remove `---ssl-verify` option as EventMachine doesn't verify the certificate.
|
@@ -54,10 +61,10 @@
|
|
54
61
|
It is now the responsibility of the app (or a middleware) to set the Content-Length.
|
55
62
|
* Log errors to STDERR [textgoeshere]
|
56
63
|
* Shut down gracefully when receiving SIGTERM [ddollar]
|
57
|
-
|
64
|
+
|
58
65
|
Processes are allowed a chance to shut down gracefully when receiving
|
59
66
|
SIGTERM (http://en.wikipedia.org/wiki/SIGTERM).
|
60
|
-
|
67
|
+
|
61
68
|
On Heroku, when shutting down a process, we send a SIGTERM followed 10
|
62
69
|
seconds later with a SIGKILL, similar to the behavior of the init daemon
|
63
70
|
on most Unix systems. This patch will allow Heroku apps to shut down
|
@@ -82,7 +89,7 @@
|
|
82
89
|
the existing connection to another protocol, and specifically is NOT
|
83
90
|
used to upgrade a separate connection. Therefore, the connection must
|
84
91
|
remain open after this response in order to facilitate that.
|
85
|
-
|
92
|
+
|
86
93
|
* Accept IE7 badly encoded URL (eg.: %uEEEE)
|
87
94
|
* Fix gemspec to work w/ Bundler [smparkes]
|
88
95
|
* Add SSL support [tmm1]
|
@@ -98,10 +105,10 @@
|
|
98
105
|
--ssl-key-file PATH Path to private key
|
99
106
|
--ssl-cert-file PATH Path to certificate
|
100
107
|
--ssl-verify Enables SSL certificate verification
|
101
|
-
|
108
|
+
|
102
109
|
* Expose peer SSL certificate in env (rack.peer_cert) [fd]
|
103
110
|
* Adjusting unix socket permissions to be more open [mbj]
|
104
|
-
|
111
|
+
|
105
112
|
== 1.2.7 No Hup
|
106
113
|
* Support multiple Ruby version (fat binaries under windows)
|
107
114
|
* Do not trap unsupported HUP signal on Windows
|
@@ -125,7 +132,7 @@
|
|
125
132
|
== 1.2.2 I Find Your Lack of Sauce Disturbing release
|
126
133
|
* Fix force kill under 1.9 [Alexey Chebotar]
|
127
134
|
* Fix regression when --only option is used w/ --socket.
|
128
|
-
* Add process name 'tag' functionality. Easier to distinguish thin daemons
|
135
|
+
* Add process name 'tag' functionality. Easier to distinguish thin daemons
|
129
136
|
from eachother in process listing [ctcherry]
|
130
137
|
|
131
138
|
== 1.2.1 Asynctilicious Ultra Supreme release
|
@@ -135,11 +142,11 @@
|
|
135
142
|
* Allow String for response body
|
136
143
|
* Require openssl before eventmachine to prevent crash in 1.9
|
137
144
|
|
138
|
-
== 1.2.0 Asynctilicious Supreme release
|
145
|
+
== 1.2.0 Asynctilicious Supreme release
|
139
146
|
* Add support for Windows mingw Ruby distro [Juan C. Rodriguez]
|
140
147
|
* Add async response support, see example/async_*.ru [raggi]
|
141
148
|
|
142
|
-
== 1.1.1 Super Disco Power Plus release
|
149
|
+
== 1.1.1 Super Disco Power Plus release
|
143
150
|
* Fix bug when running with only options [hasimo]
|
144
151
|
|
145
152
|
== 1.1.0 Super Disco Power release
|
@@ -236,20 +243,20 @@
|
|
236
243
|
* Add tasks for Vlad the Deployer in example/vlad.rake [cnantais]
|
237
244
|
* Add Ramaze Rackup config file in example dir [tmm1]
|
238
245
|
Use like this from you Ramaze app dir:
|
239
|
-
|
246
|
+
|
240
247
|
thin start -r /path/to/thin/example/ramaze.ru
|
241
|
-
|
248
|
+
|
242
249
|
* Add the --rackup option to load a Rack config file instead of the Rails adapter.
|
243
250
|
So you can use any framework with the thin script and start cluster and stuff like that.
|
244
251
|
A Rack config file is one that is usable through the rackup command and looks like this:
|
245
|
-
|
252
|
+
|
246
253
|
use Rack::CommonLogger
|
247
254
|
run MyCrazyRackAdapter.new(:uterly, 'cool')
|
248
|
-
|
255
|
+
|
249
256
|
Then use it with thin like this:
|
250
|
-
|
257
|
+
|
251
258
|
thin start --rackup config.ru
|
252
|
-
|
259
|
+
|
253
260
|
* thin config --chrdir ... -C thin/yml do not change current directory anymore, fixes #33.
|
254
261
|
* Add a better sample god config file in example/thin.god that loads all info from config
|
255
262
|
files in /etc/thin. Drop-in replacement for the thin runlevel service [Gump].
|
@@ -257,9 +264,9 @@
|
|
257
264
|
configuration.
|
258
265
|
* Add a script to run thin as a runlevel service that can start at startup, closes #31 [Gump]
|
259
266
|
Setup the service like this:
|
260
|
-
|
267
|
+
|
261
268
|
sudo thin install /etc/thin
|
262
|
-
|
269
|
+
|
263
270
|
This will install the boot script under /etc/init.d/thin. Then copy your config files to
|
264
271
|
/etc/thin. Works only under Linux.
|
265
272
|
* Set process name to 'thin server (0.0.0.0:3000)' when running as a daemon, closes #32.
|
@@ -285,9 +292,9 @@
|
|
285
292
|
* Add example config files for http://www.tildeslash.com/monit usage.
|
286
293
|
Include the example file using "include /path/to/thin/monit/file" in your monitrc file.
|
287
294
|
The group settings let you do this to manage your clusters:
|
288
|
-
|
295
|
+
|
289
296
|
sudo monit -g blog restart all
|
290
|
-
|
297
|
+
|
291
298
|
There are examples of thin listening on sockets and thin listening on unix sockets.
|
292
299
|
|
293
300
|
== 0.6.1 Cheesecake release
|
@@ -298,20 +305,20 @@
|
|
298
305
|
* Add support for connection through UNIX domain socket.
|
299
306
|
Use the --socket (-S) option w/ the thin script to configure the socket filename.
|
300
307
|
Nginx support binding to a UNIX socket like this:
|
301
|
-
|
308
|
+
|
302
309
|
upstream backend {
|
303
310
|
server unix:/tmp/thin.0.sock;
|
304
311
|
server unix:/tmp/thin.1.sock;
|
305
312
|
server unix:/tmp/thin.2.sock;
|
306
313
|
}
|
307
|
-
|
314
|
+
|
308
315
|
Start your servers like this:
|
309
|
-
|
316
|
+
|
310
317
|
thin start -s3 -S/tmp/thin.sock
|
311
|
-
|
318
|
+
|
312
319
|
* Remove Server#listen! method. Use Server#start instead.
|
313
320
|
* Server can now yield a Rack::Builder to allow building an app in one call:
|
314
|
-
|
321
|
+
|
315
322
|
Server.start '0.0.0.0', 3000 do
|
316
323
|
use Rack::CommonLogger
|
317
324
|
use Rack::ShowExceptions
|
@@ -320,13 +327,13 @@
|
|
320
327
|
run Rack::Lobster.new
|
321
328
|
end
|
322
329
|
end
|
323
|
-
|
330
|
+
|
324
331
|
* Add a very basic stats page through Stats adapter, load w/ --stats and browse to /stats.
|
325
332
|
* Add --trace (-V) option to trace request/response and get backtrace w/out all Ruby debug stuff.
|
326
333
|
* Add --config (-C) option to load options from a config file in thin script [Matt Todd].
|
327
334
|
* Alter response headers to output directly to a string.
|
328
335
|
* Improve specs stability.
|
329
|
-
* Move request body to a Tempfile if too big (> 112
|
336
|
+
* Move request body to a Tempfile if too big (> 112 KB)
|
330
337
|
* Remove useless check for max header size in Request (already done in the parser)
|
331
338
|
|
332
339
|
== 0.5.4 Flying Mustard release
|
@@ -338,7 +345,7 @@
|
|
338
345
|
Thanks to Kent Sibilev and Ezra for their help on that one.
|
339
346
|
* Add 'Server' response header
|
340
347
|
* Fix --user and --group option not changing daemon process privileges
|
341
|
-
|
348
|
+
|
342
349
|
== 0.5.3 Purple Yogurt release
|
343
350
|
* win32 pre-compiled gem now available
|
344
351
|
* change rake task configuration to allow win32 gem build
|
@@ -358,7 +365,7 @@
|
|
358
365
|
--log-file => --log
|
359
366
|
--pid-file => --pid
|
360
367
|
--env => --environment
|
361
|
-
|
368
|
+
|
362
369
|
== 0.5.1 LOLCAT release
|
363
370
|
* Add URL rewriting to Rails adapter so that page caching works and / fetches index.html if present.
|
364
371
|
* Fix bug in multiline response header parsing.
|
@@ -373,9 +380,9 @@
|
|
373
380
|
|
374
381
|
== 0.5.0
|
375
382
|
* Full rewrite to use EventMachine, Rack and Mongrel parser
|
376
|
-
|
383
|
+
|
377
384
|
== 0.4.1
|
378
385
|
* Fix Rails environment option not being used in thin script.
|
379
|
-
|
386
|
+
|
380
387
|
== 0.4.0
|
381
388
|
* First alphaish release as a gem.
|
data/README.md
CHANGED
@@ -18,8 +18,8 @@ bundled in an easy to use gem for your own pleasure.
|
|
18
18
|
Code: http://github.com/macournoyer/thin
|
19
19
|
IRC: #thin on freenode
|
20
20
|
|
21
|
-
Installation
|
22
|
-
|
21
|
+
## Installation
|
22
|
+
|
23
23
|
For the latest stable version:
|
24
24
|
|
25
25
|
`gem install thin`
|
@@ -32,9 +32,8 @@ cd thin
|
|
32
32
|
rake install
|
33
33
|
```
|
34
34
|
|
35
|
+
## Usage
|
35
36
|
|
36
|
-
Usage
|
37
|
-
=====
|
38
37
|
A +thin+ script offers an easy way to start your Rack application:
|
39
38
|
|
40
39
|
```
|
@@ -45,14 +44,121 @@ thin start
|
|
45
44
|
When using with Rails and Bundler, make sure to add `gem 'thin'`
|
46
45
|
to your Gemfile.
|
47
46
|
|
48
|
-
See example directory for samples
|
47
|
+
See example directory for samples.
|
48
|
+
|
49
|
+
### Command Line Examples
|
50
|
+
|
51
|
+
Use a rackup file and bind to localhost port 8080:
|
52
|
+
|
53
|
+
```
|
54
|
+
thin -R config.ru -a 127.0.0.1 -p 8080 start
|
55
|
+
```
|
56
|
+
|
57
|
+
Store the server process ID, log to a file and daemonize:
|
58
|
+
|
59
|
+
```
|
60
|
+
thin -p 9292 -P tmp/pids/thin.pid -l logs/thin.log -d start
|
61
|
+
```
|
62
|
+
|
63
|
+
Thin is quite flexible in that many options can be specified at the command line (see below for usage).
|
64
|
+
|
65
|
+
### Configuration files
|
66
|
+
|
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:
|
68
|
+
|
69
|
+
```yaml
|
70
|
+
---
|
71
|
+
user: www-data
|
72
|
+
group: www-data
|
73
|
+
pid: tmp/pids/thin.pid
|
74
|
+
timeout: 30
|
75
|
+
wait: 30
|
76
|
+
log: log/thin.log
|
77
|
+
max_conns: 1024
|
78
|
+
require: []
|
79
|
+
environment: production
|
80
|
+
max_persistent_conns: 512
|
81
|
+
servers: 1
|
82
|
+
threaded: true
|
83
|
+
no-epoll: true
|
84
|
+
daemonize: true
|
85
|
+
socket: tmp/sockets/thin.sock
|
86
|
+
chdir: /path/to/your/apps/root
|
87
|
+
tag: a-name-to-show-up-in-ps aux
|
88
|
+
```
|
89
|
+
|
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
|
+
## License
|
49
157
|
|
50
|
-
License
|
51
|
-
=======
|
52
158
|
Ruby License, http://www.ruby-lang.org/en/LICENSE.txt.
|
53
159
|
|
54
|
-
Credits
|
55
|
-
|
160
|
+
## Credits
|
161
|
+
|
56
162
|
The parser was stolen from Mongrel http://mongrel.rubyforge.org by Zed Shaw.
|
57
163
|
Mongrel is copyright 2007 Zed A. Shaw and contributors. It is licensed under
|
58
164
|
the Ruby license and the GPL2.
|
data/lib/rack/adapter/rails.rb
CHANGED
@@ -11,32 +11,27 @@ require 'cgi'
|
|
11
11
|
#
|
12
12
|
# Based on http://fuzed.rubyforge.org/ Rails adapter
|
13
13
|
module Rack
|
14
|
-
module Adapter
|
14
|
+
module Adapter
|
15
15
|
class Rails
|
16
16
|
FILE_METHODS = %w(GET HEAD).freeze
|
17
|
-
|
18
|
-
def initialize(options={})
|
19
|
-
@root = options[:root]
|
20
|
-
@env = options[:environment]
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
@root = options[:root] || Dir.pwd
|
20
|
+
@env = options[:environment] || 'development'
|
21
21
|
@prefix = options[:prefix]
|
22
|
-
|
22
|
+
|
23
23
|
load_application
|
24
|
-
|
25
|
-
@rails_app =
|
26
|
-
|
27
|
-
else
|
28
|
-
CgiApp.new
|
29
|
-
end
|
30
|
-
|
31
|
-
@file_app = Rack::File.new(::File.join(RAILS_ROOT, "public"))
|
24
|
+
|
25
|
+
@rails_app = self.class.rack_based? ? ActionController::Dispatcher.new : CgiApp.new
|
26
|
+
@file_app = Rack::File.new(::File.join(RAILS_ROOT, "public"))
|
32
27
|
end
|
33
|
-
|
28
|
+
|
34
29
|
def load_application
|
35
30
|
ENV['RAILS_ENV'] = @env
|
36
31
|
|
37
32
|
require "#{@root}/config/environment"
|
38
33
|
require 'dispatcher'
|
39
|
-
|
34
|
+
|
40
35
|
if @prefix
|
41
36
|
if ActionController::Base.respond_to?(:relative_url_root=)
|
42
37
|
ActionController::Base.relative_url_root = @prefix # Rails 2.1.1
|
@@ -45,17 +40,17 @@ module Rack
|
|
45
40
|
end
|
46
41
|
end
|
47
42
|
end
|
48
|
-
|
43
|
+
|
49
44
|
def file_exist?(path)
|
50
45
|
full_path = ::File.join(@file_app.root, Utils.unescape(path))
|
51
46
|
::File.file?(full_path) && ::File.readable_real?(full_path)
|
52
47
|
end
|
53
|
-
|
48
|
+
|
54
49
|
def call(env)
|
55
50
|
path = env['PATH_INFO'].chomp('/')
|
56
51
|
method = env['REQUEST_METHOD']
|
57
52
|
cached_path = (path.empty? ? 'index' : path) + ActionController::Base.page_cache_extension
|
58
|
-
|
53
|
+
|
59
54
|
if FILE_METHODS.include?(method)
|
60
55
|
if file_exist?(path) # Serve the file if it's there
|
61
56
|
return @file_app.call(env)
|
@@ -64,11 +59,11 @@ module Rack
|
|
64
59
|
return @file_app.call(env)
|
65
60
|
end
|
66
61
|
end
|
67
|
-
|
62
|
+
|
68
63
|
# No static file, let Rails handle it
|
69
64
|
@rails_app.call(env)
|
70
65
|
end
|
71
|
-
|
66
|
+
|
72
67
|
def self.rack_based?
|
73
68
|
rails_version = ::Rails::VERSION
|
74
69
|
return false if rails_version::MAJOR < 2
|
@@ -76,7 +71,7 @@ module Rack
|
|
76
71
|
return false if rails_version::MAJOR == 2 && rails_version::MINOR == 2 && rails_version::TINY < 3
|
77
72
|
true # >= 2.2.3
|
78
73
|
end
|
79
|
-
|
74
|
+
|
80
75
|
protected
|
81
76
|
# For Rails pre Rack (2.3)
|
82
77
|
class CgiApp
|
@@ -91,7 +86,7 @@ module Rack
|
|
91
86
|
response.finish
|
92
87
|
end
|
93
88
|
end
|
94
|
-
|
89
|
+
|
95
90
|
class CGIWrapper < ::CGI
|
96
91
|
def initialize(request, response, *args)
|
97
92
|
@request = request
|
@@ -101,36 +96,36 @@ module Rack
|
|
101
96
|
|
102
97
|
super *args
|
103
98
|
end
|
104
|
-
|
105
|
-
def header(options =
|
99
|
+
|
100
|
+
def header(options = 'text/html')
|
106
101
|
if options.is_a?(String)
|
107
102
|
@response['Content-Type'] = options unless @response['Content-Type']
|
108
103
|
else
|
109
104
|
@response['Content-Length'] = options.delete('Content-Length').to_s if options['Content-Length']
|
110
|
-
|
105
|
+
|
111
106
|
@response['Content-Type'] = options.delete('type') || "text/html"
|
112
|
-
@response['Content-Type'] +=
|
113
|
-
|
107
|
+
@response['Content-Type'] += '; charset=' + options.delete('charset') if options['charset']
|
108
|
+
|
114
109
|
@response['Content-Language'] = options.delete('language') if options['language']
|
115
110
|
@response['Expires'] = options.delete('expires') if options['expires']
|
116
111
|
|
117
112
|
@response.status = options.delete('Status') if options['Status']
|
118
|
-
|
113
|
+
|
119
114
|
# Convert 'cookie' header to 'Set-Cookie' headers.
|
120
|
-
# Because Set-Cookie header can appear more the once in the response body,
|
115
|
+
# Because Set-Cookie header can appear more the once in the response body,
|
121
116
|
# we store it in a line break seperated string that will be translated to
|
122
117
|
# multiple Set-Cookie header by the handler.
|
123
118
|
if cookie = options.delete('cookie')
|
124
119
|
cookies = []
|
125
|
-
|
120
|
+
|
126
121
|
case cookie
|
127
122
|
when Array then cookie.each { |c| cookies << c.to_s }
|
128
123
|
when Hash then cookie.each { |_, c| cookies << c.to_s }
|
129
124
|
else cookies << cookie.to_s
|
130
125
|
end
|
131
|
-
|
126
|
+
|
132
127
|
@output_cookies.each { |c| cookies << c.to_s } if @output_cookies
|
133
|
-
|
128
|
+
|
134
129
|
@response['Set-Cookie'] = [@response['Set-Cookie'], cookies].compact
|
135
130
|
# See http://groups.google.com/group/rack-devel/browse_thread/thread/e8759b91a82c5a10/a8dbd4574fe97d69?#a8dbd4574fe97d69
|
136
131
|
if Thin.ruby_18?
|
@@ -139,42 +134,42 @@ module Rack
|
|
139
134
|
@response['Set-Cookie'] = @response['Set-Cookie'].join("\n")
|
140
135
|
end
|
141
136
|
end
|
142
|
-
|
143
|
-
options.each { |k,v| @response[k] = v }
|
137
|
+
|
138
|
+
options.each { |k, v| @response[k] = v }
|
144
139
|
end
|
145
|
-
|
146
|
-
|
140
|
+
|
141
|
+
''
|
147
142
|
end
|
148
|
-
|
143
|
+
|
149
144
|
def params
|
150
145
|
@params ||= @request.params
|
151
146
|
end
|
152
|
-
|
147
|
+
|
153
148
|
def cookies
|
154
149
|
@request.cookies
|
155
150
|
end
|
156
|
-
|
151
|
+
|
157
152
|
def query_string
|
158
153
|
@request.query_string
|
159
154
|
end
|
160
|
-
|
155
|
+
|
161
156
|
# Used to wrap the normal args variable used inside CGI.
|
162
157
|
def args
|
163
158
|
@args
|
164
159
|
end
|
165
|
-
|
160
|
+
|
166
161
|
# Used to wrap the normal env_table variable used inside CGI.
|
167
162
|
def env_table
|
168
163
|
@request.env
|
169
164
|
end
|
170
|
-
|
165
|
+
|
171
166
|
# Used to wrap the normal stdinput variable used inside CGI.
|
172
167
|
def stdinput
|
173
168
|
@input
|
174
169
|
end
|
175
|
-
|
170
|
+
|
176
171
|
def stdoutput
|
177
|
-
STDERR.puts
|
172
|
+
STDERR.puts 'stdoutput should not be used.'
|
178
173
|
@response.body
|
179
174
|
end
|
180
175
|
end
|
data/lib/thin/backends/base.rb
CHANGED
@@ -3,10 +3,10 @@ module Thin
|
|
3
3
|
# Backend to act as a Swiftiply client (http://swiftiply.swiftcore.org).
|
4
4
|
class SwiftiplyClient < Base
|
5
5
|
attr_accessor :key
|
6
|
-
|
6
|
+
|
7
7
|
attr_accessor :host, :port
|
8
|
-
|
9
|
-
def initialize(host, port, options={})
|
8
|
+
|
9
|
+
def initialize(host, port, options = {})
|
10
10
|
@host = host
|
11
11
|
@port = port.to_i
|
12
12
|
@key = options[:swiftiply].to_s
|
@@ -26,31 +26,31 @@ module Thin
|
|
26
26
|
def to_s
|
27
27
|
"#{@host}:#{@port} swiftiply"
|
28
28
|
end
|
29
|
-
end
|
29
|
+
end
|
30
30
|
end
|
31
31
|
|
32
32
|
class SwiftiplyConnection < Connection
|
33
33
|
def connection_completed
|
34
34
|
send_data swiftiply_handshake(@backend.key)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def persistent?
|
38
38
|
true
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def unbind
|
42
42
|
super
|
43
43
|
EventMachine.add_timer(rand(2)) { reconnect(@backend.host, @backend.port) } if @backend.running?
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
protected
|
47
47
|
def swiftiply_handshake(key)
|
48
|
-
'swiftclient' << host_ip.collect { |x| sprintf('%02x', x.to_i)}.join << sprintf('%04x', @backend.port) << sprintf('%02x', key.length) << key
|
48
|
+
'swiftclient' << host_ip.collect { |x| sprintf('%02x', x.to_i) }.join << sprintf('%04x', @backend.port) << sprintf('%02x', key.length) << key
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
# For some reason Swiftiply request the current host
|
52
52
|
def host_ip
|
53
|
-
Socket.gethostbyname(@backend.host)[3].unpack('CCCC') rescue [0,0,0,0]
|
53
|
+
Socket.gethostbyname(@backend.host)[3].unpack('CCCC') rescue [0, 0, 0, 0]
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -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 =>
|
58
|
+
server.ssl_options = { :private_key_file => @options[:ssl_key_file], :cert_chain_file => @options[:ssl_cert_file], :verify_peer => !@options[:ssl_disable_verify] }
|
59
59
|
end
|
60
60
|
|
61
61
|
# Detach the process, after this line the current process returns
|
data/lib/thin/request.rb
CHANGED
@@ -12,11 +12,11 @@ module Thin
|
|
12
12
|
MAX_BODY = 1024 * (80 + 32)
|
13
13
|
BODY_TMPFILE = 'thin-body'.freeze
|
14
14
|
MAX_HEADER = 1024 * (80 + 32)
|
15
|
-
|
15
|
+
|
16
16
|
INITIAL_BODY = ''
|
17
17
|
# Force external_encoding of request's body to ASCII_8BIT
|
18
18
|
INITIAL_BODY.encode!(Encoding::ASCII_8BIT) if INITIAL_BODY.respond_to?(:encode!)
|
19
|
-
|
19
|
+
|
20
20
|
# Freeze some HTTP header names & values
|
21
21
|
SERVER_SOFTWARE = 'SERVER_SOFTWARE'.freeze
|
22
22
|
SERVER_NAME = 'SERVER_NAME'.freeze
|
@@ -30,7 +30,7 @@ module Thin
|
|
30
30
|
KEEP_ALIVE_REGEXP = /\bkeep-alive\b/i.freeze
|
31
31
|
CLOSE_REGEXP = /\bclose\b/i.freeze
|
32
32
|
HEAD = 'HEAD'.freeze
|
33
|
-
|
33
|
+
|
34
34
|
# Freeze some Rack header names
|
35
35
|
RACK_INPUT = 'rack.input'.freeze
|
36
36
|
RACK_VERSION = 'rack.version'.freeze
|
@@ -135,7 +135,7 @@ module Thin
|
|
135
135
|
@env[ASYNC_CALLBACK] = callback
|
136
136
|
@env[ASYNC_CLOSE] = EventMachine::DefaultDeferrable.new
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
def async_close
|
140
140
|
@async_close ||= @env[ASYNC_CLOSE]
|
141
141
|
end
|
@@ -146,7 +146,7 @@ module Thin
|
|
146
146
|
|
147
147
|
# Close any resource used by the request
|
148
148
|
def close
|
149
|
-
@body.
|
149
|
+
@body.close! if @body.class == Tempfile
|
150
150
|
end
|
151
151
|
|
152
152
|
private
|
data/lib/thin/response.rb
CHANGED
@@ -35,7 +35,7 @@ module Thin
|
|
35
35
|
def headers_output
|
36
36
|
# Set default headers
|
37
37
|
@headers[CONNECTION] = persistent? ? KEEP_ALIVE : CLOSE unless @headers.has_key?(CONNECTION)
|
38
|
-
@headers[SERVER] = Thin::
|
38
|
+
@headers[SERVER] = Thin::NAME unless @headers.has_key?(SERVER)
|
39
39
|
|
40
40
|
@headers.to_s
|
41
41
|
end
|
data/lib/thin/runner.rb
CHANGED
@@ -79,6 +79,7 @@ module Thin
|
|
79
79
|
opts.on( "--ssl", "Enables SSL") { @options[:ssl] = true }
|
80
80
|
opts.on( "--ssl-key-file PATH", "Path to private key") { |path| @options[:ssl_key_file] = path }
|
81
81
|
opts.on( "--ssl-cert-file PATH", "Path to certificate") { |path| @options[:ssl_cert_file] = path }
|
82
|
+
opts.on( "--ssl-disable-verify", "Disables (optional) client cert requests") { @options[:ssl_disable_verify] = true }
|
82
83
|
|
83
84
|
opts.separator ""
|
84
85
|
opts.separator "Adapter options:"
|
data/lib/thin/server.rb
CHANGED
@@ -158,7 +158,7 @@ module Thin
|
|
158
158
|
|
159
159
|
log_info "Maximum connections set to #{@backend.maximum_connections}"
|
160
160
|
log_info "Listening on #{@backend}, CTRL+C to stop"
|
161
|
-
|
161
|
+
|
162
162
|
@backend.start { setup_signals if @setup_signals }
|
163
163
|
end
|
164
164
|
alias :start! :start
|
@@ -185,7 +185,13 @@ module Thin
|
|
185
185
|
# This doesn't wait for connection to finish their work and send data.
|
186
186
|
# All current requests will be dropped.
|
187
187
|
def stop!
|
188
|
-
|
188
|
+
if @backend.started_reactor?
|
189
|
+
log_info "Stopping ..."
|
190
|
+
else
|
191
|
+
log_info "Stopping Thin ..."
|
192
|
+
log_info "Thin was started inside an existing EventMachine.run block."
|
193
|
+
log_info "Call `EventMachine.stop` to stop the reactor and quit the process."
|
194
|
+
end
|
189
195
|
|
190
196
|
@backend.stop!
|
191
197
|
end
|
data/lib/thin/statuses.rb
CHANGED
@@ -32,7 +32,8 @@ module Thin
|
|
32
32
|
412 => 'Precondition Failed',
|
33
33
|
413 => 'Request Entity Too Large',
|
34
34
|
414 => 'Request-URI Too Large',
|
35
|
-
415 => 'Unsupported Media Type',
|
35
|
+
415 => 'Unsupported Media Type',
|
36
|
+
422 => 'Unprocessable Entity',
|
36
37
|
500 => 'Internal Server Error',
|
37
38
|
501 => 'Not Implemented',
|
38
39
|
502 => 'Bad Gateway',
|
data/lib/thin/version.rb
CHANGED
@@ -6,11 +6,11 @@ module Thin
|
|
6
6
|
module VERSION #:nodoc:
|
7
7
|
MAJOR = 1
|
8
8
|
MINOR = 6
|
9
|
-
TINY =
|
9
|
+
TINY = 3
|
10
10
|
|
11
11
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
12
12
|
|
13
|
-
CODENAME = "
|
13
|
+
CODENAME = "Protein Powder".freeze
|
14
14
|
|
15
15
|
RACK = [1, 0].freeze # Rack protocol version
|
16
16
|
end
|
metadata
CHANGED
@@ -1,55 +1,61 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc-Andre Cournoyer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-02 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.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.0
|
26
|
+
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: eventmachine
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.0
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.0
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: daemons
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
- - ">="
|
46
49
|
- !ruby/object:Gem::Version
|
47
50
|
version: 1.0.9
|
48
51
|
type: :runtime
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
51
54
|
requirements:
|
52
|
-
- -
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.0'
|
58
|
+
- - ">="
|
53
59
|
- !ruby/object:Gem::Version
|
54
60
|
version: 1.0.9
|
55
61
|
description: A thin and fast web server
|
@@ -77,8 +83,16 @@ files:
|
|
77
83
|
- example/thin_solaris_smf.erb
|
78
84
|
- example/thin_solaris_smf.readme.txt
|
79
85
|
- example/vlad.rake
|
86
|
+
- ext/thin_parser/common.rl
|
87
|
+
- ext/thin_parser/ext_help.h
|
88
|
+
- ext/thin_parser/extconf.rb
|
89
|
+
- ext/thin_parser/parser.c
|
90
|
+
- ext/thin_parser/parser.h
|
91
|
+
- ext/thin_parser/parser.rl
|
92
|
+
- ext/thin_parser/thin.c
|
80
93
|
- lib/rack/adapter/loader.rb
|
81
94
|
- lib/rack/adapter/rails.rb
|
95
|
+
- lib/thin.rb
|
82
96
|
- lib/thin/backends/base.rb
|
83
97
|
- lib/thin/backends/swiftiply_client.rb
|
84
98
|
- lib/thin/backends/tcp_server.rb
|
@@ -100,17 +114,10 @@ files:
|
|
100
114
|
- lib/thin/stats.rb
|
101
115
|
- lib/thin/statuses.rb
|
102
116
|
- lib/thin/version.rb
|
103
|
-
- lib/thin.rb
|
104
|
-
- ext/thin_parser/ext_help.h
|
105
|
-
- ext/thin_parser/parser.h
|
106
|
-
- ext/thin_parser/parser.c
|
107
|
-
- ext/thin_parser/thin.c
|
108
|
-
- ext/thin_parser/extconf.rb
|
109
|
-
- ext/thin_parser/common.rl
|
110
|
-
- ext/thin_parser/parser.rl
|
111
117
|
homepage: http://code.macournoyer.com/thin/
|
112
118
|
licenses:
|
113
|
-
-
|
119
|
+
- GPLv2+
|
120
|
+
- Ruby 1.8
|
114
121
|
metadata: {}
|
115
122
|
post_install_message:
|
116
123
|
rdoc_options: []
|
@@ -118,17 +125,17 @@ require_paths:
|
|
118
125
|
- lib
|
119
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
127
|
requirements:
|
121
|
-
- -
|
128
|
+
- - ">="
|
122
129
|
- !ruby/object:Gem::Version
|
123
130
|
version: 1.8.5
|
124
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
132
|
requirements:
|
126
|
-
- -
|
133
|
+
- - ">="
|
127
134
|
- !ruby/object:Gem::Version
|
128
135
|
version: '0'
|
129
136
|
requirements: []
|
130
137
|
rubyforge_project: thin
|
131
|
-
rubygems_version: 2.
|
138
|
+
rubygems_version: 2.2.2
|
132
139
|
signing_key:
|
133
140
|
specification_version: 4
|
134
141
|
summary: A thin and fast web server
|