thin 1.7.2 → 1.8.1
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 +5 -5
- data/CHANGELOG +6 -0
- data/example/async_chat.ru +0 -0
- data/example/async_tailer.ru +0 -0
- data/ext/thin_parser/parser.h +5 -5
- data/lib/rack/handler/thin.rb +38 -0
- data/lib/thin/backends/base.rb +3 -1
- data/lib/thin/daemonizing.rb +24 -5
- data/lib/thin/headers.rb +7 -0
- data/lib/thin/logging.rb +1 -1
- data/lib/thin/request.rb +3 -1
- data/lib/thin/statuses.rb +8 -4
- data/lib/thin/version.rb +5 -5
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f0681c9fc49913fca3b6478faa3ce96a449e3926e09d5986fca0b1ace57d6fc7
|
4
|
+
data.tar.gz: 44f1f7fd3b3e176939178745df3116286b2b32cd5c01d0d6fe19bf4637e5aac7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e476bb431b484071fff7240da1d17265ad07571951697ca9d023e457268911b2d3c37451236aabf6ff57b59eb9d30c51479bd3ef3f39aadbf6ce830f5c212a8
|
7
|
+
data.tar.gz: '094627fc3d7da6e51c64059987625c9d5c1bbeec5b4766343b41aa00a1ebb769ea89ed7cf14ba9c6805450ffc82b92d7abd1ae7b4138c37ff7054d26fe337e69'
|
data/CHANGELOG
CHANGED
data/example/async_chat.ru
CHANGED
File without changes
|
data/example/async_tailer.ru
CHANGED
File without changes
|
data/ext/thin_parser/parser.h
CHANGED
@@ -38,11 +38,11 @@ typedef struct http_parser {
|
|
38
38
|
|
39
39
|
} http_parser;
|
40
40
|
|
41
|
-
int
|
42
|
-
int
|
43
|
-
size_t
|
44
|
-
int
|
45
|
-
int
|
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
|
|
@@ -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
|
data/lib/thin/backends/base.rb
CHANGED
@@ -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.
|
data/lib/thin/daemonizing.rb
CHANGED
@@ -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
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}"
|
@@ -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
|
-
|
126
|
-
|
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}"
|
data/lib/thin/headers.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
module Thin
|
2
|
+
# Raised when an header is not valid
|
3
|
+
# and the server can not process it.
|
4
|
+
class InvalidHeader < StandardError; end
|
5
|
+
|
2
6
|
# Store HTTP header name-value pairs direcly to a string
|
3
7
|
# and allow duplicated entries on some names.
|
4
8
|
class Headers
|
5
9
|
HEADER_FORMAT = "%s: %s\r\n".freeze
|
6
10
|
ALLOWED_DUPLICATES = %w(set-cookie set-cookie2 warning www-authenticate).freeze
|
11
|
+
CR_OR_LF = /[\r\n]/.freeze
|
7
12
|
|
8
13
|
def initialize
|
9
14
|
@sent = {}
|
@@ -22,6 +27,8 @@ module Thin
|
|
22
27
|
value.httpdate
|
23
28
|
when NilClass
|
24
29
|
return
|
30
|
+
when CR_OR_LF
|
31
|
+
raise InvalidHeader, "Header contains CR or LF"
|
25
32
|
else
|
26
33
|
value.to_s
|
27
34
|
end
|
data/lib/thin/logging.rb
CHANGED
data/lib/thin/request.rb
CHANGED
@@ -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
|
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
|
data/lib/thin/statuses.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/thin/version.rb
CHANGED
@@ -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 =
|
9
|
-
TINY =
|
8
|
+
MINOR = 8
|
9
|
+
TINY = 1
|
10
10
|
|
11
11
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
12
12
|
|
13
|
-
CODENAME = "
|
13
|
+
CODENAME = "Infinite Smoothie".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,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.1
|
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:
|
11
|
+
date: 2021-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -70,7 +70,7 @@ dependencies:
|
|
70
70
|
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: 1.0.9
|
73
|
-
description:
|
73
|
+
description:
|
74
74
|
email: macournoyer@gmail.com
|
75
75
|
executables:
|
76
76
|
- thin
|
@@ -104,6 +104,7 @@ files:
|
|
104
104
|
- ext/thin_parser/thin.c
|
105
105
|
- lib/rack/adapter/loader.rb
|
106
106
|
- lib/rack/adapter/rails.rb
|
107
|
+
- lib/rack/handler/thin.rb
|
107
108
|
- lib/thin.rb
|
108
109
|
- lib/thin/backends/base.rb
|
109
110
|
- lib/thin/backends/swiftiply_client.rb
|
@@ -126,10 +127,10 @@ files:
|
|
126
127
|
- lib/thin/stats.rb
|
127
128
|
- lib/thin/statuses.rb
|
128
129
|
- lib/thin/version.rb
|
129
|
-
homepage:
|
130
|
+
homepage: https://github.com/macournoyer/thin
|
130
131
|
licenses:
|
131
|
-
-
|
132
|
-
- Ruby
|
132
|
+
- GPL-2.0+
|
133
|
+
- Ruby
|
133
134
|
metadata:
|
134
135
|
source_code_uri: https://github.com/macournoyer/thin
|
135
136
|
changelog_uri: https://github.com/macournoyer/thin/blob/master/CHANGELOG
|
@@ -148,8 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
149
|
- !ruby/object:Gem::Version
|
149
150
|
version: '0'
|
150
151
|
requirements: []
|
151
|
-
|
152
|
-
rubygems_version: 2.5.1
|
152
|
+
rubygems_version: 3.0.3
|
153
153
|
signing_key:
|
154
154
|
specification_version: 4
|
155
155
|
summary: A thin and fast web server
|