hanami-router 2.0.0.rc1 → 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: dc0a68636ae47869944fc0c76f262c420356d3fbf10bd12b270692f48d3ea7bb
4
- data.tar.gz: cb653be9037e33f02a05bcbf2048109d64e561afafaa03c8ed353b4b3183d672
3
+ metadata.gz: d211b5c2f94d5e609ae9de76707c3740d387771f0864fab1d8a04f1f81942663
4
+ data.tar.gz: 354ce7d52713736379e88271b84e930b6b203299a355e9568c64572380286efe
5
5
  SHA512:
6
- metadata.gz: 4e50ba3c0279d9c26a1ef882127ef7d02ca39cb5ebab25589799ab7190e4562a40e57d0dcbcfe285b1e9dc7ab312dedc0ebf2553d4da3afc921821a8d23cc233
7
- data.tar.gz: b6f390eb1750d6e596bb1064573467fbd8d5ceccb3bbf0e34a8ab021dd1162d4fc88a8edee4d36a221d053a8ee3d656114004ac6ebbb9b87fc43636bd8715004
6
+ metadata.gz: e8ef3013b9ec171da3eeef8ee92564cc55ad010c62a2133a386325c31ee2501331a92808b37503671d4b75b8d0a8d5eb38ce0bac7b24099bffea689f14cc51e0
7
+ data.tar.gz: bdf66d398a5e1f32b279ffb22cb4ba6719b2565631880a18e4e2d82469b293930b0f29265d483495d7b7c23dfe4b842aa0cadb34a083d32bad945a2bfc4e8100
data/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
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
+
15
+ ## v2.0.0 - 2022-11-22
16
+
17
+ ### Fixed
18
+
19
+ - [Luca Guidi] Don't parse request body when Body Parser already parsed it
20
+
5
21
  ## v2.0.0.rc1 - 2022-11-08
6
22
 
7
23
  ### 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
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "hanami/router/params"
4
4
  require "hanami/middleware/error"
5
+ require_relative "../router/constants"
5
6
 
6
7
  module Hanami
7
8
  module Middleware
@@ -27,9 +28,6 @@ module Hanami
27
28
  # @api private
28
29
  ROUTER_PARAMS = "router.params"
29
30
 
30
- # @api private
31
- ROUTER_PARSED_BODY = "router.parsed_body"
32
-
33
31
  # @api private
34
32
  FALLBACK_KEY = "_"
35
33
 
@@ -47,8 +45,8 @@ module Hanami
47
45
  env[RACK_INPUT].rewind # somebody might try to read this stream
48
46
 
49
47
  if (parser = @parsers[media_type(env)])
50
- env[ROUTER_PARSED_BODY] = parser.parse(body)
51
- env[ROUTER_PARAMS] = _symbolize(env[ROUTER_PARSED_BODY])
48
+ env[Router::ROUTER_PARSED_BODY] = parser.parse(body, env)
49
+ env[ROUTER_PARAMS] = _symbolize(env[Router::ROUTER_PARSED_BODY])
52
50
  end
53
51
 
54
52
  @app.call(env)
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ class Router
5
+ # @api private
6
+ # @since 2.0.0
7
+ ROUTER_PARSED_BODY = "router.parsed_body"
8
+ end
9
+ end
@@ -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.rc1"
11
+ VERSION = "2.0.1"
11
12
  end
12
13
  end
data/lib/hanami/router.rb CHANGED
@@ -10,6 +10,7 @@ module Hanami
10
10
  # @since 0.1.0
11
11
  class Router
12
12
  require "hanami/router/version"
13
+ require "hanami/router/constants"
13
14
  require "hanami/router/errors"
14
15
  require "hanami/router/segment"
15
16
  require "hanami/router/redirect"
@@ -651,10 +652,15 @@ module Hanami
651
652
  # @since 2.0.0
652
653
  # @api private
653
654
  def not_allowed(env)
654
- (_not_allowed_fixed(env) ||
655
- _not_allowed_variable(env)) and return [HTTP_STATUS_NOT_ALLOWED,
656
- {::Rack::CONTENT_LENGTH => HTTP_BODY_NOT_ALLOWED_LENGTH},
657
- [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]]
658
664
  end
659
665
 
660
666
  # @since 2.0.0
@@ -919,7 +925,7 @@ module Hanami
919
925
  params ||= {}
920
926
  env[PARAMS] ||= {}
921
927
 
922
- if (input = env[::Rack::RACK_INPUT]) and input.rewind
928
+ if !env.key?(ROUTER_PARSED_BODY) && (input = env[::Rack::RACK_INPUT]) and input.rewind
923
929
  env[PARAMS].merge!(::Rack::Utils.parse_nested_query(input.read))
924
930
  input.rewind
925
931
  end
@@ -933,28 +939,32 @@ module Hanami
933
939
  # @since 2.0.0
934
940
  # @api private
935
941
  def _not_allowed_fixed(env)
936
- found = false
942
+ found = []
937
943
 
938
- @fixed.each_value do |routes|
939
- break if found
944
+ @fixed.each do |http_method, routes|
945
+ next if routes.fetch(env[::Rack::PATH_INFO], nil).nil?
940
946
 
941
- found = routes.key?(env[::Rack::PATH_INFO])
947
+ found << http_method
942
948
  end
943
949
 
950
+ return nil if found.empty?
951
+
944
952
  found
945
953
  end
946
954
 
947
955
  # @since 2.0.0
948
956
  # @api private
949
957
  def _not_allowed_variable(env)
950
- found = false
958
+ found = []
951
959
 
952
- @variable.each_value do |routes|
953
- break if found
960
+ @variable.each do |http_method, routes|
961
+ next if routes.find(env[::Rack::PATH_INFO]).nil?
954
962
 
955
- found = routes.find(env[::Rack::PATH_INFO])
963
+ found << http_method
956
964
  end
957
965
 
966
+ return nil if found.empty?
967
+
958
968
  found
959
969
  end
960
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.rc1
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-08 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
@@ -164,6 +165,7 @@ files:
164
165
  - lib/hanami/middleware/trie.rb
165
166
  - lib/hanami/router.rb
166
167
  - lib/hanami/router/block.rb
168
+ - lib/hanami/router/constants.rb
167
169
  - lib/hanami/router/errors.rb
168
170
  - lib/hanami/router/formatter/csv.rb
169
171
  - lib/hanami/router/formatter/human_friendly.rb
@@ -194,9 +196,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
196
  version: '3.0'
195
197
  required_rubygems_version: !ruby/object:Gem::Requirement
196
198
  requirements:
197
- - - ">"
199
+ - - ">="
198
200
  - !ruby/object:Gem::Version
199
- version: 1.3.1
201
+ version: '0'
200
202
  requirements: []
201
203
  rubygems_version: 3.3.3
202
204
  signing_key: