hanami-controller 1.0.0.beta1 → 1.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -1
- data/lib/hanami/action/cache/conditional_get.rb +1 -1
- data/lib/hanami/action/flash.rb +19 -2
- data/lib/hanami/action/rack.rb +83 -3
- data/lib/hanami/action/rack/file.rb +4 -3
- data/lib/hanami/controller/configuration.rb +7 -2
- data/lib/hanami/controller/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a55f1d51fe4e8c7f3d631f070eab1233fadc0c3e
|
4
|
+
data.tar.gz: c9eb6f944227efb95943885e866adf40be3614dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01cbf64f7661609247d8eeb2ed3b73168a0e21dbcd69f48f60bd79d828db788099bdd70f4192a47090e8babd007faa75ac50d6d480dc9235d5aa39a1fe141961
|
7
|
+
data.tar.gz: f24e1ee54fe5b990d4261c92889d602dd9e6fd9dfaef31dc975a6ff122a32ffc69c5c806b07cc24931919dac68d2a7ad152b841c9a1c61f61c6a3627fadc99cb
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,17 @@
|
|
1
1
|
# Hanami::Controller
|
2
2
|
Complete, fast and testable actions for Rack
|
3
3
|
|
4
|
-
## v1.0.
|
4
|
+
## v1.0.0.beta2 - 2017-03-02
|
5
|
+
### Added
|
6
|
+
- [Marcello Rocha] Add `Action#unsafe_send_file` to send files outside of the public directory of a project
|
7
|
+
|
8
|
+
### Fixed
|
9
|
+
- [Anton Davydov] Ensure HTTP Cache to not crash when `HTTP_IF_MODIFIED_SINCE` and `HTTP_IF_NONE_MATCH` have blank values
|
10
|
+
- [Luca Guidi] Keep flash values after a redirect
|
11
|
+
- [Craig M. Wellington & Luca Guidi] Ensure to return 404 when `Action#send_file` cannot find a file with a globbed route
|
12
|
+
- [Luca Guidi] Don't mutate Rack env when sending files
|
13
|
+
|
14
|
+
## v1.0.0.beta1 - 2017-02-14
|
5
15
|
### Added
|
6
16
|
- [Luca Guidi] Official support for Ruby: MRI 2.4
|
7
17
|
|
data/lib/hanami/action/flash.rb
CHANGED
@@ -31,6 +31,7 @@ module Hanami
|
|
31
31
|
@session = session
|
32
32
|
@request_id = request_id
|
33
33
|
@last_request_id = session[LAST_REQUEST_KEY]
|
34
|
+
@merged = {}
|
34
35
|
|
35
36
|
session[SESSION_KEY] ||= {}
|
36
37
|
session[SESSION_KEY][request_id] ||= {}
|
@@ -54,7 +55,7 @@ module Hanami
|
|
54
55
|
# @since 0.3.0
|
55
56
|
# @api private
|
56
57
|
def [](key)
|
57
|
-
|
58
|
+
@merged.fetch(key) do
|
58
59
|
_values.find {|data| !data[key].nil? }
|
59
60
|
end
|
60
61
|
end
|
@@ -73,8 +74,9 @@ module Hanami
|
|
73
74
|
# It may happen that `#flash` is nil, and those two methods will fail
|
74
75
|
unless flash.nil?
|
75
76
|
expire_stale!
|
76
|
-
set_last_request_id!
|
77
77
|
remove!
|
78
|
+
merge!
|
79
|
+
set_last_request_id!
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
@@ -89,6 +91,13 @@ module Hanami
|
|
89
91
|
_values.all?(&:empty?)
|
90
92
|
end
|
91
93
|
|
94
|
+
# @return [String]
|
95
|
+
#
|
96
|
+
# @since 1.0.0.beta2
|
97
|
+
def inspect
|
98
|
+
"#<#{self.class}:#{'0x%x' % (__id__ << 1)} #{@merged.inspect}>"
|
99
|
+
end
|
100
|
+
|
92
101
|
private
|
93
102
|
|
94
103
|
# The flash registry that holds the data for **all** the recent requests
|
@@ -135,6 +144,14 @@ module Hanami
|
|
135
144
|
@session.delete(SESSION_KEY) if empty?
|
136
145
|
end
|
137
146
|
|
147
|
+
# @since 1.0.0.beta2
|
148
|
+
# @api private
|
149
|
+
#
|
150
|
+
# @see Hanami::Action::Flash#[]
|
151
|
+
def merge!
|
152
|
+
@merged = last_request_flash.merge(data)
|
153
|
+
end
|
154
|
+
|
138
155
|
# Values from all the stored requests
|
139
156
|
#
|
140
157
|
# @return [Array]
|
data/lib/hanami/action/rack.rb
CHANGED
@@ -10,12 +10,36 @@ module Hanami
|
|
10
10
|
#
|
11
11
|
# @since 0.1.0
|
12
12
|
module Rack
|
13
|
+
# Rack SPEC response code
|
14
|
+
#
|
15
|
+
# @since 1.0.0.beta2
|
16
|
+
# @api private
|
17
|
+
RESPONSE_CODE = 0
|
18
|
+
|
19
|
+
# Rack SPEC response headers
|
20
|
+
#
|
21
|
+
# @since 1.0.0.beta2
|
22
|
+
# @api private
|
23
|
+
RESPONSE_HEADERS = 1
|
24
|
+
|
25
|
+
# Rack SPEC response body
|
26
|
+
#
|
27
|
+
# @since 1.0.0.beta2
|
28
|
+
# @api private
|
29
|
+
RESPONSE_BODY = 2
|
30
|
+
|
13
31
|
# The default HTTP response code
|
14
32
|
#
|
15
33
|
# @since 0.1.0
|
16
34
|
# @api private
|
17
35
|
DEFAULT_RESPONSE_CODE = 200
|
18
36
|
|
37
|
+
# Not Found
|
38
|
+
#
|
39
|
+
# @since 1.0.0.beta2
|
40
|
+
# @api private
|
41
|
+
NOT_FOUND = 404
|
42
|
+
|
19
43
|
# The default Rack response body
|
20
44
|
#
|
21
45
|
# @since 0.1.0
|
@@ -36,6 +60,19 @@ module Hanami
|
|
36
60
|
# @api private
|
37
61
|
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
38
62
|
|
63
|
+
# The Content-Length HTTP header
|
64
|
+
#
|
65
|
+
# @since 1.0.0.beta2
|
66
|
+
# @api private
|
67
|
+
CONTENT_LENGTH = 'Content-Length'.freeze
|
68
|
+
|
69
|
+
# The non-standard HTTP header to pass the control over when a resource
|
70
|
+
# cannot be found by the current endpoint
|
71
|
+
#
|
72
|
+
# @since 1.0.0.beta2
|
73
|
+
# @api private
|
74
|
+
X_CASCADE = 'X-Cascade'.freeze
|
75
|
+
|
39
76
|
# HEAD request
|
40
77
|
#
|
41
78
|
# @since 0.3.2
|
@@ -257,6 +294,7 @@ module Hanami
|
|
257
294
|
end
|
258
295
|
|
259
296
|
# Send a file as response.
|
297
|
+
# <tt>This method only sends files from the public directory</tt>
|
260
298
|
#
|
261
299
|
# It automatically handle the following cases:
|
262
300
|
#
|
@@ -282,9 +320,37 @@ module Hanami
|
|
282
320
|
# end
|
283
321
|
# end
|
284
322
|
def send_file(path)
|
285
|
-
|
286
|
-
|
287
|
-
|
323
|
+
_send_file(
|
324
|
+
File.new(path, self.class.configuration.public_directory).call(@_env)
|
325
|
+
)
|
326
|
+
end
|
327
|
+
|
328
|
+
# Send a file as response from anywhere in the file system.
|
329
|
+
#
|
330
|
+
# @see Hanami::Action::Rack#send_file
|
331
|
+
#
|
332
|
+
# @param path [String, Pathname] path to the file to be sent
|
333
|
+
# @return [void]
|
334
|
+
#
|
335
|
+
# @since 1.0.0.beta2
|
336
|
+
#
|
337
|
+
# @example
|
338
|
+
# require 'hanami/controller'
|
339
|
+
#
|
340
|
+
# class Show
|
341
|
+
# include Hanami::Action
|
342
|
+
#
|
343
|
+
# def call(params)
|
344
|
+
# # ...
|
345
|
+
# unsafe_send_file Pathname.new('/tmp/path/to/file')
|
346
|
+
# end
|
347
|
+
# end
|
348
|
+
def unsafe_send_file(path)
|
349
|
+
directory = self.class.configuration.root_directory if Pathname.new(path).relative?
|
350
|
+
|
351
|
+
_send_file(
|
352
|
+
File.new(path, directory).call(@_env)
|
353
|
+
)
|
288
354
|
end
|
289
355
|
|
290
356
|
# Check if the current request is a HEAD
|
@@ -303,6 +369,20 @@ module Hanami
|
|
303
369
|
def request_method
|
304
370
|
@_env[REQUEST_METHOD]
|
305
371
|
end
|
372
|
+
|
373
|
+
# @since 1.0.0.beta2
|
374
|
+
# @api private
|
375
|
+
def _send_file(response)
|
376
|
+
headers.merge!(response[RESPONSE_HEADERS])
|
377
|
+
|
378
|
+
if response[RESPONSE_CODE] == NOT_FOUND
|
379
|
+
headers.delete(X_CASCADE)
|
380
|
+
headers.delete(CONTENT_LENGTH)
|
381
|
+
halt NOT_FOUND
|
382
|
+
else
|
383
|
+
halt response[RESPONSE_CODE], response[RESPONSE_BODY]
|
384
|
+
end
|
385
|
+
end
|
306
386
|
end
|
307
387
|
end
|
308
388
|
end
|
@@ -10,7 +10,6 @@ module Hanami
|
|
10
10
|
#
|
11
11
|
# @see Hanami::Action::Rack#send_file
|
12
12
|
class File
|
13
|
-
|
14
13
|
# The key that returns path info from the Rack env
|
15
14
|
#
|
16
15
|
# @since 1.0.0.beta1
|
@@ -22,14 +21,16 @@ module Hanami
|
|
22
21
|
# @since 0.4.3
|
23
22
|
# @api private
|
24
23
|
def initialize(path, root)
|
25
|
-
@file = ::Rack::File.new(root)
|
26
|
-
@path = path
|
24
|
+
@file = ::Rack::File.new(root.to_s)
|
25
|
+
@path = path.to_s
|
27
26
|
end
|
28
27
|
|
29
28
|
# @since 0.4.3
|
30
29
|
# @api private
|
31
30
|
def call(env)
|
31
|
+
env = env.dup
|
32
32
|
env[PATH_INFO] = @path
|
33
|
+
|
33
34
|
@file.get(env)
|
34
35
|
rescue Errno::ENOENT
|
35
36
|
[404, {}, nil]
|
@@ -651,11 +651,15 @@ module Hanami
|
|
651
651
|
@formats.key(format)
|
652
652
|
end
|
653
653
|
|
654
|
+
# @api private
|
655
|
+
# @since 1.0.0.beta2
|
656
|
+
attr_reader :root_directory
|
657
|
+
|
654
658
|
def public_directory(value = nil)
|
655
659
|
if value.nil?
|
656
660
|
@public_directory
|
657
661
|
else
|
658
|
-
@public_directory =
|
662
|
+
@public_directory = root_directory.join(value).to_s
|
659
663
|
end
|
660
664
|
end
|
661
665
|
|
@@ -706,7 +710,8 @@ module Hanami
|
|
706
710
|
@default_charset = nil
|
707
711
|
@default_headers = {}
|
708
712
|
@cookies = {}
|
709
|
-
@
|
713
|
+
@root_directory = ::Pathname.new(Dir.pwd).realpath
|
714
|
+
@public_directory = root_directory.join(DEFAULT_PUBLIC_DIRECTORY).to_s
|
710
715
|
@action_module = ::Hanami::Action
|
711
716
|
end
|
712
717
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami-controller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-02
|
13
|
+
date: 2017-03-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|