unicorn-cuba-base 1.0.0 → 1.1.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.
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
data/lib/unicorn-cuba-base.rb
CHANGED
@@ -21,6 +21,7 @@ class Controler < Cuba
|
|
21
21
|
end
|
22
22
|
|
23
23
|
require_relative 'unicorn-cuba-base/stats_reporter'
|
24
|
+
require_relative 'unicorn-cuba-base/default_error_reporter'
|
24
25
|
|
25
26
|
class Application
|
26
27
|
def cli(&block)
|
@@ -90,9 +91,9 @@ class Application
|
|
90
91
|
access_log_file = @settings.access_log_file.open('a+')
|
91
92
|
access_log_file.sync = true
|
92
93
|
main_controler.use Rack::CommonLogger, access_log_file
|
94
|
+
main_controler.use Rack::MemoryLimit, @settings.limit_memory * 1024 ** 2
|
93
95
|
main_controler.use Rack::ErrorHandling
|
94
96
|
main_controler.use Rack::UnhandledRequest
|
95
|
-
main_controler.use Rack::MemoryLimit, @settings.limit_memory * 1024 ** 2
|
96
97
|
|
97
98
|
Unicorn::HttpServer.new(main_controler, unicorn_settings).start.join
|
98
99
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class DefaultErrorReporter < Controler
|
2
|
+
self.define do
|
3
|
+
on error Rack::UnhandledRequest::UnhandledRequestError do |error|
|
4
|
+
write_error 404, error
|
5
|
+
end
|
6
|
+
|
7
|
+
on error Unicorn::ClientShutdown do |error|
|
8
|
+
log.warn 'client disconnected prematurely', error
|
9
|
+
raise error
|
10
|
+
end
|
11
|
+
|
12
|
+
on error StandardError do |error|
|
13
|
+
log.error "unhandled error while processing request: #{env['REQUEST_METHOD']} #{env['SCRIPT_NAME']}[#{env["PATH_INFO"]}]", error
|
14
|
+
log.debug {
|
15
|
+
out = StringIO.new
|
16
|
+
PP::pp(env, out, 200)
|
17
|
+
"Request: \n" + out.string
|
18
|
+
}
|
19
|
+
|
20
|
+
write_error 500, error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -15,7 +15,7 @@ class MemoryLimit
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def read(bytes = nil)
|
18
|
-
data = @root_limit.get do |max_read_bytes|
|
18
|
+
data = @root_limit.get("#{self.class.name} IO read") do |max_read_bytes|
|
19
19
|
if not bytes or bytes > max_read_bytes
|
20
20
|
data = super max_read_bytes
|
21
21
|
raise MemoryLimitedExceededError unless eof?
|
@@ -28,27 +28,36 @@ class MemoryLimit
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def initialize(bytes = 256 * 1024 ** 2)
|
31
|
-
log.info "
|
31
|
+
log.info "setting up new memory limit of #{bytes} bytes" if bytes
|
32
32
|
@limit = bytes
|
33
33
|
end
|
34
34
|
|
35
35
|
attr_reader :limit
|
36
36
|
|
37
|
-
def get
|
37
|
+
def get(reason = nil)
|
38
38
|
yield(@limit).tap do |data|
|
39
|
-
borrow
|
39
|
+
borrow(data.bytesize, reason) if data
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def borrow(bytes)
|
44
|
-
|
43
|
+
def borrow(bytes, reason = nil)
|
44
|
+
if reason
|
45
|
+
log.debug "borrowing #{bytes} from #{@limit} bytes of limit for #{reason}"
|
46
|
+
else
|
47
|
+
log.debug "borrowing #{bytes} from #{@limit} bytes of limit"
|
48
|
+
end
|
49
|
+
|
45
50
|
bytes > @limit and raise MemoryLimitedExceededError
|
46
51
|
@limit -= bytes
|
47
52
|
bytes
|
48
53
|
end
|
49
54
|
|
50
|
-
def return(bytes)
|
51
|
-
|
55
|
+
def return(bytes, reason = nil)
|
56
|
+
if reason
|
57
|
+
log.debug "returning #{bytes} to #{@limit} bytes of limit used for #{reason}"
|
58
|
+
else
|
59
|
+
log.debug "returning #{bytes} to #{@limit} bytes of limit"
|
60
|
+
end
|
52
61
|
@limit += bytes
|
53
62
|
bytes
|
54
63
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'securerandom'
|
2
|
+
require 'json'
|
2
3
|
require 'unicorn-cuba-base/stats'
|
3
4
|
|
4
5
|
module Plugin
|
@@ -12,33 +13,39 @@ module Plugin
|
|
12
13
|
:total_write_error_part
|
13
14
|
)
|
14
15
|
|
15
|
-
def write(code, content_type, body)
|
16
|
+
def write(code, content_type, body, headers = {})
|
16
17
|
req.body.read # read all remaining upload before we send response so that client will read it
|
17
18
|
res.status = code
|
18
19
|
res["Content-Type"] = content_type
|
20
|
+
headers.each do |key, value|
|
21
|
+
res[key] = value
|
22
|
+
end
|
19
23
|
ResponseHelpers.stats.incr_total_write
|
20
24
|
res.write body
|
21
25
|
end
|
22
26
|
|
23
|
-
def
|
27
|
+
def write_text(code, content_type, msg, headers = {})
|
24
28
|
msg = msg.join("\r\n") if msg.is_a? Array
|
25
|
-
write code,
|
29
|
+
write code, content_type, (msg.gsub(/(?<!\r)\n/, "\r\n") + "\r\n"), headers
|
26
30
|
end
|
27
31
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
32
|
+
def write_plain(code, msg, headers = {})
|
33
|
+
write_text code, 'text/plain', msg, headers
|
34
|
+
end
|
35
|
+
|
36
|
+
def write_url_list(code, msg, headers = {})
|
37
|
+
write_text code, 'text/uri-list', msg, headers
|
31
38
|
end
|
32
39
|
|
33
|
-
def write_error(code, error)
|
40
|
+
def write_error(code, error, headers = {})
|
34
41
|
msg = error.message
|
35
42
|
log.warn "sending #{code} error response: #{msg}"
|
36
43
|
ResponseHelpers.stats.incr_total_write_error
|
37
|
-
write_plain code, msg
|
44
|
+
write_plain code, msg, headers
|
38
45
|
end
|
39
46
|
|
40
|
-
def
|
41
|
-
write code, '
|
47
|
+
def write_json(code, obj, headers = {})
|
48
|
+
write code, 'application/json', obj.to_json, headers
|
42
49
|
end
|
43
50
|
|
44
51
|
# Multipart
|
@@ -68,11 +75,11 @@ module Plugin
|
|
68
75
|
write_part 'text/plain', msg.to_s.gsub("\n", "\r\n"), headers
|
69
76
|
end
|
70
77
|
|
71
|
-
def write_error_part(code, error)
|
78
|
+
def write_error_part(code, error, headers = {})
|
72
79
|
msg = error.message
|
73
80
|
log.warn "sending error in multipart response part: #{msg}"
|
74
81
|
ResponseHelpers.stats.incr_total_write_error_part
|
75
|
-
write_plain_part msg, 'Status' => code
|
82
|
+
write_plain_part msg, headers.merge('Status' => code)
|
76
83
|
end
|
77
84
|
|
78
85
|
def write_epilogue
|
data/unicorn-cuba-base.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "unicorn-cuba-base"
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jakub Pastuszek"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-09-11"
|
13
13
|
s.description = "web application base powered by Unicorn HTTP server and based on Cuba framework extended with additional Rack middleware and Cuba plugins"
|
14
14
|
s.email = "jpastuszek@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"lib/unicorn-cuba-base.rb",
|
29
|
+
"lib/unicorn-cuba-base/default_error_reporter.rb",
|
29
30
|
"lib/unicorn-cuba-base/memory_limit.rb",
|
30
31
|
"lib/unicorn-cuba-base/plugin/error_matcher.rb",
|
31
32
|
"lib/unicorn-cuba-base/plugin/logging.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unicorn-cuba-base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cuba
|
@@ -173,6 +173,7 @@ files:
|
|
173
173
|
- Rakefile
|
174
174
|
- VERSION
|
175
175
|
- lib/unicorn-cuba-base.rb
|
176
|
+
- lib/unicorn-cuba-base/default_error_reporter.rb
|
176
177
|
- lib/unicorn-cuba-base/memory_limit.rb
|
177
178
|
- lib/unicorn-cuba-base/plugin/error_matcher.rb
|
178
179
|
- lib/unicorn-cuba-base/plugin/logging.rb
|
@@ -203,7 +204,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
203
204
|
version: '0'
|
204
205
|
segments:
|
205
206
|
- 0
|
206
|
-
hash:
|
207
|
+
hash: 463697011492453799
|
207
208
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
209
|
none: false
|
209
210
|
requirements:
|