hanami-router 2.0.0.rc1 → 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: 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: