hanami-router 2.0.0 → 2.0.1

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: 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