lennarb 0.1.5 → 0.1.6
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.md +165 -0
- data/lib/lenna/application.rb +53 -0
- data/lib/lenna/middleware/app.rb +107 -92
- data/lib/lenna/middleware/default/error_handler.rb +184 -179
- data/lib/lenna/middleware/default/logging.rb +79 -81
- data/lib/lenna/router/builder.rb +111 -86
- data/lib/lenna/router/cache.rb +44 -30
- data/lib/lenna/router/namespace_stack.rb +66 -62
- data/lib/lenna/router/request.rb +125 -101
- data/lib/lenna/router/response.rb +505 -375
- data/lib/lenna/router/route_matcher.rb +56 -57
- data/lib/lenna/router.rb +186 -154
- data/lib/lennarb/array_extensions.rb +25 -11
- data/lib/lennarb/version.rb +5 -2
- data/lib/lennarb.rb +8 -1
- data/license.md +21 -0
- data/readme.md +31 -0
- metadata +64 -56
- data/CHANGELOG.md +0 -62
- data/LICENCE +0 -24
- data/README.md +0 -229
- data/lib/lenna/base.rb +0 -52
@@ -1,97 +1,103 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2023, by Aristóteles Coutinho.
|
5
|
+
|
3
6
|
require 'cgi'
|
4
7
|
|
5
8
|
module Lenna
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
9
|
+
module Middleware
|
10
|
+
module Default
|
11
|
+
# This middleware will handle errors.
|
12
|
+
#
|
13
|
+
# @private Since `v0.1.0`
|
14
|
+
#
|
15
|
+
module ErrorHandler
|
16
|
+
extend self
|
17
|
+
|
18
|
+
# This method will be called by the server.
|
19
|
+
#
|
20
|
+
# @parameter req [Rack::Request] The request object
|
21
|
+
# @parameter res [Rack::Response] The response object
|
22
|
+
# @parameter next_middleware [Proc] The next middleware in the stack
|
23
|
+
#
|
24
|
+
# @return [void]
|
25
|
+
#
|
26
|
+
def call(req, res, next_middleware)
|
27
|
+
next_middleware.call
|
28
|
+
rescue StandardError => e
|
29
|
+
env = req.env
|
30
|
+
log_error(env, e)
|
31
|
+
|
32
|
+
render_error_page(e, req, res)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# This method will render the error page.
|
38
|
+
#
|
39
|
+
# @parameter error [StandardError] The error object
|
40
|
+
# @parameter env [Hash] The environment variables
|
41
|
+
# @parameter res [Rack::Response] The response object
|
42
|
+
#
|
43
|
+
# @return [void]
|
44
|
+
#
|
45
|
+
def render_error_page(error, req, res)
|
46
|
+
case req.headers['Content-Type']
|
47
|
+
in 'application/json' then render_json(error, res)
|
48
|
+
else render_html(error, res)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# This method will render the JSON error page.
|
53
|
+
#
|
54
|
+
# @parameter error [StandardError] The error object
|
55
|
+
# @parameter env [Hash] The environment variables
|
56
|
+
# @parameter res [Rack::Response] The response object
|
57
|
+
#
|
58
|
+
# @return [void]
|
59
|
+
#
|
60
|
+
def render_json(error, res)
|
61
|
+
case ENV.fetch('RACK_ENV', 'development')
|
62
|
+
in 'development' | 'test' then res.json(
|
63
|
+
data: {
|
64
|
+
error: error.message,
|
65
|
+
status: 500
|
66
|
+
}
|
67
|
+
)
|
68
|
+
else res.json(data: { error: 'Internal Server Error', status: 500 })
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# This method will render the HTML error page.
|
73
|
+
#
|
74
|
+
# @parameter error [StandardError] The error object
|
75
|
+
# @parameter env [Hash] The environment variables
|
76
|
+
# @parameter res [Rack::Response] The response object
|
77
|
+
#
|
78
|
+
# @return [void]
|
79
|
+
#
|
80
|
+
def render_html(error, res)
|
81
|
+
res.html(error_page(error), status: 500)
|
82
|
+
end
|
83
|
+
|
84
|
+
# This method will log the error.
|
85
|
+
#
|
86
|
+
# @parameter env [Hash] The environment variables
|
87
|
+
# @parameter error [StandardError] The error object
|
88
|
+
#
|
89
|
+
# @return [void]
|
90
|
+
#
|
91
|
+
def log_error(env, error)
|
92
|
+
env['rack.errors'].puts error.message
|
93
|
+
env['rack.errors'].puts error.backtrace.join("\n")
|
94
|
+
env['rack.errors'].flush
|
95
|
+
end
|
96
|
+
|
97
|
+
# This method will render the error page.
|
98
|
+
#
|
99
|
+
def error_page(error)
|
100
|
+
style = <<-STYLE
|
95
101
|
<style>
|
96
102
|
body { font-family: 'Helvetica Neue', sans-serif; background-color: #F7F7F7; color: #333; margin: 0; padding: 0; }
|
97
103
|
.error-container { max-width: 600px; margin: 20px auto; padding: 20px; box-shadow: 0 4px 8px 0 rgba(0,0,0,0.1); background: white; border-radius: 4px; }
|
@@ -105,18 +111,18 @@ module Lenna
|
|
105
111
|
svg { fill: #e74c3c; width: 50px; height: auto; }
|
106
112
|
.container { display: flex; justify-content: space-between; align-items: center; align-content: center;}
|
107
113
|
</style>
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
114
|
+
STYLE
|
115
|
+
|
116
|
+
# SVG logo
|
117
|
+
svg_logo = <<~SVG
|
118
|
+
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="100" height="100" viewBox="0 0 100 100">
|
119
|
+
<path fill="#f1bc19" d="M77 12A1 1 0 1 0 77 14A1 1 0 1 0 77 12Z"></path><path fill="#e4e4f9" d="M50 13A37 37 0 1 0 50 87A37 37 0 1 0 50 13Z"></path><path fill="#f1bc19" d="M83 11A4 4 0 1 0 83 19A4 4 0 1 0 83 11Z"></path><path fill="#8889b9" d="M87 22A2 2 0 1 0 87 26A2 2 0 1 0 87 22Z"></path><path fill="#fbcd59" d="M81 74A2 2 0 1 0 81 78 2 2 0 1 0 81 74zM15 59A4 4 0 1 0 15 67 4 4 0 1 0 15 59z"></path><path fill="#8889b9" d="M25 85A2 2 0 1 0 25 89A2 2 0 1 0 25 85Z"></path><path fill="#fff" d="M18.5 49A2.5 2.5 0 1 0 18.5 54 2.5 2.5 0 1 0 18.5 49zM79.5 32A1.5 1.5 0 1 0 79.5 35 1.5 1.5 0 1 0 79.5 32z"></path><g><path fill="#fdfcee" d="M50 25.599999999999998A24.3 24.3 0 1 0 50 74.2A24.3 24.3 0 1 0 50 25.599999999999998Z"></path><path fill="#472b29" d="M50,74.8c-13.8,0-25-11.2-25-25c0-13.8,11.2-25,25-25c13.8,0,25,11.2,25,25C75,63.6,63.8,74.8,50,74.8z M50,26.3c-13,0-23.5,10.6-23.5,23.5S37,73.4,50,73.4s23.5-10.6,23.5-23.5S63,26.3,50,26.3z"></path></g><g><path fill="#ea5167" d="M49.9 29.6A20.4 20.4 0 1 0 49.9 70.4A20.4 20.4 0 1 0 49.9 29.6Z"></path></g><g><path fill="#ef7d99" d="M50.2,32.9c10.6,0,19.3,8.2,20.1,18.5c0-0.5,0.1-1,0.1-1.5c0-11-9-20-20.2-20c-11.1,0-20.2,9-20.2,20 c0,0.5,0,1,0.1,1.5C30.9,41,39.5,32.9,50.2,32.9z"></path></g><g><path fill="#472b29" d="M69.4,44.6c-0.2,0-0.4-0.1-0.5-0.4c-0.1-0.3-0.2-0.6-0.3-0.9c-0.4-1.1-0.9-2.2-1.5-3.2 c-0.1-0.2-0.1-0.5,0.2-0.7c0.2-0.1,0.5-0.1,0.7,0.2c0.6,1.1,1.1,2.2,1.5,3.3c0.1,0.3,0.2,0.6,0.3,0.9c0.1,0.3-0.1,0.5-0.3,0.6 C69.5,44.6,69.5,44.6,69.4,44.6z"></path></g><g><path fill="#472b29" d="M50,70.8c-11.5,0-20.9-9.3-20.9-20.8c0-11.5,9.4-20.8,20.9-20.8c6,0,11.7,2.6,15.6,7c0.3,0.3,0.6,0.7,0.9,1 c0.2,0.2,0.1,0.5-0.1,0.7c-0.2,0.2-0.5,0.1-0.7-0.1c-0.3-0.3-0.5-0.7-0.8-1c-3.8-4.2-9.2-6.7-14.9-6.7c-11,0-19.9,8.9-19.9,19.8 c0,10.9,8.9,19.8,19.9,19.8s19.9-8.9,19.9-19.8c0-1-0.1-2-0.2-3c0-0.3,0.1-0.5,0.4-0.6c0.3,0,0.5,0.1,0.6,0.4 c0.2,1,0.2,2.1,0.2,3.1C70.9,61.4,61.5,70.8,50,70.8z"></path></g><g><path fill="#fdfcee" d="M56,57.1c-0.3,0-0.6-0.1-0.9-0.4l-5.2-5.2l-5.2,5.2c-0.2,0.2-0.5,0.4-0.9,0.4s-0.6-0.1-0.9-0.4 c-0.5-0.5-0.5-1.2,0-1.7l5.2-5.2L43,44.6c-0.5-0.5-0.5-1.2,0-1.7c0.2-0.2,0.5-0.4,0.9-0.4s0.6,0.1,0.9,0.4l5.2,5.2l5.2-5.2 c0.2-0.2,0.5-0.4,0.9-0.4c0.3,0,0.6,0.1,0.9,0.4s0.4,0.5,0.4,0.9s-0.1,0.6-0.4,0.9l-5.2,5.2l5.2,5.2c0.2,0.2,0.4,0.5,0.4,0.9 c0,0.3-0.1,0.6-0.4,0.9S56.3,57.1,56,57.1z"></path><path fill="#472b29" d="M56,43.1c0.2,0,0.4,0.1,0.5,0.2c0.3,0.3,0.3,0.7,0,1l-5.5,5.5l5.5,5.5c0.3,0.3,0.3,0.7,0,1 c-0.1,0.1-0.3,0.2-0.5,0.2s-0.4-0.1-0.5-0.2l-5.5-5.5l-5.5,5.5c-0.1,0.1-0.3,0.2-0.5,0.2s-0.4-0.1-0.5-0.2c-0.3-0.3-0.3-0.7,0-1 l5.5-5.5l-5.5-5.5c-0.3-0.3-0.3-0.7,0-1c0.1-0.1,0.3-0.2,0.5-0.2s0.4,0.1,0.5,0.2l5.5,5.5l5.5-5.5C55.6,43.1,55.8,43.1,56,43.1 M56,42.1c-0.5,0-0.9,0.2-1.2,0.5l-4.8,4.8l-4.8-4.8c-0.3-0.3-0.8-0.5-1.2-0.5s-0.9,0.2-1.2,0.5c-0.3,0.3-0.5,0.8-0.5,1.2 s0.2,0.9,0.5,1.2l4.8,4.8l-4.8,4.8c-0.3,0.3-0.5,0.8-0.5,1.2s0.2,0.9,0.5,1.2c0.3,0.3,0.8,0.5,1.2,0.5s0.9-0.2,1.2-0.5l4.8-4.8 l4.8,4.8c0.3,0.3,0.8,0.5,1.2,0.5s0.9-0.2,1.2-0.5c0.3-0.3,0.5-0.8,0.5-1.2s-0.2-0.9-0.5-1.2l-4.8-4.8l4.8-4.8 c0.3-0.3,0.5-0.8,0.5-1.2s-0.2-0.9-0.5-1.2C56.9,42.2,56.4,42.1,56,42.1L56,42.1z"></path></g>
|
120
|
+
</svg>
|
121
|
+
#{' '}
|
122
|
+
SVG
|
123
|
+
|
124
|
+
# HTML page
|
125
|
+
<<-HTML
|
120
126
|
<!DOCTYPE html>
|
121
127
|
<html lang="en">
|
122
128
|
<head>
|
@@ -135,28 +141,28 @@ module Lenna
|
|
135
141
|
<div class="item-right">#{svg_logo}</div>
|
136
142
|
</div>
|
137
143
|
#{' '}
|
138
|
-
#{error_message_and_backtrace(error
|
144
|
+
#{error_message_and_backtrace(error)}
|
139
145
|
</div>
|
140
146
|
</body>
|
141
147
|
</html>
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
148
|
+
HTML
|
149
|
+
end
|
150
|
+
|
151
|
+
# This method will render the error message and backtrace.
|
152
|
+
#
|
153
|
+
# @parameter error [StandardError] The error object
|
154
|
+
# @parameter env [Hash] The environment variables
|
155
|
+
#
|
156
|
+
# @return [String] The HTML string
|
157
|
+
#
|
158
|
+
def error_message_and_backtrace(error)
|
159
|
+
if ENV['RACK_ENV'] == 'development'
|
160
|
+
truncated_message =
|
161
|
+
error.message[0..500] + (error.message.length > 500 ? '...' : '')
|
162
|
+
|
163
|
+
file, line = error.backtrace.first.split(':')
|
164
|
+
line_number = Integer(line)
|
165
|
+
<<-DETAILS
|
160
166
|
<div class="error-details">
|
161
167
|
<h2>Error Details:</h2>
|
162
168
|
<p>
|
@@ -176,63 +182,62 @@ module Lenna
|
|
176
182
|
</p>
|
177
183
|
</details>
|
178
184
|
</div>
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
end
|
185
|
+
DETAILS
|
186
|
+
else
|
187
|
+
"<p>We're sorry, but something went wrong. We've been notified " \
|
188
|
+
'about this issue and will take a look at it shortly.</p>'
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# This method will extract the source code.
|
193
|
+
#
|
194
|
+
# @parameter file [String] The file path
|
195
|
+
# @parameter line_number [Integer] The line number
|
196
|
+
#
|
197
|
+
# @return [String] The HTML string
|
198
|
+
#
|
199
|
+
# ex.
|
200
|
+
# extract_source('/path/to/file.rb', 10)
|
201
|
+
# # => "<strong style='color: red;'> 7: </strong> =>
|
202
|
+
# def foo\n<strong style='color: red;'> 8: </strong>
|
203
|
+
# puts 'bar'\n<strong style='color: red;'> 9: </strong>
|
204
|
+
# end\n<strong style='color: red;'> 10: </strong> foo\n<strong
|
205
|
+
# style='color: red;'> 11: </strong> "
|
206
|
+
#
|
207
|
+
def extract_source(file, line_number)
|
208
|
+
lines = ::File.readlines(file)
|
209
|
+
start_line = [line_number - 3, 0].max
|
210
|
+
end_line = [line_number + 3, lines.size].min
|
211
|
+
|
212
|
+
line_ranger = lines[start_line...end_line]
|
213
|
+
|
214
|
+
format_lines(line_ranger, line_number).join
|
215
|
+
end
|
216
|
+
|
217
|
+
# This method will format the lines.
|
218
|
+
#
|
219
|
+
# ex.
|
220
|
+
# format_lines(line_ranger, line_number)
|
221
|
+
# # => ["<strong style='color: red;'> 7: </strong> =>\n",
|
222
|
+
# "<strong style='color: red;'> 8: </strong> puts 'bar'\n",
|
223
|
+
# "<strong style='color: red;'> 9: </strong> end\n",
|
224
|
+
# "<strong style='color: red;'> 10: </strong> foo\n",
|
225
|
+
# "<strong style='color: red;'> 11: </strong> "]
|
226
|
+
#
|
227
|
+
def format_lines(lines, highlight_line)
|
228
|
+
lines.map.with_index(highlight_line - 3 + 1) do |line, line_num|
|
229
|
+
line_number_text = "#{line_num.to_s.rjust(6)}: "
|
230
|
+
formatted_line = ::CGI.escapeHTML(line)
|
231
|
+
|
232
|
+
if line_num == highlight_line
|
233
|
+
"<strong style='color: red;'>#{line_number_text}</strong> " \
|
234
|
+
"#{formatted_line}"
|
235
|
+
else
|
236
|
+
"#{line_number_text}#{formatted_line}"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
238
243
|
end
|
@@ -1,95 +1,93 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2023, by Aristóteles Coutinho.
|
5
|
+
|
3
6
|
require 'colorize'
|
4
7
|
|
5
8
|
module Lenna
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# # => [2021-01-01 00:00:00 +0000] "GET /" 200 0.00ms
|
15
|
-
module Logging
|
16
|
-
extend self
|
9
|
+
module Middleware
|
10
|
+
module Default
|
11
|
+
# The Logging module is responsible for logging the requests.
|
12
|
+
#
|
13
|
+
# @private
|
14
|
+
#
|
15
|
+
module Logging
|
16
|
+
extend self
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
18
|
+
# This method is used to log the request.
|
19
|
+
#
|
20
|
+
# @parameter req [Rack::Request ] The request
|
21
|
+
# @parameter res [Rack::Response] The response
|
22
|
+
# @parameter next_middleware [Proc] The next middleware
|
23
|
+
#
|
24
|
+
def call(req, res, next_middleware)
|
25
|
+
start_time = ::Time.now
|
26
|
+
next_middleware.call
|
27
|
+
end_time = ::Time.now
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
http_method = colorize_http_method(req.request_method)
|
30
|
+
status_code = colorize_status_code(res.status.to_s)
|
31
|
+
duration = calculate_duration(start_time, end_time)
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
log_message = "[#{start_time}] \"#{http_method} #{req.path_info}\" " \
|
34
|
+
"#{status_code} #{format('%.2f', duration)}ms"
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
::Kernel.puts(log_message)
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
+
private
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
41
|
+
# This method is used to colorize the request method.
|
42
|
+
#
|
43
|
+
# @parameter request_method [String] The request method
|
44
|
+
#
|
45
|
+
# @return [String] The colorized request method
|
46
|
+
#
|
47
|
+
# @private
|
48
|
+
#
|
49
|
+
def colorize_http_method(request_method)
|
50
|
+
case request_method
|
51
|
+
in 'GET' then 'GET'.green
|
52
|
+
in 'POST' then 'POST'.magenta
|
53
|
+
in 'PUT' then 'PUT'.yellow
|
54
|
+
in 'DELETE' then 'DELETE'.red
|
55
|
+
else request_method.blue
|
56
|
+
end
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
59
|
+
# This method is used to colorize the status code.
|
60
|
+
#
|
61
|
+
# @param status_code [String] The status code
|
62
|
+
#
|
63
|
+
# @return [String] The colorized status code
|
64
|
+
#
|
65
|
+
# @private
|
66
|
+
#
|
67
|
+
def colorize_status_code(status_code)
|
68
|
+
case status_code
|
69
|
+
in '2' then status_code.green
|
70
|
+
in '3' then status_code.blue
|
71
|
+
in '4' then status_code.yellow
|
72
|
+
in '5' then status_code.red
|
73
|
+
else status_code
|
74
|
+
end
|
75
|
+
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
77
|
+
# This method is used to calculate the duration.
|
78
|
+
#
|
79
|
+
# @param start_time [Time] The start time
|
80
|
+
#
|
81
|
+
# @param end_time [Time] The end time
|
82
|
+
# @return [Float] The duration
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
def calculate_duration(start_time, end_time)
|
87
|
+
millis_in_second = 1000.0
|
88
|
+
(end_time - start_time) * millis_in_second
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
95
93
|
end
|