hanami-router 2.0.0 → 2.0.1

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: d1d74dfb9252f6462cb018bd567261aad94f83ea6837bb78f3d597dd9b62d0c5
4
- data.tar.gz: 30c7f9425d0ad82d0c3059ed8a2d8fcc5e1a1a11092caf5f725338748451fddc
3
+ metadata.gz: d211b5c2f94d5e609ae9de76707c3740d387771f0864fab1d8a04f1f81942663
4
+ data.tar.gz: 354ce7d52713736379e88271b84e930b6b203299a355e9568c64572380286efe
5
5
  SHA512:
6
- metadata.gz: 1f351789e9d4f24ef65cfdb6e19868e56c612b2f222dfd2f250f15bddfdcf00fb9d7146a5b4bd978fa2cf5b067b2dc1a96f9cf0430f028240a4c6543075cd0a1
7
- data.tar.gz: 7019f2ef7c57177041495e7614992b117548d5d0eeace16d4784a9dc07b678d1d49e0987a6f750fd51b342cd5b86136fe393cef2d1fa126250a07ff8887bc1fe
6
+ metadata.gz: e8ef3013b9ec171da3eeef8ee92564cc55ad010c62a2133a386325c31ee2501331a92808b37503671d4b75b8d0a8d5eb38ce0bac7b24099bffea689f14cc51e0
7
+ data.tar.gz: bdf66d398a5e1f32b279ffb22cb4ba6719b2565631880a18e4e2d82469b293930b0f29265d483495d7b7c23dfe4b842aa0cadb34a083d32bad945a2bfc4e8100
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  Rack compatible HTTP router for Ruby
4
4
 
5
+ ## v2.0.1 - 2022-12-06
6
+
7
+ ### Added
8
+
9
+ - [Armin, Luca Guidi] Introduce `Hanami::Middleware::BodyParser::FormParser` to parse multipart file upload
10
+
11
+ ### Fixed
12
+
13
+ - [Luca Guidi] Return HTTP response header `Allow` when returning `405` HTTP status
14
+
5
15
  ## v2.0.0 - 2022-11-22
6
16
 
7
17
  ### Fixed
data/README.md CHANGED
@@ -331,22 +331,22 @@ curl http://localhost:2300/authors/1 \
331
331
  require "hanami/router"
332
332
 
333
333
  router = Hanami::Router.new do
334
- get "/books/:id", to: "books#show", as: :book
334
+ get "/books/:id", to: "books.show", as: :book
335
335
  end
336
336
 
337
337
  route = router.recognize("/books/23")
338
338
  route.verb # "GET"
339
- route.action # => "books#show"
339
+ route.endpoint # => "books.show"
340
340
  route.params # => {:id=>"23"}
341
341
  route.routable? # => true
342
342
 
343
343
  route = router.recognize(:book, id: 23)
344
344
  route.verb # "GET"
345
- route.action # => "books#show"
345
+ route.endpoint # => "books.show"
346
346
  route.params # => {:id=>"23"}
347
347
  route.routable? # => true
348
348
 
349
- route = router.recognize("/books/23", method: :post)
349
+ route = router.recognize("/books/23", {}, method: :post)
350
350
  route.verb # "POST"
351
351
  route.routable? # => false
