hanami-controller 2.0.0.beta1 → 2.0.0.rc1
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 +25 -0
- data/README.md +4 -4
- data/hanami-controller.gemspec +2 -2
- data/lib/hanami/action/base_params.rb +39 -16
- data/lib/hanami/action/config.rb +268 -0
- data/lib/hanami/action/constants.rb +5 -17
- data/lib/hanami/action/csrf_protection.rb +2 -7
- data/lib/hanami/action/errors.rb +69 -0
- data/lib/hanami/action/flash.rb +29 -22
- data/lib/hanami/action/halt.rb +3 -1
- data/lib/hanami/action/mime.rb +81 -35
- data/lib/hanami/action/params.rb +5 -12
- data/lib/hanami/action/rack/file.rb +6 -2
- data/lib/hanami/action/request.rb +67 -5
- data/lib/hanami/action/response.rb +221 -30
- data/lib/hanami/action/session.rb +11 -2
- data/lib/hanami/action/validatable.rb +9 -5
- data/lib/hanami/action.rb +181 -188
- data/lib/hanami/controller/version.rb +2 -4
- data/lib/hanami/controller.rb +0 -16
- data/lib/hanami/http/status.rb +2 -0
- metadata +12 -12
- data/lib/hanami/action/configuration.rb +0 -436
- data/lib/hanami/controller/error.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a5d623c09e8ecb8c267de856196333c5da74e066b55501af2acc706349d0d73
|
4
|
+
data.tar.gz: '0786076a81b7a11ca79aedba2ff0318f207683e71ba931293dcc1f585a191e0b'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81f1cddefe11892d05ccb63e8649bc9fb6e50f2258eb02503044577e9c0e445c57cbf2318046a4002e3c9b107f9df530463cbeb10460bb3339bb52b747deb0eb
|
7
|
+
data.tar.gz: eb26f557543e0d345580b9160ec4123def85b4a4ec5a1ad0a17f8a8d15d05dc34f12e13705082e21b95a5cc3095d36677b099a319a1c2472c7180e413f5c5faf
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
Complete, fast and testable actions for Rack
|
4
4
|
|
5
|
+
## v2.0.0.rc1 - 2022-11-08
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
|
9
|
+
- [Tim Riley] Simplify assignment of response format: `response.format = :json` (was `response.format = format(:json)`)
|
10
|
+
|
11
|
+
## v2.0.0.beta4 - 2022-10-24
|
12
|
+
|
13
|
+
### Added
|
14
|
+
|
15
|
+
- [Tim Riley] Add `Response#flash`, and delgate to request object for both `Response#session` and `Response#flash`, ensuring the same objects are used when accessed via either request or response (#399)
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- [Benjamin Klotz] When a params validation schema is provided (in a `params do` block), only return the validated params from `request.params` (#375)
|
20
|
+
- [Sean Collins] Handle dry-schema's messages hash now being frozen by default (#391)
|
21
|
+
|
22
|
+
### Changed
|
23
|
+
|
24
|
+
- [Tim Riley] When `Action.accept` is declared (or `Action::Config.accepted_formats` configured), return a 406 error if an `Accept` request header is present but is not acceptable. In the absence of an `Accept` header, return a 415 error if a `Content-Type` header is present but not acceptable. If neither header is provided, accept the request. (#396)
|
25
|
+
- [Tim Riley] Add `Action.handle_exception` class method as a shortcut for `Hanami::Action::Config#handle_exception` (#394)
|
26
|
+
- [Tim Riley] Significantly reduce memory usage by leveraging recent dry-configurable changes, and relocating `accepted_formats`, `before_callbacks`, `after_callbacks` inheritable attributes to `config` (#392)
|
27
|
+
- [Tim Riley] Make params validation schemas (defined in `params do` block) inheritable to subclasses (#394)
|
28
|
+
- [Benhamin Klotz, Tim Riley] Raise `Hanami::Action::MissingSessionError` with a friendly message if `Request#session`, `Request#flash`, `Response#session` or `Response#flash` are called for an action that does not already include `Hanami::Action:Session` mixin (#379 via #395)
|
29
|
+
|
5
30
|
## v2.0.0.beta1 - 2022-07-20
|
6
31
|
|
7
32
|
### Fixed
|
data/README.md
CHANGED
@@ -744,7 +744,7 @@ However, you can force this value:
|
|
744
744
|
class Show < Hanami::Action
|
745
745
|
def handle(*, res)
|
746
746
|
# ...
|
747
|
-
res.format =
|
747
|
+
res.format = :json
|
748
748
|
end
|
749
749
|
end
|
750
750
|
|
@@ -771,7 +771,7 @@ end
|
|
771
771
|
# When called with "\*/\*" => 200
|
772
772
|
# When called with "text/html" => 200
|
773
773
|
# When called with "application/json" => 200
|
774
|
-
# When called with "application/xml" =>
|
774
|
+
# When called with "application/xml" => 415
|
775
775
|
```
|
776
776
|
|
777
777
|
You can check if the requested MIME type is accepted by the client.
|
@@ -820,7 +820,7 @@ response.format # => :custom
|
|
820
820
|
class Show < Hanami::Action
|
821
821
|
def handle(*, res)
|
822
822
|
# ...
|
823
|
-
res.format =
|
823
|
+
res.format = :custom
|
824
824
|
end
|
825
825
|
end
|
826
826
|
|
@@ -841,7 +841,7 @@ end
|
|
841
841
|
|
842
842
|
class Csv < Hanami::Action
|
843
843
|
def handle(*, res)
|
844
|
-
res.format =
|
844
|
+
res.format = :csv
|
845
845
|
res.body = Enumerator.new do |yielder|
|
846
846
|
yielder << csv_header
|
847
847
|
|
data/hanami-controller.gemspec
CHANGED
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.required_ruby_version = ">= 3.0"
|
22
22
|
|
23
23
|
spec.add_dependency "rack", "~> 2.0"
|
24
|
-
spec.add_dependency "hanami-utils", "~> 2.0.
|
25
|
-
spec.add_dependency "dry-configurable", "~> 0
|
24
|
+
spec.add_dependency "hanami-utils", "~> 2.0.0.rc1"
|
25
|
+
spec.add_dependency "dry-configurable", "~> 1.0", "< 2"
|
26
26
|
|
27
27
|
spec.add_development_dependency "bundler", ">= 1.6", "< 3"
|
28
28
|
spec.add_development_dependency "rack-test", "~> 2.0"
|
@@ -5,6 +5,19 @@ require "hanami/utils/hash"
|
|
5
5
|
|
6
6
|
module Hanami
|
7
7
|
class Action
|
8
|
+
# Provides access to params included in a Rack request.
|
9
|
+
#
|
10
|
+
# Offers useful access to params via methods like {#[]}, {#get} and {#to_h}.
|
11
|
+
#
|
12
|
+
# These params are available via {Request#params}.
|
13
|
+
#
|
14
|
+
# This class is used by default when {Hanami::Action::Validatable} is not included, or when no
|
15
|
+
# {Validatable::ClassMethods#params params} validation schema is defined.
|
16
|
+
#
|
17
|
+
# @see Hanami::Action::Request#params
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
# @since 0.7.0
|
8
21
|
class BaseParams
|
9
22
|
# @attr_reader env [Hash] the Rack env
|
10
23
|
#
|
@@ -18,12 +31,10 @@ module Hanami
|
|
18
31
|
# @api private
|
19
32
|
attr_reader :raw
|
20
33
|
|
21
|
-
#
|
34
|
+
# Returns a new frozen params object for the Rack env.
|
22
35
|
#
|
23
36
|
# @param env [Hash] a Rack env or an hash of params.
|
24
37
|
#
|
25
|
-
# @return [Params]
|
26
|
-
#
|
27
38
|
# @since 0.7.0
|
28
39
|
# @api private
|
29
40
|
def initialize(env)
|
@@ -33,26 +44,27 @@ module Hanami
|
|
33
44
|
freeze
|
34
45
|
end
|
35
46
|
|
36
|
-
# Returns the
|
47
|
+
# Returns the value for the given params key.
|
37
48
|
#
|
38
49
|
# @param key [Symbol] the key
|
39
50
|
#
|
40
|
-
# @return [Object,nil]
|
51
|
+
# @return [Object,nil] the associated value, if found
|
41
52
|
#
|
42
53
|
# @since 0.7.0
|
54
|
+
# @api public
|
43
55
|
def [](key)
|
44
56
|
@params[key]
|
45
57
|
end
|
46
58
|
|
47
|
-
#
|
48
|
-
#
|
59
|
+
# Returns an value associated with the given params key.
|
60
|
+
#
|
61
|
+
# You can access nested attributes by listing all the keys in the path. This uses the same key
|
62
|
+
# path semantics as `Hash#dig`.
|
49
63
|
#
|
50
64
|
# @param keys [Array<Symbol,Integer>] the key
|
51
65
|
#
|
52
66
|
# @return [Object,NilClass] return the associated value, if found
|
53
67
|
#
|
54
|
-
# @since 0.7.0
|
55
|
-
#
|
56
68
|
# @example
|
57
69
|
# require "hanami/controller"
|
58
70
|
#
|
@@ -73,6 +85,9 @@ module Hanami
|
|
73
85
|
# end
|
74
86
|
# end
|
75
87
|
# end
|
88
|
+
#
|
89
|
+
# @since 0.7.0
|
90
|
+
# @api public
|
76
91
|
def get(*keys)
|
77
92
|
@params.dig(*keys)
|
78
93
|
end
|
@@ -83,32 +98,40 @@ module Hanami
|
|
83
98
|
# @since 0.8.0
|
84
99
|
alias_method :dig, :get
|
85
100
|
|
86
|
-
#
|
101
|
+
# Returns true at all times, providing a common interface with {Params}.
|
87
102
|
#
|
88
103
|
# @return [TrueClass] always returns true
|
89
104
|
#
|
90
|
-
# @since 0.7.0
|
91
|
-
#
|
92
105
|
# @see Hanami::Action::Params#valid?
|
106
|
+
#
|
107
|
+
# @api public
|
108
|
+
# @since 0.7.0
|
93
109
|
def valid?
|
94
110
|
true
|
95
111
|
end
|
96
112
|
|
97
|
-
#
|
113
|
+
# Returns a hash of the parsed request params.
|
98
114
|
#
|
99
|
-
# @return [
|
115
|
+
# @return [Hash]
|
100
116
|
#
|
101
117
|
# @since 0.7.0
|
118
|
+
# @api public
|
102
119
|
def to_h
|
103
120
|
@params
|
104
121
|
end
|
105
122
|
alias_method :to_hash, :to_h
|
106
123
|
|
107
|
-
# Iterates
|
124
|
+
# Iterates over the params.
|
125
|
+
#
|
126
|
+
# Calls the given block with each param key-value pair; returns the full hash of params.
|
127
|
+
#
|
128
|
+
# @yieldparam key [Symbol]
|
129
|
+
# @yieldparam value [Object]
|
108
130
|
#
|
109
|
-
# @
|
131
|
+
# @return [to_h]
|
110
132
|
#
|
111
133
|
# @since 0.7.1
|
134
|
+
# @api public
|
112
135
|
def each(&blk)
|
113
136
|
to_h.each(&blk)
|
114
137
|
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require_relative "mime"
|
5
|
+
|
6
|
+
module Hanami
|
7
|
+
class Action
|
8
|
+
# Config for `Hanami::Action` classes.
|
9
|
+
#
|
10
|
+
# @see Hanami::Action.config
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
# @since 2.0.0
|
14
|
+
class Config < Dry::Configurable::Config
|
15
|
+
# Default MIME type to format mapping
|
16
|
+
#
|
17
|
+
# @since 0.2.0
|
18
|
+
# @api private
|
19
|
+
DEFAULT_FORMATS = {
|
20
|
+
"application/octet-stream" => :all,
|
21
|
+
"*/*" => :all,
|
22
|
+
"text/html" => :html
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
# Default public directory
|
26
|
+
#
|
27
|
+
# This serves as the root directory for file downloads
|
28
|
+
#
|
29
|
+
# @since 1.0.0
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
DEFAULT_PUBLIC_DIRECTORY = "public"
|
33
|
+
|
34
|
+
# @!attribute [rw] handled_exceptions
|
35
|
+
#
|
36
|
+
# Specifies how to handle exceptions with an HTTP status.
|
37
|
+
#
|
38
|
+
# Raised exceptions will return the corresponding HTTP status.
|
39
|
+
#
|
40
|
+
# @return [Hash{Exception=>Integer}] exception classes as keys and HTTP statuses as values
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# config.handled_exceptions = {ArgumentError => 400}
|
44
|
+
#
|
45
|
+
# @since 0.2.0
|
46
|
+
|
47
|
+
# Specifies how to handle exceptions with an HTTP status
|
48
|
+
#
|
49
|
+
# Raised exceptions will return the corresponding HTTP status
|
50
|
+
#
|
51
|
+
# The specified exceptions will be merged with any previously configured
|
52
|
+
# exceptions
|
53
|
+
#
|
54
|
+
# @param exceptions [Hash{Exception=>Integer}] exception classes as keys
|
55
|
+
# and HTTP statuses as values
|
56
|
+
#
|
57
|
+
# @return [void]
|
58
|
+
#
|
59
|
+
# @example
|
60
|
+
# config.handle_exceptions(ArgumentError => 400}
|
61
|
+
#
|
62
|
+
# @see handled_exceptions
|
63
|
+
#
|
64
|
+
# @since 0.2.0
|
65
|
+
def handle_exception(exceptions)
|
66
|
+
self.handled_exceptions = handled_exceptions
|
67
|
+
.merge(exceptions)
|
68
|
+
.sort { |(ex1, _), (ex2, _)| ex1.ancestors.include?(ex2) ? -1 : 1 }
|
69
|
+
.to_h
|
70
|
+
end
|
71
|
+
|
72
|
+
# @!attribute [rw] formats
|
73
|
+
#
|
74
|
+
# Specifies the MIME type to format mapping
|
75
|
+
#
|
76
|
+
# @return [Hash{String=>Symbol}] MIME type strings as keys and format symbols as values
|
77
|
+
#
|
78
|
+
# @see format
|
79
|
+
# @see Hanami::Action::Mime
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# config.formats = {"text/html" => :html}
|
83
|
+
#
|
84
|
+
# @since 0.2.0
|
85
|
+
|
86
|
+
# Registers a MIME type to format mapping
|
87
|
+
#
|
88
|
+
# @param hash [Hash{Symbol=>String}] format symbols as keys and the MIME
|
89
|
+
# type strings must as values
|
90
|
+
#
|
91
|
+
# @return [void]
|
92
|
+
#
|
93
|
+
# @see formats
|
94
|
+
# @see Hanami::Action::Mime
|
95
|
+
#
|
96
|
+
# @example
|
97
|
+
# config.format html: "text/html"
|
98
|
+
#
|
99
|
+
# @since 0.2.0
|
100
|
+
def format(hash)
|
101
|
+
symbol, mime_type = *Utils::Kernel.Array(hash)
|
102
|
+
formats[Utils::Kernel.String(mime_type)] = Utils::Kernel.Symbol(symbol)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the configured format for the given MIME type
|
106
|
+
#
|
107
|
+
# @param mime_type [#to_s,#to_str] A mime type
|
108
|
+
#
|
109
|
+
# @return [Symbol,nil] the corresponding format, nil if not found
|
110
|
+
#
|
111
|
+
# @see format
|
112
|
+
#
|
113
|
+
# @since 0.2.0
|
114
|
+
# @api private
|
115
|
+
def format_for(mime_type)
|
116
|
+
formats[mime_type]
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns the configured format's MIME types
|
120
|
+
#
|
121
|
+
# @return [Array<String>] the format's MIME types
|
122
|
+
#
|
123
|
+
# @see formats=
|
124
|
+
# @see format
|
125
|
+
#
|
126
|
+
# @since 0.8.0
|
127
|
+
#
|
128
|
+
# @api private
|
129
|
+
def mime_types
|
130
|
+
# FIXME: this isn't efficient. speed it up!
|
131
|
+
((formats.keys - DEFAULT_FORMATS.keys) +
|
132
|
+
Hanami::Action::Mime::TYPES.values).freeze
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns a MIME type for the given format
|
136
|
+
#
|
137
|
+
# @param format [#to_sym] a format
|
138
|
+
#
|
139
|
+
# @return [String,nil] the corresponding MIME type, if present
|
140
|
+
#
|
141
|
+
# @since 0.2.0
|
142
|
+
# @api private
|
143
|
+
def mime_type_for(format)
|
144
|
+
formats.key(format)
|
145
|
+
end
|
146
|
+
|
147
|
+
# @since 2.0.0
|
148
|
+
# @api private
|
149
|
+
def accepted_mime_types
|
150
|
+
accepted_formats.any? ? Mime.restrict_mime_types(self) : mime_types
|
151
|
+
end
|
152
|
+
|
153
|
+
# @!attribute [rw] default_request_format
|
154
|
+
#
|
155
|
+
# Sets a format as default fallback for all the requests without a strict
|
156
|
+
# requirement for the MIME type.
|
157
|
+
#
|
158
|
+
# The given format must be coercible to a symbol, and be a valid MIME
|
159
|
+
# type alias. If it isn't, at runtime the framework will raise an
|
160
|
+
# `Hanami::Action::UnknownFormatError`.
|
161
|
+
#
|
162
|
+
# By default, this value is nil.
|
163
|
+
#
|
164
|
+
# @return [Symbol]
|
165
|
+
#
|
166
|
+
# @see Hanami::Action::Mime
|
167
|
+
#
|
168
|
+
# @since 0.5.0
|
169
|
+
|
170
|
+
# @!attribute [rw] default_response_format
|
171
|
+
#
|
172
|
+
# Sets a format to be used for all responses regardless of the request
|
173
|
+
# type.
|
174
|
+
#
|
175
|
+
# The given format must be coercible to a symbol, and be a valid MIME
|
176
|
+
# type alias. If it isn't, at the runtime the framework will raise an
|
177
|
+
# `Hanami::Action::UnknownFormatError`.
|
178
|
+
#
|
179
|
+
# By default, this value is nil.
|
180
|
+
#
|
181
|
+
# @return [Symbol]
|
182
|
+
#
|
183
|
+
# @see Hanami::Action::Mime
|
184
|
+
#
|
185
|
+
# @since 0.5.0
|
186
|
+
|
187
|
+
# @!attribute [rw] default_charset
|
188
|
+
#
|
189
|
+
# Sets a charset (character set) as default fallback for all the requests
|
190
|
+
# without a strict requirement for the charset.
|
191
|
+
#
|
192
|
+
# By default, this value is nil.
|
193
|
+
#
|
194
|
+
# @return [String]
|
195
|
+
#
|
196
|
+
# @see Hanami::Action::Mime
|
197
|
+
#
|
198
|
+
# @since 0.3.0
|
199
|
+
|
200
|
+
# @!attribute [rw] default_headers
|
201
|
+
#
|
202
|
+
# Sets default headers for all responses.
|
203
|
+
#
|
204
|
+
# By default, this is an empty hash.
|
205
|
+
#
|
206
|
+
# @return [Hash{String=>String}] the headers
|
207
|
+
#
|
208
|
+
# @example
|
209
|
+
# config.default_headers = {"X-Frame-Options" => "DENY"}
|
210
|
+
#
|
211
|
+
# @see default_headers
|
212
|
+
#
|
213
|
+
# @since 0.4.0
|
214
|
+
|
215
|
+
# @!attribute [rw] cookies
|
216
|
+
#
|
217
|
+
# Sets default cookie options for all responses.
|
218
|
+
#
|
219
|
+
# By default this, is an empty hash.
|
220
|
+
#
|
221
|
+
# @return [Hash{Symbol=>String}] the cookie options
|
222
|
+
#
|
223
|
+
# @example
|
224
|
+
# config.cookies = {
|
225
|
+
# domain: "hanamirb.org",
|
226
|
+
# path: "/controller",
|
227
|
+
# secure: true,
|
228
|
+
# httponly: true
|
229
|
+
# }
|
230
|
+
#
|
231
|
+
# @since 0.4.0
|
232
|
+
|
233
|
+
# @!attribute [rw] root_directory
|
234
|
+
#
|
235
|
+
# Sets the the for the public directory, which is used for file downloads.
|
236
|
+
# This must be an existent directory.
|
237
|
+
#
|
238
|
+
# Defaults to the current working directory.
|
239
|
+
#
|
240
|
+
# @return [String] the directory path
|
241
|
+
#
|
242
|
+
# @api private
|
243
|
+
#
|
244
|
+
# @since 1.0.0
|
245
|
+
|
246
|
+
# @!attribute [rw] public_directory
|
247
|
+
#
|
248
|
+
# Sets the path to public directory. This directory is used for file downloads.
|
249
|
+
#
|
250
|
+
# This given directory will be appended onto the root directory.
|
251
|
+
#
|
252
|
+
# By default, the public directory is `"public"`.
|
253
|
+
# @return [String] the public directory path
|
254
|
+
#
|
255
|
+
# @example
|
256
|
+
# config.public_directory = "public"
|
257
|
+
# config.public_directory # => "/path/to/root/public"
|
258
|
+
#
|
259
|
+
# @see root_directory
|
260
|
+
#
|
261
|
+
# @since 2.0.0
|
262
|
+
def public_directory
|
263
|
+
# This must be a string, for Rack compatibility
|
264
|
+
root_directory.join(super).to_s
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -114,13 +114,7 @@ module Hanami
|
|
114
114
|
#
|
115
115
|
# @since 0.1.0
|
116
116
|
# @api private
|
117
|
-
HTTP_ACCEPT
|
118
|
-
|
119
|
-
# The header key to set the mime type of the response
|
120
|
-
#
|
121
|
-
# @since 0.1.0
|
122
|
-
# @api private
|
123
|
-
CONTENT_TYPE = ::Rack::CONTENT_TYPE
|
117
|
+
HTTP_ACCEPT = "HTTP_ACCEPT"
|
124
118
|
|
125
119
|
# The default mime type for an incoming HTTP request
|
126
120
|
#
|
@@ -152,7 +146,7 @@ module Hanami
|
|
152
146
|
#
|
153
147
|
# @since 2.0.0
|
154
148
|
# @api private
|
155
|
-
ETAG
|
149
|
+
ETAG = ::Rack::ETAG
|
156
150
|
|
157
151
|
# @since 2.0.0
|
158
152
|
# @api private
|
@@ -221,7 +215,7 @@ module Hanami
|
|
221
215
|
#
|
222
216
|
# @since 2.0.0
|
223
217
|
# @api private
|
224
|
-
COOKIE_HASH_KEY
|
218
|
+
COOKIE_HASH_KEY = ::Rack::RACK_REQUEST_COOKIE_HASH
|
225
219
|
|
226
220
|
# The key used by Rack to set the cookies as a String in the env
|
227
221
|
#
|
@@ -233,7 +227,7 @@ module Hanami
|
|
233
227
|
#
|
234
228
|
# @since 2.0.0
|
235
229
|
# @api private
|
236
|
-
RACK_INPUT
|
230
|
+
RACK_INPUT = ::Rack::RACK_INPUT
|
237
231
|
|
238
232
|
# The key that returns router params from the Rack env
|
239
233
|
# This is a builtin integration for Hanami::Router
|
@@ -250,12 +244,6 @@ module Hanami
|
|
250
244
|
|
251
245
|
# @since 2.0.0
|
252
246
|
# @api private
|
253
|
-
DEFAULT_CHARSET
|
254
|
-
|
255
|
-
# The key that returns content mime type from the Rack env
|
256
|
-
#
|
257
|
-
# @since 2.0.0
|
258
|
-
# @api private
|
259
|
-
HTTP_CONTENT_TYPE = "CONTENT_TYPE"
|
247
|
+
DEFAULT_CHARSET = "utf-8"
|
260
248
|
end
|
261
249
|
end
|
@@ -1,19 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "hanami/utils/blank"
|
4
|
-
require "hanami/controller/error"
|
5
4
|
require "rack/utils"
|
6
5
|
require "securerandom"
|
6
|
+
require_relative "errors"
|
7
7
|
|
8
8
|
module Hanami
|
9
9
|
# @api private
|
10
10
|
class Action
|
11
|
-
# Invalid CSRF Token
|
12
|
-
#
|
13
|
-
# @since 0.4.0
|
14
|
-
class InvalidCSRFTokenError < Controller::Error
|
15
|
-
end
|
16
|
-
|
17
11
|
# CSRF Protection
|
18
12
|
#
|
19
13
|
# This security mechanism is enabled automatically if sessions are turned on.
|
@@ -96,6 +90,7 @@ module Hanami
|
|
96
90
|
# @api private
|
97
91
|
def self.included(action)
|
98
92
|
unless Hanami.respond_to?(:env?) && Hanami.env?(:test)
|
93
|
+
action.include Hanami::Action::Session
|
99
94
|
action.class_eval do
|
100
95
|
before :set_csrf_token, :verify_csrf_token
|
101
96
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
class Action
|
5
|
+
# Base class for all Action errors.
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
# @since 2.0.0
|
9
|
+
class Error < ::StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
# Unknown format error
|
13
|
+
#
|
14
|
+
# This error is raised when a action sets a format that it isn't recognized
|
15
|
+
# both by `Hanami::Action::Configuration` and the list of Rack mime types
|
16
|
+
#
|
17
|
+
# @since 2.0.0
|
18
|
+
#
|
19
|
+
# @see Hanami::Action::Mime#format=
|
20
|
+
class UnknownFormatError < Error
|
21
|
+
# @since 2.0.0
|
22
|
+
# @api private
|
23
|
+
def initialize(format)
|
24
|
+
super("Cannot find a corresponding Mime type for '#{format}'. Please configure it with Hanami::Controller::Configuration#format.") # rubocop:disable Layout/LineLength
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Error raised when session is accessed but not enabled.
|
29
|
+
#
|
30
|
+
# This error is raised when `session` or `flash` is accessed/set on request/response objects
|
31
|
+
# in actions which do not include `Hanami::Action::Session`.
|
32
|
+
#
|
33
|
+
# @see Hanami::Action::Session
|
34
|
+
# @see Hanami::Action::Request#session
|
35
|
+
# @see Hanami::Action::Response#session
|
36
|
+
# @see Hanami::Action::Response#flash
|
37
|
+
#
|
38
|
+
# @api public
|
39
|
+
# @since 2.0.0
|
40
|
+
class MissingSessionError < Error
|
41
|
+
# @api private
|
42
|
+
# @since 2.0.0
|
43
|
+
def initialize(session_method)
|
44
|
+
super(<<~TEXT)
|
45
|
+
Sessions are not enabled. To use `#{session_method}`:
|
46
|
+
|
47
|
+
Configure sessions in your Hanami app, e.g.
|
48
|
+
|
49
|
+
module MyApp
|
50
|
+
class App < Hanami::App
|
51
|
+
# See Rack::Session::Cookie for options
|
52
|
+
config.sessions = :cookie, {**cookie_session_options}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Or include session support directly in your action class:
|
57
|
+
|
58
|
+
include Hanami::Action::Session
|
59
|
+
TEXT
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Invalid CSRF Token
|
64
|
+
#
|
65
|
+
# @since 0.4.0
|
66
|
+
class InvalidCSRFTokenError < Error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|