lennarb 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,379 +1,509 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Aristóteles Coutinho.
5
+
3
6
  module Lenna
4
- class Router
5
- # The Response class is responsible for managing the response.
6
- #
7
- # @attr headers [Hash] the response headers
8
- # @attr body [Array(String)] the response body
9
- # @attr status [Integer] the response status
10
- # @attr params [Hash] the response params
11
- class Response
12
- private attr_writer :body, :headers, :status, :params
13
- public attr_reader :body, :headers, :status, :params
14
-
15
- def initialize(headers = {}, status = 200, body = [])
16
- @params = {}
17
- @body = body
18
- @status = status
19
- @headers = headers
20
- end
21
-
22
- # This method will set the response status.
23
- #
24
- # @param value [Integer] the response status
25
- #
26
- # @return [void]
27
- #
28
- # @api public
29
- def assign_status(value) = put_status(value)
30
-
31
- # Thi method set the body value.
32
- #
33
- # @param value [Array(String)] the body value
34
- #
35
- # @return [void]
36
- #
37
- # @api public
38
- def assign_body(value) = put_body(value)
39
-
40
- # This method will set the header value.
41
- #
42
- # @param header [String] the header name
43
- # @param value [String] the header value
44
- # @return [void]
45
- # @note This method will set the header value.
46
- # If the header already exists, then the value will
47
- # be appended to the header.
48
- #
49
- # @api public
50
- #
51
- # @example
52
- # assign_header('X-Request-Id', '123')
53
- # # => '123'
54
- #
55
- # assign_header('X-Request-Id', '456')
56
- # # => ['123', '456']
57
- #
58
- # assign_header('X-Request-Id', ['456', '789'])
59
- # # => ['123', '456', '789']
60
- def assign_header(key, value) = put_header(key, value)
61
-
62
- # Add multiple headers.
63
- #
64
- # @param headers [Hash] the headers
65
- # @return [void]
66
- # @note This method will add the headers.
67
- # The headers are a hash where the key is the
68
- # header name and the value is the header value.
69
- #
70
- # @example
71
- # headers = {
72
- # 'Content-Type' => 'application/json',
73
- # 'X-Request-Id' => '123'
74
- # }
75
- #
76
- def assign_headers(headers)
77
- headers => ::Hash
78
-
79
- headers.each { |key, value| put_header(key, value) }
80
- end
81
-
82
- # This method will get the content type.
83
- #
84
- # @return [String] the content type
85
- #
86
- # @api public
87
- def content_type = @headers['Content-Type']
88
-
89
- # This method will delete the header.
90
- # @param header [String] the header name
91
- #
92
- # @return [void]
93
- #
94
- # @api public
95
- def remove_header(key) = delete_header(key)
96
-
97
- # This method will get the redirect location.
98
- #
99
- # @param value [String] the key of the cookie
100
- #
101
- # @return [String] the cookie
102
- #
103
- # @api public
104
- def cookie(value)
105
- value => ::String
106
-
107
- @headers['Set-Cookie']
108
- .then { |cookie| cookie.split('; ') }
109
- .then { |cookie| cookie.find { |c| c.start_with?("#{value}=") } }
110
- .then { |cookie| cookie.split('=').last }
111
- end
112
-
113
- # This method will set the cookie.
114
- #
115
- # @param key [String] the key of the cookie
116
- # @param value [String] the value of the cookie
117
- #
118
- # @return [void]
119
- #
120
- # @api public
121
- def assign_cookie(key, value)
122
- key => ::String
123
- value => ::String
124
-
125
- cookie = "#{key}=#{value}"
126
-
127
- put_header('Set-Cookie', cookie)
128
- end
129
-
130
- # This method will get all the cookies.
131
- #
132
- # @return [Hash] the cookies
133
- # @api public
134
- def cookies
135
- @headers['Set-Cookie']
136
- .then { |cookie| cookie.split('; ') }
137
- .each_with_object({}) do |cookie, acc|
138
- key, value = cookie.split('=')
139
-
140
- acc[key] = value
141
- end
142
- end
143
-
144
- # This method will set redirect location. The status will be set to 302.
145
- #
146
- # @param location [String] the redirect location
147
- # @param status [Integer] the redirect status, default is 302.
148
- #
149
- # @return [void]
150
- #
151
- # @api public
152
- def redirect(location, status: 302)
153
- location => ::String
154
-
155
- put_header('Location', location)
156
- put_status(status)
157
-
158
- finish!
159
- rescue ::NoMatchingPatternError
160
- raise ::ArgumentError, 'location must be a string'
161
- end
162
-
163
- # This method will finish the response.
164
- #
165
- # @return [void]
166
- #
167
- # @api public
168
- def finish = finish!
169
-
170
- # This method will set the response content type.
171
- #
172
- # @param type [String] the response content type
173
- # @param charset [Hash] the response charset
174
- #
175
- # @return [void]
176
- #
177
- # @api public
178
- def assign_content_type(type, charset: nil)
179
- type => ::String
180
-
181
- case charset
182
- in ::String then put_header(
183
- 'Content-Type',
184
- "#{type}; charset=#{charset}"
185
- )
186
- else put_header('Content-Type', type)
187
- end
188
- rescue ::NoMatchingPatternError
189
- raise ::ArgumentError, 'type must be a string'
190
- end
191
-
192
- # This method will set the response data and finish the response.
193
- #
194
- # @param data [Hash, Array] the response data
195
- #
196
- # @return [void]
197
- #
198
- # @api public
199
- def json(data:, status: 200)
200
- data => ::Array | ::Hash
201
-
202
- put_status(status)
203
- put_header('Content-Type', 'application/json')
204
- put_body(data.to_json)
205
-
206
- finish!
207
- end
208
-
209
- # Set the response content type to text/html.
210
- #
211
- # @param str [String] the response body
212
- #
213
- # @return [void]
214
- #
215
- # @api public
216
- def html(str = nil, status: 200)
217
- put_status(status)
218
- put_header('Content-Type', 'text/html')
219
- put_body(str)
220
-
221
- finish!
222
- end
223
-
224
- # This method will render the template.
225
- #
226
- # @param template_nam [String] the template name
227
- # @param path [String] the template path, default is 'views'
228
- # @param locals [Hash] the template locals
229
- #
230
- # @return [void | Exception]
231
- #
232
- # @example
233
- # render('index')
234
- # # => Render the template `views/index.html.erb`
235
- #
236
- # render('users/index')
237
- # # => Render the template `views/users/index.html.erb`
238
- #
239
- # render('index', path: 'app/views/users')
240
- # # => Render the template `app/views/users/index.html.erb`
241
- #
242
- # render('index', locals: { name: 'John' })
243
- # # => Render the template `views/index.html.erb` with the local
244
- # # variable `name` set to 'John'
245
- def render(template_name, path: 'views', locals: {}, status: 200)
246
- template_path = ::File.join(path, "#{template_name}.html.erb")
247
-
248
- # Check if the template exists
249
- unless File.exist?(template_path)
250
- msg = "Template not found: #{template_path} 🤷‍♂️."
251
-
252
- # Oops! The template doesn't exist or the path is wrong.
253
- #
254
- # The template exists? 🤔
255
- # If you want to render a template from a custom path, then you
256
- # can pass the full path though the path: keyword argument instead
257
- # of just the name. For example:
258
- # render('index', path: 'app/views/users')
259
- raise msg
260
- end
261
-
262
- ::File
263
- .read(template_path)
264
- .then { |template| ::ERB.new(template).result_with_hash(locals) }
265
- .then { |erb_template| html(erb_template, status:) }
266
- end
267
-
268
- # Helper methods for the response.
269
- #
270
- # @return [void]
271
- #
272
- # @api public
273
- #
274
- # @see #render
275
- # @see #finish!
276
- def not_found
277
- put_body(['Not Found'])
278
- put_status(404)
279
-
280
- finish!
281
- end
282
-
283
- private
284
-
285
- # This method will get the response status.
286
- #
287
- # @return [Integer] the response status
288
- #
289
- # @api private
290
- def put_status(value)
291
- value => ::Integer
292
-
293
- self.status = value
294
- rescue ::NoMatchingPatternError
295
- raise ::ArgumentError, 'status must be an integer'
296
- end
297
-
298
- # This method will set the body.
299
- #
300
- # @param body [Array(String)] the body to be used
301
- # @return [void]
302
- def put_body(value)
303
- value => ::String | ::Array
304
-
305
- case value
306
- in ::String then @body = [value]
307
- in ::Array then @body = value
308
- end
309
- rescue ::NoMatchingPatternError
310
- raise ::ArgumentError, 'body must be a string or an array'
311
- end
312
-
313
- # @param key [String] the header name
314
- # @param value [String] the value to be used
315
- #
316
- # @return [void]
317
- def put_header(key, value)
318
- raise ::ArgumentError, 'key must be a string' unless key.is_a?(::String)
319
-
320
- unless value.is_a?(::String) || value.is_a?(::Array)
321
- raise ::ArgumentError, 'value must be a string or an array'
322
- end
323
-
324
- header_value = @headers[key]
325
-
326
- new_values = ::Array.wrap(value)
327
- existing_values = ::Array.wrap(header_value)
328
-
329
- @headers[key] = (existing_values + new_values).uniq.join(', ')
330
- end
331
-
332
- # @param key [String] the header name
333
- #
334
- # @return [void]
335
- def delete_header(key) = @headers.delete(key)
336
-
337
- # @param value [String] the redirect location
338
- #
339
- # @return [void]
340
- def location!(value)
341
- value => ::String
342
-
343
- put_header('Location', value)
344
- end
345
-
346
- # This method will finish the response.
347
- #
348
- # @return [void]
349
- def finish!
350
- default_router_header!
351
- default_content_length! unless @headers['Content-Length']
352
- default_html_content_type! unless @headers['Content-Type']
353
-
354
- [@status, @headers, @body]
355
- end
356
-
357
- # This method will set the response default html content type.
358
- #
359
- # @return [void]
360
- def default_html_content_type!
361
- put_header('Content-Type', 'text/html')
362
- end
363
-
364
- # This method will set the response default content length.
365
- #
366
- # @return [void]
367
- def default_content_length!
368
- put_header('Content-Length', @body.join.size.to_s)
369
- end
370
-
371
- # This method will set the response default router header.
372
- #
373
- # @return [void]
374
- def default_router_header!
375
- put_header('Server', "Lennarb VERSION #{::Lennarb::VERSION}")
376
- end
377
- end
378
- end
7
+ class Router
8
+ # The Response class is responsible for managing the response.
9
+ #
10
+ # @attr headers [Hash] the response headers
11
+ # @attr body [Array(String)] the response body
12
+ # @attr status [Integer] the response status
13
+ # @attr params [Hash] the response params
14
+ #
15
+ # @public `Since v0.1.0`
16
+ #
17
+ class Response
18
+ # The status of the response.
19
+ #
20
+ # @return [Integer] the status of the Response
21
+ #
22
+ # @public
23
+ #
24
+ public attr_accessor :status
25
+
26
+ # The body of the response.
27
+ #
28
+ # @return [Array(String)] the body of the Response
29
+ #
30
+ # @public
31
+ #
32
+ public attr_reader :body
33
+
34
+ # The headers of the response.
35
+ #
36
+ # @return [Hash] the headers of the Response
37
+ #
38
+ # @public
39
+ #
40
+ public attr_reader :headers
41
+
42
+ # The params of the response.
43
+ #
44
+ # @return [Hash] the params of the Response
45
+ #
46
+ # @public
47
+ #
48
+ public attr_reader :params
49
+
50
+ # The length of the response.
51
+ #
52
+ # @return [Integer] the length of the Response
53
+ #
54
+ # @public
55
+ #
56
+ public attr_reader :length
57
+
58
+ # This method will initialize the response.
59
+ #
60
+ # @parameter headers [Hash] the response headers, default is {}
61
+ # @parameter status [Integer] the response status, default is 200
62
+ # @parameter body [Array(String)] the response body, default is []
63
+ # @parameter params [Hash] the response params, default is {}
64
+ # @length [Integer] the response length, default is 0
65
+ #
66
+ # @return [void]
67
+ #
68
+ def initialize(headers = {}, status = 200, body = [])
69
+ @params = {}
70
+ @body = body
71
+ @status = status
72
+ @headers = headers
73
+ @length = 0
74
+ end
75
+
76
+ # This method will set the params.
77
+ #
78
+ # @parameter params [Hash] the params to be used
79
+ #
80
+ # @return [void]
81
+ #
82
+ # @public
83
+ #
84
+ # ex.
85
+ # response.params = { 'name' => 'John' }
86
+ # # => { 'name' => 'John' }
87
+ #
88
+ def assign_params(params)
89
+ params => ::Hash
90
+
91
+ @params = params
92
+ rescue ::NoMatchingPatternError
93
+ raise ::ArgumentError, 'params must be a hash'
94
+ end
95
+ alias params= assign_params
96
+
97
+ # Returns the response header corresponding to `key`.
98
+ #
99
+ # @parameter key [String] the header name
100
+ #
101
+ # @return [String] the header value
102
+ #
103
+ # @public
104
+ #
105
+ # ex.
106
+ # res["Content-Type"] # => "text/html"
107
+ # res["Content-Length"] # => "42"
108
+ #
109
+ def [](key) = @headers[key]
110
+
111
+ # Thi method set the body value.
112
+ #
113
+ # @parameter value [Array(String)] the body value
114
+ #
115
+ # @return [void]
116
+ #
117
+ # @public
118
+ #
119
+ def assign_body(value) = put_body(value)
120
+ alias body= assign_body
121
+
122
+ # This method will set the header value.
123
+ #
124
+ # @parameter header [String] the header name
125
+ # @parameter value [String] the header value
126
+ #
127
+ # @return [void]
128
+ #
129
+ # @public
130
+ #
131
+ # ex.
132
+ # assign_header('X-Request-Id', '123')
133
+ # # => '123'
134
+ #
135
+ # assign_header('X-Request-Id', '456')
136
+ # # => ['123', '456']
137
+ #
138
+ # assign_header('X-Request-Id', ['456', '789'])
139
+ # # => ['123', '456', '789']
140
+ #
141
+ def assign_header(key, value) = put_header(key, value)
142
+ alias []= assign_header
143
+
144
+ # Add multiple headers.
145
+ #
146
+ # @parameter headers [Hash] the headers
147
+ # @return [void]
148
+ #
149
+ # ex.
150
+ # headers = {
151
+ # 'Content-Type' => 'application/json',
152
+ # 'X-Request-Id' => '123'
153
+ # }
154
+ #
155
+ def assign_headers(headers)
156
+ headers => ::Hash
157
+
158
+ headers.each { |key, value| put_header(key, value) }
159
+ end
160
+ alias headers= assign_headers
161
+
162
+ # This method will get the content type.
163
+ #
164
+ # @return [String] the content type
165
+ #
166
+ # @public
167
+ #
168
+ def content_type = @headers['Content-Type']
169
+
170
+ # This method will delete the header.
171
+ #
172
+ # @parameter header [String] the header name
173
+ #
174
+ # @return [void]
175
+ #
176
+ # @public
177
+ #
178
+ def remove_header(key) = delete_header(key)
179
+
180
+ # This method will set the cookie.
181
+ #
182
+ # @parameter key [String] the key of the cookie
183
+ # @return [void]
184
+ # @parameter value [String] the value of the cookie
185
+ #
186
+ #
187
+ # @public
188
+ #
189
+ # ex.
190
+ # response.assign_cookie('foo', 'bar')
191
+ # # => 'foo=bar'
192
+ #
193
+ # response.header['Set-Cookie']
194
+ # # => 'foo=bar'
195
+ #
196
+ # response.assign_cookie('foo2', 'bar2')
197
+ # # => 'foo=bar; foo2=bar2'
198
+ # response.header['Set-Cookie']
199
+ # # => 'foo=bar; foo2=bar2'
200
+ #
201
+ # response.assign_cookie('bar', {
202
+ # domain: 'example.com',
203
+ # path: '/',
204
+ # # expires: Time.now + 24 * 60 * 60,
205
+ # secure: true,
206
+ # httponly: true
207
+ # })
208
+ #
209
+ # response.header['Set-Cookie'].split('\n').last
210
+ # # => 'bar=; domain=example.com; path=/; secure; HttpOnly'
211
+ #
212
+ # note:
213
+ # This method doesn't sign and/or encrypt the cookie.
214
+ # If you want to sign and/or encrypt the cookie, then you can use
215
+ # the `Rack::Session::Cookie` middleware.
216
+ #
217
+ def assign_cookie(key, value)
218
+ key => ::String
219
+ value => ::String
220
+
221
+ ::Rack::Utils.set_cookie_header!(@headers, key, value)
222
+ rescue ::NoMatchingPatternError
223
+ raise ::ArgumentError, 'key must be a string'
224
+ end
225
+
226
+ # This method will get all the cookies.
227
+ #
228
+ # @return [Hash] the cookies
229
+ #
230
+ # @public
231
+ #
232
+ def cookies = @headers['set-cookie']
233
+
234
+ # This method will delete the cookie.
235
+ #
236
+ # @parameter key [String] the key of the cookie
237
+ #
238
+ # @return [void]
239
+ #
240
+ # @public
241
+ #
242
+ # ex.
243
+ # response.delete_cookie('foo')
244
+ # # => 'foo=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000'
245
+ #
246
+ def delete_cookie(key)
247
+ key => ::String
248
+
249
+ ::Rack::Utils.delete_cookie_header!(@headers, key)
250
+ rescue ::NoMatchingPatternError
251
+ raise ::ArgumentError, 'key must be a string'
252
+ end
253
+
254
+ # This method will set redirect location. The status will be set to 302.
255
+ #
256
+ # @parameter location [String] the redirect location
257
+ # @parameter status [Integer] the redirect status, default is 302.
258
+ #
259
+ # @return [void]
260
+ #
261
+ # @public
262
+ #
263
+ def redirect(location, status: 302)
264
+ location => ::String
265
+
266
+ put_header('Location', location)
267
+ put_status(status)
268
+
269
+ finish!
270
+ rescue ::NoMatchingPatternError
271
+ raise ::ArgumentError, 'location must be a string'
272
+ end
273
+
274
+ # This method will finish the response.
275
+ #
276
+ # @return [void]
277
+ #
278
+ # @public
279
+ #
280
+ def finish = finish!
281
+
282
+ # This method will set the response content type.
283
+ #
284
+ # @parameter type [String] the response content type
285
+ # @parameter charset [Hash] the response charset
286
+ #
287
+ # @return [void]
288
+ #
289
+ # @public
290
+ #
291
+ def assign_content_type(type, charset: nil)
292
+ type => ::String
293
+
294
+ case charset
295
+ in ::String then put_header('Content-Type', "#{type}; charset=#{charset}")
296
+ else put_header('Content-Type', type)
297
+ end
298
+ rescue ::NoMatchingPatternError
299
+ raise ::ArgumentError, 'type must be a string'
300
+ end
301
+
302
+ # This method will set the response data and finish the response.
303
+ #
304
+ # @parameter data [Hash | Array] the response data
305
+ #
306
+ # @return [void]
307
+ #
308
+ # @public
309
+ #
310
+ # ex.
311
+ # response.json({ foo: 'bar' })
312
+ # # => { foo: 'bar' }
313
+ #
314
+ # response.json([{ foo: 'bar' }])
315
+ # # => [{ foo: 'bar' }]
316
+ #
317
+ def json(data = {}, status: 200)
318
+ data => ::Array | ::Hash
319
+
320
+ put_status(status)
321
+ put_header('Content-Type', 'application/json')
322
+ put_body(data.to_json)
323
+
324
+ finish!
325
+ end
326
+
327
+ # Set the response content type to text/html.
328
+ #
329
+ # @parameter str [String] the response body
330
+ #
331
+ # @return [void]
332
+ #
333
+ # @public
334
+ #
335
+ def html(str = nil, status: 200)
336
+ put_status(status)
337
+ put_header('Content-Type', 'text/html')
338
+ put_body(str)
339
+
340
+ finish!
341
+ end
342
+
343
+ # This method will render the template.
344
+ #
345
+ # @parameter template_nam [String] the template name
346
+ # @parameter path [String] the template path, default is 'views'
347
+ # @parameter locals [Hash] the template locals
348
+ #
349
+ # @return [void | Exception]
350
+ #
351
+ # @public
352
+ #
353
+ # ex.
354
+ # render('index')
355
+ # # => Render the template `views/index.html.erb`
356
+ #
357
+ # render('users/index')
358
+ # # => Render the template `views/users/index.html.erb`
359
+ #
360
+ # render('index', path: 'app/views/users')
361
+ # # => Render the template `app/views/users/index.html.erb`
362
+ #
363
+ # render('index', locals: { name: 'John' })
364
+ # # => Render the template `views/index.html.erb` with the local
365
+ # # variable `name` set to 'John'
366
+ #
367
+ def render(template_name, path: 'views', locals: {}, status: 200)
368
+ template_path = ::File.join(path, "#{template_name}.html.erb")
369
+
370
+ # Check if the template exists
371
+ unless File.exist?(template_path)
372
+ msg = "Template not found: #{template_path} 🤷‍♂️."
373
+
374
+ # Oops! The template doesn't exist or the path is wrong.
375
+ #
376
+ # The template exists? 🤔
377
+ # If you want to render a template from a custom path, then you
378
+ # can pass the full path though the path: keyword argument instead
379
+ # of just the name. For example:
380
+ # render('index', path: 'app/views/users')
381
+ raise msg
382
+ end
383
+
384
+ ::File
385
+ .read(template_path)
386
+ .then { |template| ::ERB.new(template).result_with_hash(locals) }
387
+ .then { |erb_template| html(erb_template, status:) }
388
+ end
389
+
390
+ # Helper methods for the response.
391
+ #
392
+ # @return [void]
393
+ #
394
+ # @public
395
+ #
396
+ def not_found
397
+ put_body(['Not Found'])
398
+ put_status(404)
399
+
400
+ finish!
401
+ end
402
+
403
+ private
404
+
405
+ # This method will get the response status.
406
+ #
407
+ # @return [Integer] the response status
408
+ #
409
+ def put_status(value)
410
+ value => ::Integer
411
+
412
+ self.status = value
413
+ rescue ::NoMatchingPatternError
414
+ raise ::ArgumentError, 'status must be an integer'
415
+ end
416
+
417
+ # This method will set the body.
418
+ #
419
+ # @parameter body [Array(String)] the body to be used
420
+ #
421
+ # @return [void]
422
+ #
423
+ def put_body(value)
424
+ value => ::String | ::Array
425
+
426
+ case value
427
+ in ::String then @body = [value]
428
+ in ::Array then @body = value
429
+ end
430
+ rescue ::NoMatchingPatternError
431
+ raise ::ArgumentError, 'body must be a string or an array'
432
+ end
433
+
434
+ # @parameter key [String] the header name
435
+ # @parameter value [String] the value to be used
436
+ #
437
+ # @return [void]
438
+ #
439
+ def put_header(key, value)
440
+ raise ::ArgumentError, 'key must be a string' unless key.is_a?(::String)
441
+
442
+ unless value.is_a?(::String) || value.is_a?(::Array)
443
+ raise ::ArgumentError, 'value must be a string or an array'
444
+ end
445
+
446
+ header_value = @headers[key]
447
+
448
+ new_values = ::Array.wrap(value)
449
+ existing_values = ::Array.wrap(header_value)
450
+
451
+ @headers[key] = (existing_values + new_values).uniq.join(', ')
452
+ end
453
+
454
+ # This method will delete a header by key.
455
+ #
456
+ # @parameter key [String] the header name
457
+ #
458
+ # @return [void]
459
+ #
460
+ def delete_header(key) = @headers.delete(key)
461
+
462
+ # @parameter value [String] the redirect location
463
+ #
464
+ # @return [void]
465
+ #
466
+ def location!(value)
467
+ value => ::String
468
+
469
+ put_header('Location', value)
470
+ end
471
+
472
+ # This method will finish the response.
473
+ #
474
+ # @return [void]
475
+ #
476
+ def finish!
477
+ default_router_header!
478
+ default_content_length! unless @headers['Content-Length']
479
+ default_html_content_type! unless @headers['Content-Type']
480
+
481
+ [@status, @headers, @body]
482
+ end
483
+
484
+ # This method will set the response default html content type.
485
+ #
486
+ # @return [void]
487
+ #
488
+ def default_html_content_type!
489
+ put_header('Content-Type', 'text/html')
490
+ end
491
+
492
+ # This method will set the response default content length.
493
+ #
494
+ # @return [void]
495
+ #
496
+ def default_content_length!
497
+ put_header('Content-Length', @body.join.size.to_s)
498
+ end
499
+
500
+ # This method will set the response default router header.
501
+ #
502
+ # @return [void]
503
+ #
504
+ def default_router_header!
505
+ put_header('Server', "Lennarb VERSION #{::Lennarb::VERSION}")
506
+ end
507
+ end
508
+ end
379
509
  end