hanami-controller 2.0.0.alpha1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49b2d026e0d36ca0e450dd4ac0b3b0cf6f4c61e17cc8c81f71b802d23d8fbb29
4
- data.tar.gz: 59f0c51a316fba2fb712806f16a129c36e9bc875a35820a6ac042066d79d1126
3
+ metadata.gz: d159c89cbe6b24762a475776ae1585e76925c8f26501c6334c908893624587e5
4
+ data.tar.gz: b5f4b394c5337ae9b46f2482f86f69aaf151dbaee9cd2ac95be15f69a12ce65a
5
5
  SHA512:
6
- metadata.gz: 0b7d144f8a8a076d2e4e5149d0cd3415041a49049888671a67f586db1e107cf749dec6d8f4141099205eb8eb6bbb3f670420c78df3b9509845de364310ceb9b1
7
- data.tar.gz: 2dbc46c1fec018bb5e7bf5ee63d019a925eeda300948037d78c420a4c81034d53e43784ba4d39a4d3f8d63c957a2c00d8307b1127e9b5c292b5033f5599232ce
6
+ metadata.gz: aac599272b21e8ca56b2c519b93a47593dc126d442be727d87b4e8884e1c2da3d349d480399e1ed781560acb9e450e24b1985fbcd7083d65d79fb8573c3db606
7
+ data.tar.gz: 75beecc46dce543367e7869887cda80937c2d838a65996f9bd831e56dfade6fa1ccccc03c7c0a0ace5aad833e26db10638e6c51e869b70cb6dc95abd351b7000
data/CHANGELOG.md CHANGED
@@ -1,6 +1,25 @@
1
1
  # Hanami::Controller
2
2
  Complete, fast and testable actions for Rack
3
3
 
4
+ ## v2.0.0.alpha2 - 2021-05-04
5
+ ### Added
6
+ - [Luca Guidi] Official support for Ruby: MRI 3.0
7
+ - [Tim Riley] Introduced `Hanami::Action::ApplicationAction`
8
+ - [Tim Riley] Introduced `Hanami::Action::Configuration`
9
+ - [Tim Riley] Introduced `Hanami::Action::ApplicationConfiguration`
10
+ - [Tim Riley] Auto-inject a paired view into any `Hanami::Action::ApplicationAction` instance
11
+ - [Tim Riley] Auto-render `Hanami::Action::ApplicationAction` subclasses that don't implement `#handle`
12
+ - [Tim Riley] Enable CSRF protection automatically when HTTP sessions are enabled
13
+
14
+ ### Fixed
15
+ - [Luca Guidi] Ensure `Hanami::Action::Response#renderable?` to return `false` when body is set
16
+ - [Andrew Croome] Ensure `Hanami::Action.accept` to use Rack `CONTENT_TYPE` for the _before callback_ check
17
+
18
+ ### Changed
19
+ - [Luca Guidi] Drop support for Ruby: MRI 2.5.
20
+ - [Tim Riley] Removed `Hanami::Action.handle_exception` in favor of `Hanami::Action.config.handle_exception`
21
+ - [Tim Riley] Rewritten `Hanami::Action::Flash`, based on Roda's `FlashHash`
22
+
4
23
  ## v2.0.0.alpha1 - 2019-01-30
5
24
  ### Added
6
25
  - [Luca Guidi] `Hanami::Action::Request#session` to access the HTTP session as it was originally sent
@@ -50,6 +69,16 @@ Complete, fast and testable actions for Rack
50
69
  - [Luca Guidi] When an exception is raised, it won't be caught, unless it's handled
51
70
  - [Luca Guidi] `Hanami::Action` exception handlers now accept `Hanami::Action::Request`, `Hanami::Action::Response`, and exception arguments
52
71
 
