hanami-controller 2.0.0.alpha1 → 2.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
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