hanami-controller 1.3.0 → 2.0.0.alpha2
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 +83 -0
- data/LICENSE.md +1 -1
- data/README.md +297 -538
- data/hanami-controller.gemspec +6 -5
- data/lib/hanami/action.rb +129 -73
- data/lib/hanami/action/application_action.rb +111 -0
- data/lib/hanami/action/application_configuration.rb +92 -0
- data/lib/hanami/action/application_configuration/cookies.rb +29 -0
- data/lib/hanami/action/application_configuration/sessions.rb +46 -0
- data/lib/hanami/action/base_params.rb +2 -2
- data/lib/hanami/action/cache.rb +1 -139
- data/lib/hanami/action/cache/cache_control.rb +4 -4
- data/lib/hanami/action/cache/conditional_get.rb +7 -2
- data/lib/hanami/action/cache/directives.rb +1 -1
- data/lib/hanami/action/cache/expires.rb +3 -3
- data/lib/hanami/action/configuration.rb +430 -0
- data/lib/hanami/action/cookie_jar.rb +3 -3
- data/lib/hanami/action/cookies.rb +3 -62
- data/lib/hanami/action/csrf_protection.rb +214 -0
- data/lib/hanami/action/flash.rb +102 -207
- data/lib/hanami/action/glue.rb +5 -31
- data/lib/hanami/action/halt.rb +12 -0
- data/lib/hanami/action/mime.rb +78 -485
- data/lib/hanami/action/params.rb +3 -3
- data/lib/hanami/action/rack/file.rb +1 -1
- data/lib/hanami/action/request.rb +30 -20
- data/lib/hanami/action/response.rb +193 -0
- data/lib/hanami/action/session.rb +11 -128
- data/lib/hanami/action/standalone_action.rb +581 -0
- data/lib/hanami/action/validatable.rb +2 -2
- data/lib/hanami/action/view_name_inferrer.rb +46 -0
- data/lib/hanami/controller.rb +0 -227
- data/lib/hanami/controller/version.rb +1 -1
- data/lib/hanami/http/status.rb +2 -2
- metadata +47 -30
- data/lib/hanami-controller.rb +0 -1
- data/lib/hanami/action/callable.rb +0 -92
- data/lib/hanami/action/callbacks.rb +0 -214
- data/lib/hanami/action/configurable.rb +0 -50
- data/lib/hanami/action/exposable.rb +0 -126
- data/lib/hanami/action/exposable/guard.rb +0 -104
- data/lib/hanami/action/head.rb +0 -121
- data/lib/hanami/action/rack.rb +0 -399
- data/lib/hanami/action/rack/callable.rb +0 -47
- data/lib/hanami/action/redirect.rb +0 -59
- data/lib/hanami/action/throwable.rb +0 -196
- data/lib/hanami/controller/configuration.rb +0 -763
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
class Action
|
5
|
+
class ApplicationConfiguration
|
6
|
+
# Wrapper for application-level configuration of HTTP cookies for Hanami actions.
|
7
|
+
# This decorates the hash of cookie options that is otherwise directly configurable
|
8
|
+
# on actions, and adds the `enabled?` method to allow `ApplicationAction` to
|
9
|
+
# determine whether to include the `Action::Cookies` module.
|
10
|
+
#
|
11
|
+
# @since 2.0.0
|
12
|
+
class Cookies
|
13
|
+
attr_reader :options
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def enabled?
|
20
|
+
!options.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_h
|
24
|
+
options.to_h
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/constants"
|
4
|
+
require "hanami/utils/string"
|
5
|
+
require "hanami/utils/class"
|
6
|
+
|
7
|
+
module Hanami
|
8
|
+
class Action
|
9
|
+
class ApplicationConfiguration
|
10
|
+
# Configuration for HTTP sessions in Hanami actions
|
11
|
+
#
|
12
|
+
# @since 2.0.0
|
13
|
+
class Sessions
|
14
|
+
attr_reader :storage, :options
|
15
|
+
|
16
|
+
def initialize(storage = nil, *options)
|
17
|
+
@storage = storage
|
18
|
+
@options = options
|
19
|
+
end
|
20
|
+
|
21
|
+
def enabled?
|
22
|
+
!storage.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def middleware
|
26
|
+
return [] if !enabled?
|
27
|
+
|
28
|
+
[[storage_middleware, options]]
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def storage_middleware
|
34
|
+
require_storage
|
35
|
+
|
36
|
+
name = Utils::String.classify(storage)
|
37
|
+
Utils::Class.load!(name, ::Rack::Session)
|
38
|
+
end
|
39
|
+
|
40
|
+
def require_storage
|
41
|
+
require "rack/session/#{storage}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -2,7 +2,7 @@ require 'rack/request'
|
|
2
2
|
require 'hanami/utils/hash'
|
3
3
|
|
4
4
|
module Hanami
|
5
|
-
|
5
|
+
class Action
|
6
6
|
class BaseParams
|
7
7
|
# The key that returns raw input from the Rack env
|
8
8
|
#
|
@@ -173,7 +173,7 @@ module Hanami
|
|
173
173
|
def _router_params(fallback = {})
|
174
174
|
env.fetch(ROUTER_PARAMS) do
|
175
175
|
if session = fallback.delete(RACK_SESSION) # rubocop:disable Lint/AssignmentInCondition
|
176
|
-
fallback[RACK_SESSION] = Utils::Hash.
|
176
|
+
fallback[RACK_SESSION] = Utils::Hash.deep_symbolize(session)
|
177
177
|
end
|
178
178
|
|
179
179
|
fallback
|
data/lib/hanami/action/cache.rb
CHANGED
@@ -3,7 +3,7 @@ require 'hanami/action/cache/expires'
|
|
3
3
|
require 'hanami/action/cache/conditional_get'
|
4
4
|
|
5
5
|
module Hanami
|
6
|
-
|
6
|
+
class Action
|
7
7
|
# Cache type API
|
8
8
|
#
|
9
9
|
# @since 0.3.0
|
@@ -26,144 +26,6 @@ module Hanami
|
|
26
26
|
include CacheControl, Expires
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
30
|
-
protected
|
31
|
-
|
32
|
-
# Specify response freshness policy for HTTP caches (Cache-Control header).
|
33
|
-
# Any number of non-value directives (:public, :private, :no_cache,
|
34
|
-
# :no_store, :must_revalidate, :proxy_revalidate) may be passed along with
|
35
|
-
# a Hash of value directives (:max_age, :min_stale, :s_max_age).
|
36
|
-
#
|
37
|
-
# See RFC 2616 / 14.9 for more on standard cache control directives:
|
38
|
-
# http://tools.ietf.org/html/rfc2616#section-14.9.1
|
39
|
-
#
|
40
|
-
# @param values [Array<Symbols, Hash>] mapped to cache_control directives
|
41
|
-
# @option values [Symbol] :public
|
42
|
-
# @option values [Symbol] :private
|
43
|
-
# @option values [Symbol] :no_cache
|
44
|
-
# @option values [Symbol] :no_store
|
45
|
-
# @option values [Symbol] :must_validate
|
46
|
-
# @option values [Symbol] :proxy_revalidate
|
47
|
-
# @option values [Hash] :max_age
|
48
|
-
# @option values [Hash] :min_stale
|
49
|
-
# @option values [Hash] :s_max_age
|
50
|
-
#
|
51
|
-
# @return void
|
52
|
-
#
|
53
|
-
# @since 0.3.0
|
54
|
-
#
|
55
|
-
# @example
|
56
|
-
# require 'hanami/controller'
|
57
|
-
# require 'hanami/action/cache'
|
58
|
-
#
|
59
|
-
# class Show
|
60
|
-
# include Hanami::Action
|
61
|
-
# include Hanami::Action::Cache
|
62
|
-
#
|
63
|
-
# def call(params)
|
64
|
-
# # ...
|
65
|
-
#
|
66
|
-
# # set Cache-Control directives
|
67
|
-
# cache_control :public, max_age: 900, s_maxage: 86400
|
68
|
-
#
|
69
|
-
# # overwrite previous Cache-Control directives
|
70
|
-
# cache_control :private, :no_cache, :no_store
|
71
|
-
#
|
72
|
-
# => Cache-Control: private, no-store, max-age=900
|
73
|
-
#
|
74
|
-
# end
|
75
|
-
# end
|
76
|
-
def cache_control(*values)
|
77
|
-
cache_control = CacheControl::Directives.new(*values)
|
78
|
-
headers.merge!(cache_control.headers)
|
79
|
-
end
|
80
|
-
|
81
|
-
# Set the Expires header and Cache-Control/max-age directive. Amount
|
82
|
-
# can be an integer number of seconds in the future or a Time object
|
83
|
-
# indicating when the response should be considered "stale". The remaining
|
84
|
-
# "values" arguments are passed to the #cache_control helper:
|
85
|
-
#
|
86
|
-
# @param amount [Integer,Time] number of seconds or point in time
|
87
|
-
# @param values [Array<Symbols>] mapped to cache_control directives
|
88
|
-
#
|
89
|
-
# @return void
|
90
|
-
#
|
91
|
-
# @since 0.3.0
|
92
|
-
#
|
93
|
-
# @example
|
94
|
-
# require 'hanami/controller'
|
95
|
-
# require 'hanami/action/cache'
|
96
|
-
#
|
97
|
-
# class Show
|
98
|
-
# include Hanami::Action
|
99
|
-
# include Hanami::Action::Cache
|
100
|
-
#
|
101
|
-
# def call(params)
|
102
|
-
# # ...
|
103
|
-
#
|
104
|
-
# # set Cache-Control directives and Expires
|
105
|
-
# expires 900, :public
|
106
|
-
#
|
107
|
-
# # overwrite Cache-Control directives and Expires
|
108
|
-
# expires 300, :private, :no_cache, :no_store
|
109
|
-
#
|
110
|
-
# => Expires: Thu, 26 Jun 2014 12:00:00 GMT
|
111
|
-
# => Cache-Control: private, no-cache, no-store max-age=300
|
112
|
-
#
|
113
|
-
# end
|
114
|
-
# end
|
115
|
-
def expires(amount, *values)
|
116
|
-
expires = Expires::Directives.new(amount, *values)
|
117
|
-
headers.merge!(expires.headers)
|
118
|
-
end
|
119
|
-
|
120
|
-
# Set the etag, last_modified, or both headers on the response
|
121
|
-
# and halts a 304 Not Modified if the request is still fresh
|
122
|
-
# respecting IfNoneMatch and IfModifiedSince request headers
|
123
|
-
#
|
124
|
-
# @param options [Hash]
|
125
|
-
# @option options [Integer] :etag for testing IfNoneMatch conditions
|
126
|
-
# @option options [Date] :last_modified for testing IfModifiedSince conditions
|
127
|
-
#
|
128
|
-
# @return void
|
129
|
-
#
|
130
|
-
# @since 0.3.0
|
131
|
-
#
|
132
|
-
# @example
|
133
|
-
# require 'hanami/controller'
|
134
|
-
# require 'hanami/action/cache'
|
135
|
-
#
|
136
|
-
# class Show
|
137
|
-
# include Hanami::Action
|
138
|
-
# include Hanami::Action::Cache
|
139
|
-
#
|
140
|
-
# def call(params)
|
141
|
-
# # ...
|
142
|
-
#
|
143
|
-
# # set etag response header and halt 304
|
144
|
-
# # if request matches IF_NONE_MATCH header
|
145
|
-
# fresh etag: @resource.updated_at.to_i
|
146
|
-
#
|
147
|
-
# # set last_modified response header and halt 304
|
148
|
-
# # if request matches IF_MODIFIED_SINCE
|
149
|
-
# fresh last_modified: @resource.updated_at
|
150
|
-
#
|
151
|
-
# # set etag and last_modified response header,
|
152
|
-
# # halt 304 if request matches IF_MODIFIED_SINCE
|
153
|
-
# # and IF_NONE_MATCH
|
154
|
-
# fresh last_modified: @resource.updated_at
|
155
|
-
#
|
156
|
-
# end
|
157
|
-
# end
|
158
|
-
def fresh(options)
|
159
|
-
conditional_get = ConditionalGet.new(@_env, options)
|
160
|
-
|
161
|
-
headers.merge!(conditional_get.headers)
|
162
|
-
|
163
|
-
conditional_get.fresh? do
|
164
|
-
halt 304
|
165
|
-
end
|
166
|
-
end
|
167
29
|
end
|
168
30
|
end
|
169
31
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'hanami/action/cache/directives'
|
2
2
|
|
3
3
|
module Hanami
|
4
|
-
|
4
|
+
class Action
|
5
5
|
module Cache
|
6
6
|
# Module with Cache-Control logic
|
7
7
|
#
|
@@ -37,7 +37,7 @@ module Hanami
|
|
37
37
|
def cache_control_directives
|
38
38
|
@cache_control_directives || Object.new.tap do |null_object|
|
39
39
|
def null_object.headers
|
40
|
-
Hash.new
|
40
|
+
::Hash.new
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -49,9 +49,9 @@ module Hanami
|
|
49
49
|
# @api private
|
50
50
|
#
|
51
51
|
# @see Hanami::Action#finish
|
52
|
-
def finish
|
52
|
+
def finish(_, res, _)
|
53
|
+
res.headers.merge!(self.class.cache_control_directives.headers) unless res.headers.include? HEADER
|
53
54
|
super
|
54
|
-
headers.merge!(self.class.cache_control_directives.headers) unless headers.include? HEADER
|
55
55
|
end
|
56
56
|
|
57
57
|
# Class which stores CacheControl values
|
@@ -1,5 +1,7 @@
|
|
1
|
+
require "hanami/utils/blank"
|
2
|
+
|
1
3
|
module Hanami
|
2
|
-
|
4
|
+
class Action
|
3
5
|
module Cache
|
4
6
|
# @since 0.3.0
|
5
7
|
# @api private
|
@@ -67,7 +69,10 @@ module Hanami
|
|
67
69
|
# @since 0.3.0
|
68
70
|
# @api private
|
69
71
|
def fresh?
|
70
|
-
|
72
|
+
return false if Hanami::Utils::Blank.blank?(modified_since)
|
73
|
+
return false if Hanami::Utils::Blank.blank?(@value)
|
74
|
+
|
75
|
+
Time.httpdate(modified_since).to_i >= @value.to_time.to_i
|
71
76
|
end
|
72
77
|
|
73
78
|
# @since 0.3.0
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'hanami/action/cache/cache_control'
|
2
2
|
|
3
3
|
module Hanami
|
4
|
-
|
4
|
+
class Action
|
5
5
|
module Cache
|
6
6
|
# Module with Expires logic
|
7
7
|
#
|
@@ -49,9 +49,9 @@ module Hanami
|
|
49
49
|
# @api private
|
50
50
|
#
|
51
51
|
# @see Hanami::Action#finish
|
52
|
-
def finish
|
52
|
+
def finish(_, res, _)
|
53
|
+
res.headers.merge!(self.class.expires_directives.headers) unless res.headers.include? HEADER
|
53
54
|
super
|
54
|
-
headers.merge!(self.class.expires_directives.headers) unless headers.include? HEADER
|
55
55
|
end
|
56
56
|
|
57
57
|
# Class which stores Expires directives
|
@@ -0,0 +1,430 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "hanami/utils/kernel"
|
5
|
+
require "pathname"
|
6
|
+
require_relative "mime"
|
7
|
+
|
8
|
+
module Hanami
|
9
|
+
class Action
|
10
|
+
class Configuration
|
11
|
+
include Dry::Configurable
|
12
|
+
|
13
|
+
# Initialize the Configuration
|
14
|
+
#
|
15
|
+
# @yield [config] the configuration object
|
16
|
+
#
|
17
|
+
# @return [Configuration]
|
18
|
+
#
|
19
|
+
# @since 2.0.0
|
20
|
+
# @api private
|
21
|
+
def initialize(*)
|
22
|
+
super
|
23
|
+
yield self if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the list of available settings
|
27
|
+
#
|
28
|
+
# @return [Set]
|
29
|
+
#
|
30
|
+
# @since 2.0.0
|
31
|
+
# @api private
|
32
|
+
def settings
|
33
|
+
self.class.settings
|
34
|
+
end
|
35
|
+
|
36
|
+
# @!method handled_exceptions=(exceptions)
|
37
|
+
#
|
38
|
+
# Specifies how to handle exceptions with an HTTP status
|
39
|
+
#
|
40
|
+
# Raised exceptions will return the corresponding HTTP status
|
41
|
+
#
|
42
|
+
# @param exceptions [Hash{Exception=>Integer}] exception classes as
|
43
|
+
# keys and HTTP statuses as values
|
44
|
+
#
|
45
|
+
# @return [void]
|
46
|
+
#
|
47
|
+
# @since 0.2.0
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# configuration.handled_exceptions = {ArgumentError => 400}
|
51
|
+
#
|
52
|
+
# @!method handled_exceptions
|
53
|
+
#
|
54
|
+
# Returns the configured handled exceptions
|
55
|
+
#
|
56
|
+
# @return [Hash{Exception=>Integer}]
|
57
|
+
#
|
58
|
+
# @see handled_exceptions=
|
59
|
+
#
|
60
|
+
# @since 0.2.0
|
61
|
+
setting :handled_exceptions, {}
|
62
|
+
|
63
|
+
# Specifies how to handle exceptions with an HTTP status
|
64
|
+
#
|
65
|
+
# Raised exceptions will return the corresponding HTTP status
|
66
|
+
#
|
67
|
+
# The specified exceptions will be merged with any previously configured
|
68
|
+
# exceptions
|
69
|
+
#
|
70
|
+
# @param exceptions [Hash{Exception=>Integer}] exception classes as keys
|
71
|
+
# and HTTP statuses as values
|
72
|
+
#
|
73
|
+
# @return [void]
|
74
|
+
#
|
75
|
+
# @since 0.2.0
|
76
|
+
#
|
77
|
+
# @see handled_exceptions=
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# configuration.handle_exceptions(ArgumentError => 400}
|
81
|
+
def handle_exception(exceptions)
|
82
|
+
self.handled_exceptions = handled_exceptions
|
83
|
+
.merge(exceptions)
|
84
|
+
.sort { |(ex1, _), (ex2, _)| ex1.ancestors.include?(ex2) ? -1 : 1 }
|
85
|
+
.to_h
|
86
|
+
end
|
87
|
+
|
88
|
+
# Default MIME type to format mapping
|
89
|
+
#
|
90
|
+
# @since 0.2.0
|
91
|
+
# @api private
|
92
|
+
DEFAULT_FORMATS = {
|
93
|
+
'application/octet-stream' => :all,
|
94
|
+
'*/*' => :all,
|
95
|
+
'text/html' => :html
|
96
|
+
}.freeze
|
97
|
+
|
98
|
+
# @!method formats=(formats)
|
99
|
+
#
|
100
|
+
# Specifies the MIME type to format mapping
|
101
|
+
#
|
102
|
+
# @param formats [Hash{String=>Symbol}] MIME type strings as keys and
|
103
|
+
# format symbols as values
|
104
|
+
#
|
105
|
+
# @return [void]
|
106
|
+
#
|
107
|
+
# @since 0.2.0
|
108
|
+
#
|
109
|
+
# @see format
|
110
|
+
# @see Hanami::Action::Mime
|
111
|
+
#
|
112
|
+
# @example
|
113
|
+
# configuration.formats = {"text/html" => :html}
|
114
|
+
#
|
115
|
+
# @!method formats
|
116
|
+
#
|
117
|
+
# Returns the configured MIME type to format mapping
|
118
|
+
#
|
119
|
+
# @return [Symbol,nil] the corresponding format, if present
|
120
|
+
#
|
121
|
+
# @see format
|
122
|
+
# @see formats=
|
123
|
+
#
|
124
|
+
# @since 0.2.0
|
125
|
+
setting :formats, DEFAULT_FORMATS.dup
|
126
|
+
|
127
|
+
# Registers a MIME type to format mapping
|
128
|
+
#
|
129
|
+
# @param hash [Hash{Symbol=>String}] format symbols as keys and the MIME
|
130
|
+
# type strings must as values
|
131
|
+
#
|
132
|
+
# @return [void]
|
133
|
+
#
|
134
|
+
# @since 0.2.0
|
135
|
+
#
|
136
|
+
# @see Hanami::Action::Mime
|
137
|
+
#
|
138
|
+
# @example configuration.format html: "text/html"
|
139
|
+
def format(hash)
|
140
|
+
symbol, mime_type = *Utils::Kernel.Array(hash)
|
141
|
+
formats[Utils::Kernel.String(mime_type)] = Utils::Kernel.Symbol(symbol)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Returns the configured format for the given MIME type
|
145
|
+
#
|
146
|
+
# @param mime_type [#to_s,#to_str] A mime type
|
147
|
+
#
|
148
|
+
# @return [Symbol,nil] the corresponding format, nil if not found
|
149
|
+
#
|
150
|
+
# @see format
|
151
|
+
#
|
152
|
+
# @since 0.2.0
|
153
|
+
# @api private
|
154
|
+
def format_for(mime_type)
|
155
|
+
formats[mime_type]
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns the configured format's MIME types
|
159
|
+
#
|
160
|
+
# @return [Array<String>] the format's MIME types
|
161
|
+
#
|
162
|
+
# @see formats=
|
163
|
+
# @see format
|
164
|
+
#
|
165
|
+
# @since 0.8.0
|
166
|
+
#
|
167
|
+
# @api private
|
168
|
+
def mime_types
|
169
|
+
# FIXME: this isn't efficient. speed it up!
|
170
|
+
((formats.keys - DEFAULT_FORMATS.keys) +
|
171
|
+
Hanami::Action::Mime::TYPES.values).freeze
|
172
|
+
end
|
173
|
+
|
174
|
+
# Returns a MIME type for the given format
|
175
|
+
#
|
176
|
+
# @param format [#to_sym] a format
|
177
|
+
#
|
178
|
+
# @return [String,nil] the corresponding MIME type, if present
|
179
|
+
#
|
180
|
+
# @since 0.2.0
|
181
|
+
# @api private
|
182
|
+
def mime_type_for(format)
|
183
|
+
formats.key(format)
|
184
|
+
end
|
185
|
+
|
186
|
+
# @!method default_request_format=(format)
|
187
|
+
#
|
188
|
+
# Sets a format as default fallback for all the requests without a strict
|
189
|
+
# requirement for the MIME type.
|
190
|
+
#
|
191
|
+
# The given format must be coercible to a symbol, and be a valid MIME
|
192
|
+
# type alias. If it isn't, at runtime the framework will raise an
|
193
|
+
# `Hanami::Controller::UnknownFormatError`.
|
194
|
+
#
|
195
|
+
# By default, this value is nil.
|
196
|
+
#
|
197
|
+
# @param format [Symbol]
|
198
|
+
#
|
199
|
+
# @return [void]
|
200
|
+
#
|
201
|
+
# @since 0.5.0
|
202
|
+
#
|
203
|
+
# @see Hanami::Action::Mime
|
204
|
+
#
|
205
|
+
# @!method default_request_format
|
206
|
+
#
|
207
|
+
# Returns the configured default request format
|
208
|
+
#
|
209
|
+
# @return [Symbol] format
|
210
|
+
#
|
211
|
+
# @see default_request_format=
|
212
|
+
#
|
213
|
+
# @since 0.5.0
|
214
|
+
setting :default_request_format do |format|
|
215
|
+
Utils::Kernel.Symbol(format) unless format.nil?
|
216
|
+
end
|
217
|
+
|
218
|
+
# @!method default_response_format=(format)
|
219
|
+
#
|
220
|
+
# Sets a format to be used for all responses regardless of the request
|
221
|
+
# type.
|
222
|
+
#
|
223
|
+
# The given format must be coercible to a symbol, and be a valid MIME
|
224
|
+
# type alias. If it isn't, at the runtime the framework will raise an
|
225
|
+
# `Hanami::Controller::UnknownFormatError`.
|
226
|
+
#
|
227
|
+
# By default, this value is nil.
|
228
|
+
#
|
229
|
+
# @param format [Symbol]
|
230
|
+
#
|
231
|
+
# @return [void]
|
232
|
+
#
|
233
|
+
# @since 0.5.0
|
234
|
+
#
|
235
|
+
# @see Hanami::Action::Mime
|
236
|
+
#
|
237
|
+
# @!method default_response_format
|
238
|
+
#
|
239
|
+
# Returns the configured default response format
|
240
|
+
#
|
241
|
+
# @return [Symbol] format
|
242
|
+
#
|
243
|
+
# @see default_request_format=
|
244
|
+
#
|
245
|
+
# @since 0.5.0
|
246
|
+
setting :default_response_format do |format|
|
247
|
+
Utils::Kernel.Symbol(format) unless format.nil?
|
248
|
+
end
|
249
|
+
|
250
|
+
# @!method default_charset=(charset)
|
251
|
+
#
|
252
|
+
# Sets a charset (character set) as default fallback for all the requests
|
253
|
+
# without a strict requirement for the charset.
|
254
|
+
#
|
255
|
+
# By default, this value is nil.
|
256
|
+
#
|
257
|
+
# @param charset [String]
|
258
|
+
#
|
259
|
+
# @return [void]
|
260
|
+
#
|
261
|
+
# @since 0.3.0
|
262
|
+
#
|
263
|
+
# @see Hanami::Action::Mime
|
264
|
+
#
|
265
|
+
# @!method default_charset
|
266
|
+
#
|
267
|
+
# Returns the configured default charset.
|
268
|
+
#
|
269
|
+
# @return [String,nil] the charset, if present
|
270
|
+
#
|
271
|
+
# @see default_charset=
|
272
|
+
#
|
273
|
+
# @since 0.3.0
|
274
|
+
setting :default_charset
|
275
|
+
|
276
|
+
# @!method default_headers=(headers)
|
277
|
+
#
|
278
|
+
# Sets default headers for all responses.
|
279
|
+
#
|
280
|
+
# By default, this is an empty hash.
|
281
|
+
#
|
282
|
+
# @param headers [Hash{String=>String}] the headers
|
283
|
+
#
|
284
|
+
# @return [void]
|
285
|
+
#
|
286
|
+
# @since 0.4.0
|
287
|
+
#
|
288
|
+
# @see default_headers
|
289
|
+
#
|
290
|
+
# @example
|
291
|
+
# configuration.default_headers = {'X-Frame-Options' => 'DENY'}
|
292
|
+
#
|
293
|
+
# @!method default_headers
|
294
|
+
#
|
295
|
+
# Returns the configured headers
|
296
|
+
#
|
297
|
+
# @return [Hash{String=>String}] the headers
|
298
|
+
#
|
299
|
+
# @since 0.4.0
|
300
|
+
#
|
301
|
+
# @see default_headers=
|
302
|
+
setting :default_headers, {} do |headers|
|
303
|
+
headers.compact
|
304
|
+
end
|
305
|
+
|
306
|
+
# @!method cookies=(cookie_options)
|
307
|
+
#
|
308
|
+
# Sets default cookie options for all responses.
|
309
|
+
#
|
310
|
+
# By default this, is an empty hash.
|
311
|
+
#
|
312
|
+
# @param cookie_options [Hash{Symbol=>String}] the cookie options
|
313
|
+
#
|
314
|
+
# @return [void]
|
315
|
+
#
|
316
|
+
# @since 0.4.0
|
317
|
+
#
|
318
|
+
# @example
|
319
|
+
# configuration.cookies = {
|
320
|
+
# domain: 'hanamirb.org',
|
321
|
+
# path: '/controller',
|
322
|
+
# secure: true,
|
323
|
+
# httponly: true
|
324
|
+
# }
|
325
|
+
#
|
326
|
+
# @!method cookies
|
327
|
+
#
|
328
|
+
# Returns the configured cookie options
|
329
|
+
#
|
330
|
+
# @return [Hash{Symbol=>String}]
|
331
|
+
#
|
332
|
+
# @since 0.4.0
|
333
|
+
#
|
334
|
+
# @see cookies=
|
335
|
+
setting :cookies, {} do |cookie_options|
|
336
|
+
# Call `to_h` here to permit `ApplicationConfiguration::Cookies` object to be
|
337
|
+
# provided when application actions are configured
|
338
|
+
cookie_options.to_h.compact
|
339
|
+
end
|
340
|
+
|
341
|
+
# @!method root_directory=(dir)
|
342
|
+
#
|
343
|
+
# Sets the the for the public directory, which is used for file downloads.
|
344
|
+
# This must be an existent directory.
|
345
|
+
#
|
346
|
+
# Defaults to the current working directory.
|
347
|
+
#
|
348
|
+
# @param dir [String] the directory path
|
349
|
+
#
|
350
|
+
# @return [void]
|
351
|
+
#
|
352
|
+
# @since 1.0.0
|
353
|
+
#
|
354
|
+
# @api private
|
355
|
+
#
|
356
|
+
# @!method root_directory
|
357
|
+
#
|
358
|
+
# Returns the configured root directory
|
359
|
+
#
|
360
|
+
# @return [String] the directory path
|
361
|
+
#
|
362
|
+
# @see root_directory=
|
363
|
+
#
|
364
|
+
# @since 1.0.0
|
365
|
+
#
|
366
|
+
# @api private
|
367
|
+
setting :root_directory do |dir|
|
368
|
+
dir ||= Dir.pwd
|
369
|
+
|
370
|
+
Pathname(dir).realpath
|
371
|
+
end
|
372
|
+
|
373
|
+
# Default public directory
|
374
|
+
#
|
375
|
+
# This serves as the root directory for file downloads
|
376
|
+
#
|
377
|
+
# @since 1.0.0
|
378
|
+
#
|
379
|
+
# @api private
|
380
|
+
DEFAULT_PUBLIC_DIRECTORY = 'public'.freeze
|
381
|
+
|
382
|
+
# @!method public_directory=(directory)
|
383
|
+
#
|
384
|
+
# Sets the path to public directory. This directory is used for file downloads.
|
385
|
+
#
|
386
|
+
# This given directory will be appended onto the root directory.
|
387
|
+
#
|
388
|
+
# By default, the public directory is "public".
|
389
|
+
#
|
390
|
+
# @param directory [String] the public directory path
|
391
|
+
#
|
392
|
+
# @return [void]
|
393
|
+
#
|
394
|
+
# @see root_directory
|
395
|
+
# @see public_directory
|
396
|
+
setting :public_directory, DEFAULT_PUBLIC_DIRECTORY
|
397
|
+
|
398
|
+
# Returns the configured public directory, appended onto the root directory.
|
399
|
+
#
|
400
|
+
# @return [String] the fill directory path
|
401
|
+
#
|
402
|
+
# @example
|
403
|
+
# configuration.public_directory = "public"
|
404
|
+
#
|
405
|
+
# configuration.public_directory
|
406
|
+
# # => "/path/to/root/public"
|
407
|
+
#
|
408
|
+
# @see public_directory=
|
409
|
+
# @see root_directory=
|
410
|
+
def public_directory
|
411
|
+
# This must be a string, for Rack compatibility
|
412
|
+
root_directory.join(super).to_s
|
413
|
+
end
|
414
|
+
|
415
|
+
private
|
416
|
+
|
417
|
+
def method_missing(name, *args, &block)
|
418
|
+
if config.respond_to?(name)
|
419
|
+
config.public_send(name, *args, &block)
|
420
|
+
else
|
421
|
+
super
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
def respond_to_missing?(name, _incude_all = false)
|
426
|
+
config.respond_to?(name) || super
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|