352
352
  ```
@@ -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 "mustermann", "~> 1.0"
25
- spec.add_dependency "mustermann-contrib", "~> 1.0"
24
+ spec.add_dependency "mustermann", "~> 3.0"
25
+ spec.add_dependency "mustermann-contrib", "~> 3.0"
26
26
 
27
27
  spec.add_development_dependency "bundler", ">= 1.6", "< 3"
28
28
  spec.add_development_dependency "rake", "~> 13"
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "parser"
4
+ require "rack/multipart"
5
+
6
+ module Hanami
7
+ module Middleware
8
+ class BodyParser
9
+ # @since 2.0.1
10
+ # @api private
11
+ class FormParser < Parser
12
+ # @since 2.0.1
13
+ # @api private
14
+ MIME_TYPES = [
15
+ "multipart/form-data"
16
+ ].freeze
17
+
18
+ # @since 2.0.1
19
+ # @api private
20
+ def self.mime_types
21
+ MIME_TYPES
22
+ end
23
+
24
+ # Parse a multipart body payload (form file uploading)
25
+ #
26
+ # @param body [String] a multipart body
27
+ #
28
+ # @return [Hash] the parsed multipart body
29
+ #
30
+ # @raise [Hanami::Middleware::BodyParser::BodyParsingError] when the body can't be parsed.
31
+ #
32
+ # @since 2.0.1
33
+ # @api private
34
+ def parse(*, env)
35
+ ::Rack::Multipart.parse_multipart(env)
36
+ rescue StandardError => exception
37
+ raise BodyParsingError.new(exception.message)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -25,7 +25,7 @@ module Hanami
25
25
  #
26
26
  # @since 1.3.0
27
27
  # @api private
28
- def parse(body)
28
+ def parse(body, *)
29
29
  JSON.parse(body)
30
30
  rescue StandardError => exception
31
31
  raise BodyParsingError.new(exception.message)
@@ -34,6 +34,7 @@ module Hanami
34
34
  # Parse raw HTTP request body
35
35
  #
36
36
  # @param body [String] HTTP request body
37
+ # @param env [Hash] Rack env
37
38
  #
38
39
  # @return [Hash] the result of the parsing
39
40
  #
@@ -54,7 +55,7 @@ module Hanami
54
55
  # raise Hanami::Middleware::BodyParser::BodyParsingError.new(exception.message)
55
56
  # end
56
57
  # end
57
- def parse(body) # rubocop:disable Lint/UnusedMethodArgument
58
+ def parse(body, env = {}) # rubocop:disable Lint/UnusedMethodArgument
58
59
  raise NoMethodError
59
60
  end
60
61
  end
@@ -45,7 +45,7 @@ module Hanami
45
45
  env[RACK_INPUT].rewind # somebody might try to read this stream
46
46
 
47
47
  if (parser = @parsers[media_type(env)])
48
- env[Router::ROUTER_PARSED_BODY] = parser.parse(body)
48
+ env[Router::ROUTER_PARSED_BODY] = parser.parse(body, env)
49
49
  env[ROUTER_PARAMS] = _symbolize(env[Router::ROUTER_PARSED_BODY])
50
50
  end
51
51
 
@@ -6,7 +6,8 @@ module Hanami
6
6
  #
7
7
  # @return [String]
8
8
  #
9
+ # @since 0.1.0
9
10
  # @api public
10
- VERSION = "2.0.0"
11
+ VERSION = "2.0.1"
11
12
  end
12
13
  end
data/lib/hanami/router.rb CHANGED
@@ -652,10 +652,15 @@ module Hanami
652
652
  # @since 2.0.0
653
653
  # @api private
654
654
  def not_allowed(env)
655
- (_not_allowed_fixed(env) ||
656
- _not_allowed_variable(env)) and return [HTTP_STATUS_NOT_ALLOWED,
657
- {::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH},
658
- [HTTP_BODY_NOT_ALLOWED]]
655
+ http_methods = _not_allowed_fixed(env) || _not_allowed_variable(env)
656
+ return if http_methods.nil?
657
+
658
+ [HTTP_STATUS_NOT_ALLOWED,
659
+ {
660
+ ::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH,
661
+ "Allow" => http_methods.join(", ")
662
+ },
663
+ [HTTP_BODY_NOT_ALLOWED]]
659
664
  end
660
665
 
661
666
  # @since 2.0.0
@@ -934,28 +939,32 @@ module Hanami
934
939
  # @since 2.0.0
935
940
  # @api private
936
941
  def _not_allowed_fixed(env)
937
- found = false
942
+ found = []
938
943
 
939
- @fixed.each_value do |routes|
940
- break if found
944
+ @fixed.each do |http_method, routes|
945
+ next if routes.fetch(env[::Rack::PATH_INFO], nil).nil?
941
946
 
942
- found = routes.key?(env[::Rack::PATH_INFO])
947
+ found << http_method
943
948
  end
944
949
 
950
+ return nil if found.empty?
951
+
945
952
  found
946
953
  end
947
954
 
948
955
  # @since 2.0.0
949
956
  # @api private
950
957
  def _not_allowed_variable(env)
951
- found = false
958
+ found = []
952
959
 
953
- @variable.each_value do |routes|
954
- break if found
960
+ @variable.each do |http_method, routes|
961
+ next if routes.find(env[::Rack::PATH_INFO]).nil?
955
962
 
956
- found = routes.find(env[::Rack::PATH_INFO])
963
+ found << http_method
957
964
  end
958
965
 
966
+ return nil if found.empty?
967
+
959
968
  found
960
969
  end
961
970
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-22 00:00:00.000000000 Z
11
+ date: 2022-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.0'
33
+ version: '3.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.0'
40
+ version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mustermann-contrib
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.0'
47
+ version: '3.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.0'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -157,6 +157,7 @@ files:
157
157
  - lib/hanami/middleware/body_parser.rb
158
158
  - lib/hanami/middleware/body_parser/class_interface.rb
159
159
  - lib/hanami/middleware/body_parser/errors.rb
160
+ - lib/hanami/middleware/body_parser/form_parser.rb
160
161
  - lib/hanami/middleware/body_parser/json_parser.rb
161
162
  - lib/hanami/middleware/body_parser/parser.rb
162
163
  - lib/hanami/middleware/error.rb
@@ -199,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
200
  - !ruby/object:Gem::Version
200
201
  version: '0'
201
202
  requirements: []
202
- rubygems_version: 3.3.7
203
+ rubygems_version: 3.3.3
203
204
  signing_key:
204
205
  specification_version: 4
205
206
  summary: Rack compatible HTTP router for Ruby and Hanami