72
+ ## v1.3.3 - 2020-01-14
73
+ ### Added
74
+ - [Luca Guidi] Official support for Ruby: MRI 2.7
75
+ - [Luca Guidi] Support `rack` 2.1
76
+ - [Luca Guidi] Support for both `hanami-validations` 1 and 2
77
+
78
+ ## v1.3.2 - 2019-06-28
79
+ ### Fixed
80
+ - [Ian Ker-Seymer] Ensure `Etag` to work when `If-Modified-Since` is sent from browser and upstream proxy sets `Last-Modified` automatically.
81
+
53
82
  ## v1.3.1 - 2019-01-18
54
83
  ### Added
55
84
  - [Luca Guidi] Official support for Ruby: MRI 2.6
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2014-2017 Luca Guidi
1
+ Copyright © 2014-2021 Luca Guidi
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -5,20 +5,20 @@ Complete, fast and testable actions for Rack and [Hanami](http://hanamirb.org)
5
5
  ## Status
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/hanami-controller.svg)](https://badge.fury.io/rb/hanami-controller)
8
- [![TravisCI](https://travis-ci.org/hanami/controller.svg?branch=master)](https://travis-ci.org/hanami/controller)
9
- [![CircleCI](https://circleci.com/gh/hanami/controller/tree/master.svg?style=svg)](https://circleci.com/gh/hanami/controller/tree/master)
10
- [![Test Coverage](https://codecov.io/gh/hanami/controller/branch/master/graph/badge.svg)](https://codecov.io/gh/hanami/controller)
8
+ [![CI](https://github.com/hanami/controller/workflows/ci/badge.svg?branch=unstable)](https://github.com/hanami/controller/actions?query=workflow%3Aci+branch%3Aunstable)
9
+ [![Test Coverage](https://codecov.io/gh/hanami/controller/branch/unstable/graph/badge.svg)](https://codecov.io/gh/hanami/controller)
11
10
  [![Depfu](https://badges.depfu.com/badges/7cd17419fba78b726be1353118fb01de/overview.svg)](https://depfu.com/github/hanami/controller?project=Bundler)
12
11
  [![Inline Docs](http://inch-ci.org/github/hanami/controller.svg)](http://inch-ci.org/github/hanami/controller)
13
12
 
14
13
  ## Contact
15
14
 
16
15
  * Home page: http://hanamirb.org
16
+ * Community: http://hanamirb.org/community
17
+ * Guides: https://guides.hanamirb.org
17
18
  * Mailing List: http://hanamirb.org/mailing-list
18
19
  * API Doc: http://rdoc.info/gems/hanami-controller
19
20
  * Bugs/Issues: https://github.com/hanami/controller/issues
20
21
  * Chat: http://chat.hanamirb.org
21
- * Chat: https://gitter.im/hanami/chat
22
22
 
23
23
  ## Rubies
24
24
 
@@ -963,6 +963,6 @@ __Hanami::Controller__ uses [Semantic Versioning 2.0.0](http://semver.org)
963
963
 
964
964
  ## Copyright
965
965
 
966
- Copyright © 2014-2019 Luca Guidi – Released under MIT License
966
+ Copyright © 2014-2021 Luca Guidi – Released under MIT License
967
967
 
968
968
  This project was formerly known as Lotus (`lotus-controller`).
@@ -17,13 +17,14 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = []
18
18
  spec.test_files = spec.files.grep(%r{^(spec)/})
19
19
  spec.require_paths = ['lib']
20
- spec.required_ruby_version = '>= 2.5.0'
20
+ spec.required_ruby_version = '>= 2.6.0'
21
21
 
22
22
  spec.add_dependency 'rack', '~> 2.0'
23
23
  spec.add_dependency 'hanami-utils', '~> 2.0.alpha'
24
+ spec.add_dependency 'dry-configurable', '~> 0.12'
24
25
 
25
26
  spec.add_development_dependency 'bundler', '>= 1.6', '< 3'
26
27
  spec.add_development_dependency 'rack-test', '~> 1.0'
27
- spec.add_development_dependency 'rake', '~> 12'
28
- spec.add_development_dependency 'rspec', '~> 3.7'
28
+ spec.add_development_dependency 'rake', '~> 13'
29
+ spec.add_development_dependency 'rspec', '~> 3.9'
29
30
  end
data/lib/hanami/action.rb CHANGED
@@ -1,21 +1,5 @@
1
- begin
2
- require 'hanami/validations'
3
- require 'hanami/action/validatable'
4
- rescue LoadError
5
- end
6
-
7
- require 'hanami/action/request'
8
- require 'hanami/action/response'
9
- require 'hanami/action/base_params'
10
- require 'hanami/action/rack/file'
11
-
12
- require 'rack/utils'
13
- require 'hanami/utils'
14
- require 'hanami/utils/kernel'
15
-
16
- require 'hanami/utils/class_attribute'
17
-
18
- require 'hanami/utils/callbacks'
1
+ require_relative 'action/application_action'
2
+ require_relative 'action/standalone_action'
19
3
 
20
4
  module Hanami
21
5
  # An HTTP endpoint
@@ -33,9 +17,6 @@ module Hanami
33
17
  # end
34
18
  # end
35
19
  class Action
36
- require "hanami/action/mime"
37
- require "hanami/action/halt"
38
-
39
20
  # Rack SPEC response code
40
21
  #
41
22
  # @since 1.0.0
@@ -163,564 +144,24 @@ module Hanami
163
144
  # @api private
164
145
  LOCATION = 'Location'.freeze
165
146
 
166
- # Override Ruby's hook for modules.
167
- # It includes basic Hanami::Action modules to the given class.
168
- #
169
- # @param base [Class] the target action
170
- #
171
- # @since 0.1.0
172
- # @api private
173
- def self.inherited(base)
174
- if base.superclass == Hanami::Action
175
- base.class_eval do
176
- include Utils::ClassAttribute
177
-
178
- class_attribute :before_callbacks
179
- self.before_callbacks = Utils::Callbacks::Chain.new
147
+ include StandaloneAction
180
148
 
181
- class_attribute :after_callbacks
182
- self.after_callbacks = Utils::Callbacks::Chain.new
149
+ def self.inherited(subclass)
150
+ super
183
151
 
184
- include Validatable if defined?(Validatable)
185
- end
152
+ # When inheriting within an Hanami app, and the application provider has
153
+ # changed from the superclass, (re-)configure the action for the provider,
154
+ # i.e. for the slice and/or the application itself
155
+ if (provider = application_provider(subclass)) && provider != application_provider(subclass.superclass)
156
+ subclass.include ApplicationAction.new(provider)
186
157
  end
187
158
  end
188
159
 
189
- # Returns the class which defines the params
190
- #
191
- # Returns the class which has been provided to define the
192
- # params. By default this will be Hanami::Action::Params.
193
- #
194
- # @return [Class] A params class (when whitelisted) or
195
- # Hanami::Action::Params
196
- #
197
- # @api private
198
- # @since 0.7.0
199
- def self.params_class
200
- @params_class ||= BaseParams
201
- end
202
-
203
- # FIXME: make this thread-safe
204
- def self.accepted_formats
205
- @accepted_formats ||= []
206
- end
207
-
208
- # FIXME: make this thread-safe
209
- def self.handled_exceptions
210
- @handled_exceptions ||= {}
211
- end
212
-
213
- # Define a callback for an Action.
214
- # The callback will be executed **before** the action is called, in the
215
- # order they are added.
216
- #
217
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
218
- # each of them is representing a name of a method available in the
219
- # context of the Action.
220
- #
221
- # @param blk [Proc] an anonymous function to be executed
222
- #
223
- # @return [void]
224
- #
225
- # @since 0.3.2
226
- #
227
- # @see Hanami::Action::Callbacks::ClassMethods#append_after
228
- #
229
- # @example Method names (symbols)
230
- # require 'hanami/controller'
231
- #
232
- # class Show
233
- # include Hanami::Action
234
- #
235
- # before :authenticate, :set_article
236
- #
237
- # def call(params)
238
- # end
239
- #
240
- # private
241
- # def authenticate
242
- # # ...
243
- # end
244
- #
245
- # # `params` in the method signature is optional
246
- # def set_article(params)
247
- # @article = Article.find params[:id]
248
- # end
249
- # end
250
- #
251
- # # The order of execution will be:
252
- # #
253
- # # 1. #authenticate
254
- # # 2. #set_article
255
- # # 3. #call
256
- #
257
- # @example Anonymous functions (Procs)
258
- # require 'hanami/controller'
259
- #
260
- # class Show
261
- # include Hanami::Action
262
- #
263
- # before { ... } # 1 do some authentication stuff
264
- # before {|params| @article = Article.find params[:id] } # 2
265
- #
266
- # def call(params)
267
- # end
268
- # end
269
- #
270
- # # The order of execution will be:
271
- # #
272
- # # 1. authentication
273
- # # 2. set the article
274
- # # 3. #call
275
- def self.append_before(*callbacks, &blk)
276
- before_callbacks.append(*callbacks, &blk)
277
- end
278
-
279
- class << self
280
- # @since 0.1.0
281
- alias before append_before
282
- end
283
-
284
- # Define a callback for an Action.
285
- # The callback will be executed **after** the action is called, in the
286
- # order they are added.
287
- #
288
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
289
- # each of them is representing a name of a method available in the
290
- # context of the Action.
291
- #
292
- # @param blk [Proc] an anonymous function to be executed
293
- #
294
- # @return [void]
295
- #
296
- # @since 0.3.2
297
- #
298
- # @see Hanami::Action::Callbacks::ClassMethods#append_before
299
- def self.append_after(*callbacks, &blk)
300
- after_callbacks.append(*callbacks, &blk)
301
- end
302
-
303
- class << self
304
- # @since 0.1.0
305
- alias after append_after
306
- end
307
-
308
- # Define a callback for an Action.
309
- # The callback will be executed **before** the action is called.
310
- # It will add the callback at the beginning of the callbacks' chain.
311
- #
312
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
313
- # each of them is representing a name of a method available in the
314
- # context of the Action.
315
- #
316
- # @param blk [Proc] an anonymous function to be executed
317
- #
318
- # @return [void]
319
- #
320
- # @since 0.3.2
321
- #
322
- # @see Hanami::Action::Callbacks::ClassMethods#prepend_after
323
- def self.prepend_before(*callbacks, &blk)
324
- before_callbacks.prepend(*callbacks, &blk)
325
- end
326
-
327
- # Define a callback for an Action.
328
- # The callback will be executed **after** the action is called.
329
- # It will add the callback at the beginning of the callbacks' chain.
330
- #
331
- # @param callbacks [Symbol, Array<Symbol>] a single or multiple symbol(s)
332
- # each of them is representing a name of a method available in the
333
- # context of the Action.
334
- #
335
- # @param blk [Proc] an anonymous function to be executed
336
- #
337
- # @return [void]
338
- #
339
- # @since 0.3.2
340
- #
341
- # @see Hanami::Action::Callbacks::ClassMethods#prepend_before
342
- def self.prepend_after(*callbacks, &blk)
343
- after_callbacks.prepend(*callbacks, &blk)
344
- end
345
-
346
- # Restrict the access to the specified mime type symbols.
347
- #
348
- # @param formats[Array<Symbol>] one or more symbols representing mime type(s)
349
- #
350
- # @raise [Hanami::Controller::UnknownFormatError] if the symbol cannot
351
- # be converted into a mime type
352
- #
353
- # @since 0.1.0
354
- #
355
- # @see Hanami::Controller::Configuration#format
356
- #
357
- # @example
358
- # require 'hanami/controller'
359
- #
360
- # class Show
361
- # include Hanami::Action
362
- # accept :html, :json
363
- #
364
- # def call(params)
365
- # # ...
366
- # end
367
- # end
368
- #
369
- # # When called with "*/*" => 200
370
- # # When called with "text/html" => 200
371
- # # When called with "application/json" => 200
372
- # # When called with "application/xml" => 406
373
- def self.accept(*formats)
374
- @accepted_formats = *formats
375
- before :enforce_accepted_mime_types
376
- end
377
-
378
- # Handle the given exception with an HTTP status code.
379
- #
380
- # When the exception is raise during #call execution, it will be
381
- # translated into the associated HTTP status.
382
- #
383
- # This is a fine grained control, for a global configuration see
384
- # Hanami::Action.handled_exceptions
385
- #
386
- # @param exception [Hash] the exception class must be the key and the
387
- # HTTP status the value of the hash
388
- #
389
- # @since 0.1.0
390
- #
391
- # @see Hanami::Action.handled_exceptions
392
- #
393
- # @example
394
- # require 'hanami/controller'
395
- #
396
- # class Show
397
- # include Hanami::Action
398
- # handle_exception RecordNotFound => 404
399
- #
400
- # def call(params)
401
- # # ...
402
- # raise RecordNotFound.new
403
- # end
404
- # end
405
- #
406
- # Show.new.call({id: 1}) # => [404, {}, ['Not Found']]
407
- def self.handle_exception(exception)
408
- handled_exceptions.merge!(exception)
409
- end
410
-
411
- # Callbacks API instance methods
412
- #
413
- # @since 0.1.0
414
- # @api private
415
- def self.new(configuration:, **args)
416
- allocate.tap do |obj|
417
- obj.instance_variable_set(:@configuration, configuration)
418
- obj.instance_variable_set(:@accepted_mime_types, Mime.restrict_mime_types(configuration, accepted_formats))
419
- obj.instance_variable_set(
420
- :@handled_exceptions,
421
- ::Hash[
422
- configuration
423
- .handled_exceptions
424
- .merge(handled_exceptions)
425
- .sort{ |(ex1,_),(ex2,_)| ex1.ancestors.include?(ex2) ? -1 : 1 }
426
- ]
427
- )
428
- obj.send(:initialize, **args)
429
- obj.freeze
160
+ def self.application_provider(subclass)
161
+ if Hanami.respond_to?(:application?) && Hanami.application?
162
+ Hanami.application.component_provider(subclass)
430
163
  end
431
164
  end
432
-
433
- # Implements the Rack/Hanami::Action protocol
434
- #
435
- # @since 0.1.0
436
- # @api private
437
- def call(env)
438
- request = nil
439
- response = nil
440
-
441
- halted = catch :halt do
442
- begin
443
- params = self.class.params_class.new(env)
444
- request = Hanami::Action::Request.new(env, params)
445
- response = Hanami::Action::Response.new(action: self.class.name, configuration: configuration, content_type: Mime.calculate_content_type_with_charset(configuration, request, accepted_mime_types), env: env, header: configuration.default_headers)
446
- _run_before_callbacks(request, response)
447
- handle(request, response)
448
- _run_after_callbacks(request, response)
449
- rescue => exception
450
- _handle_exception(request, response, exception)
451
- end
452
- end
453
-
454
- finish(request, response, halted)
455
- end
456
-
457
- def initialize(**)
458
- end
459
-
460
- protected
461
-
462
- def handle(request, response)
463
- end
464
-
465
- # Halt the action execution with the given HTTP status code and message.
466
- #
467
- # When used, the execution of a callback or of an action is interrupted
468
- # and the control returns to the framework, that decides how to handle
469
- # the event.
470
- #
471
- # If a message is provided, it sets the response body with the message.
472
- # Otherwise, it sets the response body with the default message associated
473
- # to the code (eg 404 will set `"Not Found"`).
474
- #
475
- # @param status [Fixnum] a valid HTTP status code
476
- # @param body [String] the response body
477
- #
478
- # @raise [StandardError] if the code isn't valid
479
- #
480
- # @since 0.2.0
481
- #
482
- # @see Hanami::Controller#handled_exceptions
483
- # @see Hanami::Action::Throwable#handle_exception
484
- # @see Hanami::Http::Status:ALL
485
- #
486
- # @example Basic usage
487
- # require 'hanami/controller'
488
- #
489
- # class Show
490
- # def call(params)
491
- # halt 404
492
- # end
493
- # end
494
- #
495
- # # => [404, {}, ["Not Found"]]
496
- #
497
- # @example Custom message
498
- # require 'hanami/controller'
499
- #
500
- # class Show
501
- # def call(params)
502
- # halt 404, "This is not the droid you're looking for."
503
- # end
504
- # end
505
- #
506
- # # => [404, {}, ["This is not the droid you're looking for."]]
507
- def halt(status, body = nil)
508
- Halt.call(status, body)
509
- end
510
-
511
- # @since 0.3.2
512
- # @api private
513
- def _requires_no_body?(res)
514
- HTTP_STATUSES_WITHOUT_BODY.include?(res.status)
515
- end
516
-
517
- # @since 2.0.0
518
- # @api private
519
- def _requires_empty_headers?(res)
520
- _requires_no_body?(res) || res.head?
521
- end
522
-
523
- private
524
-
525
- attr_reader :configuration
526
-
527
- def accepted_mime_types
528
- @accepted_mime_types || configuration.mime_types
529
- end
530
-
531
- def enforce_accepted_mime_types(req, *)
532
- Mime.accepted_mime_type?(req, accepted_mime_types, configuration) or halt 406
533
- end
534
-
535
- attr_reader :handled_exceptions
536
-
537
- def exception_handler(exception)
538
- handled_exceptions.each do |exception_class, handler|
539
- return handler if exception.kind_of?(exception_class)
540
- end
541
-
542
- nil
543
- end
544
-
545
- # @since 0.2.0
546
- # @api private
547
- def _reference_in_rack_errors(req, exception)
548
- req.env[RACK_EXCEPTION] = exception
549
-
550
- if errors = req.env[RACK_ERRORS]
551
- errors.write(_dump_exception(exception))
552
- errors.flush
553
- end
554
- end
555
-
556
- # @since 0.2.0
557
- # @api private
558
- def _dump_exception(exception)
559
- [[exception.class, exception.message].compact.join(": "), *exception.backtrace].join("\n\t")
560
- end
561
-
562
- # @since 0.1.0
563
- # @api private
564
- def _handle_exception(req, res, exception)
565
- handler = exception_handler(exception)
566
-
567
- if handler.nil?
568
- _reference_in_rack_errors(req, exception)
569
- raise exception
570
- end
571
-
572
- instance_exec(
573
- req,
574
- res,
575
- exception,
576
- &_exception_handler(handler)
577
- )
578
-
579
- nil
580
- end
581
-
582
- # @since 0.3.0
583
- # @api private
584
- def _exception_handler(handler)
585
- if respond_to?(handler.to_s, true)
586
- method(handler)
587
- else
588
- ->(*) { halt handler }
589
- end
590
- end
591
-
592
- # @since 0.1.0
593
- # @api private
594
- def _run_before_callbacks(*args)
595
- self.class.before_callbacks.run(self, *args)
596
- nil
597
- end
598
-
599
- # @since 0.1.0
600
- # @api private
601
- def _run_after_callbacks(*args)
602
- self.class.after_callbacks.run(self, *args)
603
- nil
604
- end
605
-
606
- # According to RFC 2616, when a response MUST have an empty body, it only
607
- # allows Entity Headers.
608
- #
609
- # For instance, a <tt>204</tt> doesn't allow <tt>Content-Type</tt> or any
610
- # other custom header.
611
- #
612
- # This restriction is enforced by <tt>Hanami::Action#_requires_no_body?</tt>.
613
- #
614
- # However, there are cases that demand to bypass this rule to set meta
615
- # informations via headers.
616
- #
617
- # An example is a <tt>DELETE</tt> request for a JSON API application.
618
- # It returns a <tt>204</tt> but still wants to specify the rate limit
619
- # quota via <tt>X-Rate-Limit</tt>.
620
- #
621
- # @since 0.5.0
622
- #
623
- # @see Hanami::Action#_requires_no_body?
624
- #
625
- # @example
626
- # require 'hanami/controller'
627
- #
628
- # module Books
629
- # class Destroy
630
- # include Hanami::Action
631
- #
632
- # def call(params)
633
- # # ...
634
- # self.headers.merge!(
635
- # 'Last-Modified' => 'Fri, 27 Nov 2015 13:32:36 GMT',
636
- # 'X-Rate-Limit' => '4000',
637
- # 'Content-Type' => 'application/json',
638
- # 'X-No-Pass' => 'true'
639
- # )
640
- #
641
- # self.status = 204
642
- # end
643
- #
644
- # private
645
- #
646
- # def keep_response_header?(header)
647
- # super || header == 'X-Rate-Limit'
648
- # end
649
- # end
650
- # end
651
- #
652
- # # Only the following headers will be sent:
653
- # # * Last-Modified - because we used `super' in the method that respects the HTTP RFC
654
- # # * X-Rate-Limit - because we explicitely allow it
655
- #
656
- # # Both Content-Type and X-No-Pass are removed because they're not allowed
657
- def keep_response_header?(header)
658
- ENTITY_HEADERS.include?(header)
659
- end
660
-
661
- # @since 2.0.0
662
- # @api private
663
- def _empty_headers(res)
664
- res.headers.select! { |header, _| keep_response_header?(header) }
665
- end
666
-
667
- def format(value)
668
- case value
669
- when Symbol
670
- format = Utils::Kernel.Symbol(value)
671
- [format, Action::Mime.format_to_mime_type(format, configuration)]
672
- when String
673
- [Action::Mime.detect_format(value, configuration), value]
674
- else
675
- raise Hanami::Controller::UnknownFormatError.new(value)
676
- end
677
- end
678
-
679
- # Raise error when `Hanami::Action::Session` isn't included.
680
- #
681
- # To use `session`, include `Hanami::Action::Session`.
682
- #
683
- # @raise [Hanami::Controller::MissingSessionError]
684
- #
685
- # @since 1.2.0
686
- def session
687
- raise Hanami::Controller::MissingSessionError.new(:session)
688
- end
689
-
690
- # Raise error when `Hanami::Action::Session` isn't included.
691
- #
692
- # To use `flash`, include `Hanami::Action::Session`.
693
- #
694
- # @raise [Hanami::Controller::MissingSessionError]
695
- #
696
- # @since 1.2.0
697
- def flash
698
- raise Hanami::Controller::MissingSessionError.new(:flash)
699
- end
700
-
701
- # Finalize the response
702
- #
703
- # This method is abstract and COULD be implemented by included modules in
704
- # order to prepare their data before the response will be returned to the
705
- # webserver.
706
- #
707
- # @since 0.1.0
708
- # @api private
709
- # @abstract
710
- #
711
- # @see Hanami::Action::Callable#finish
712
- # @see Hanami::Action::Session#finish
713
- # @see Hanami::Action::Cookies#finish
714
- # @see Hanami::Action::Cache#finish
715
- def finish(req, res, halted)
716
- res.status, res.body = *halted unless halted.nil?
717
-
718
- _empty_headers(res) if _requires_empty_headers?(res)
719
-
720
- res.set_format(Action::Mime.detect_format(res.content_type, configuration))
721
- res[:params] = req.params
722
- res[:format] = res.format
723
- res
724
- end
165
+ private_class_method :application_provider
725
166
  end
726
167
  end