hanami-router 3.0.0.rc1 → 3.0.0
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 +4 -4
- data/CHANGELOG.md +25 -3
- data/lib/hanami/router/constants.rb +3 -1
- data/lib/hanami/router/version.rb +1 -1
- data/lib/hanami/router.rb +38 -12
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 30cf4c77a2d61c1f8c8817c19db6bd5089627a6639dbda3f6b44441433516a67
|
|
4
|
+
data.tar.gz: a79a9f499cbd4746adc14e70dd9aeff68aad669cbdb3109bab7501264e5930ab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d08ff095875e2e7a24d4b3663344e6aa0cb3de17bd41ed22c809588a361f28bc9f1f1ffd0ccd1933bb35c88b78a330bbfc9a4aa178cd661202657cae56ce6d13
|
|
7
|
+
data.tar.gz: e6ca075b83151a66a015ba99c2120ee45bd35fe338cb4f7feb6d82e772eab60a8116ea4ee4fa90629c8e6e79cd2b17c867630916b9a5c3a0ac3154eabed1be77
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Break Versioning](https://www.taoensso.com/break-versioning).
|
|
4
7
|
|
|
5
8
|
## [Unreleased]
|
|
6
9
|
|
|
@@ -16,7 +19,26 @@ Rack compatible HTTP router for Ruby.
|
|
|
16
19
|
|
|
17
20
|
### Security
|
|
18
21
|
|
|
19
|
-
[Unreleased]: http://github.com/hanami/hanami-router/compare/v3.0.0
|
|
22
|
+
[Unreleased]: http://github.com/hanami/hanami-router/compare/v3.0.0...HEAD
|
|
23
|
+
|
|
24
|
+
## [3.0.0] - 2026-06-30
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Add `#permanent_redirect` and `#temporary_redirect` helpers for 301 and 302 responses. (@cllns in #302)
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- **BREAKING:** `#redirect` now requires an explicit `code:` argument. Use `#permanent_redirect` or `#temporary_redirect` for the common cases, and pass `code:` to `#redirect` for less common codes (e.g. `303`, `307`, `308`). (@cllns in #302)
|
|
33
|
+
- Upgrade mustermann to 3.1 and remove mustermann-contrib dependency. (@rkh in #300)
|
|
34
|
+
- Require Ruby 3.3 or newer.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- Only parse the request body into params when the content type is `application/x-www-form-urlencoded`. Previously, with no body parser middleware in use, posting a multipart upload (or other non-form body) could raise `Rack::QueryParser::InvalidParameterError`. (@cllns and @timriley in #305)
|
|
39
|
+
- Allow URL generation (via `#path`) to work with array variables. (@inouire in #304)
|
|
40
|
+
|
|
41
|
+
[3.0.0]: http://github.com/hanami/hanami-router/compare/v2.3.1...v3.0.0
|
|
20
42
|
|
|
21
43
|
## [3.0.0.rc1] - 2026-06-16
|
|
22
44
|
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Hanami
|
|
4
4
|
class Router
|
|
5
|
+
# Rack env key containing the request body as parsed by the body parser middleware. Signals that
|
|
6
|
+
# the body has already been parsed, so the router should not attempt to parse it again.
|
|
7
|
+
#
|
|
5
8
|
# @api private
|
|
6
|
-
# @since 2.0.0
|
|
7
9
|
ROUTER_PARSED_BODY = "router.parsed_body"
|
|
8
10
|
end
|
|
9
11
|
end
|
data/lib/hanami/router.rb
CHANGED
|
@@ -113,9 +113,7 @@ module Hanami
|
|
|
113
113
|
env[::Rack::RACK_INPUT] = Rack::RewindableInput.new(input)
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
-
endpoint.call(
|
|
117
|
-
_params(env, params)
|
|
118
|
-
).to_a
|
|
116
|
+
endpoint.call(_env_with_params(env, params)).to_a
|
|
119
117
|
end
|
|
120
118
|
|
|
121
119
|
# Defines a named root route (a GET route for "/")
|
|
@@ -684,7 +682,7 @@ module Hanami
|
|
|
684
682
|
env = env_for(env, params, options)
|
|
685
683
|
endpoint, params = lookup(env)
|
|
686
684
|
|
|
687
|
-
RecognizedRoute.new(endpoint,
|
|
685
|
+
RecognizedRoute.new(endpoint, _env_with_params(env, params))
|
|
688
686
|
end
|
|
689
687
|
|
|
690
688
|
# @since 2.0.0
|
|
@@ -777,7 +775,6 @@ module Hanami
|
|
|
777
775
|
# @api private
|
|
778
776
|
PREFIXED_NAME_SEPARATOR = "_"
|
|
779
777
|
|
|
780
|
-
# @since x.x.x
|
|
781
778
|
# @api private
|
|
782
779
|
UNDERSCORED_NAME_REGEXP = /[-+~.]/
|
|
783
780
|
|
|
@@ -789,6 +786,9 @@ module Hanami
|
|
|
789
786
|
# @api private
|
|
790
787
|
EMPTY_STRING = ""
|
|
791
788
|
|
|
789
|
+
# @api private
|
|
790
|
+
EMPTY_HASH = {}.freeze
|
|
791
|
+
|
|
792
792
|
# @since 2.0.0
|
|
793
793
|
# @api private
|
|
794
794
|
DEFAULT_RESOLVER = ->(_, to) { to }
|
|
@@ -841,6 +841,15 @@ module Hanami
|
|
|
841
841
|
# @api private
|
|
842
842
|
PARAMS = "router.params"
|
|
843
843
|
|
|
844
|
+
# @api private
|
|
845
|
+
CONTENT_TYPE = "CONTENT_TYPE"
|
|
846
|
+
|
|
847
|
+
# @api private
|
|
848
|
+
FORM_URLENCODED_MEDIA_TYPE = "application/x-www-form-urlencoded"
|
|
849
|
+
|
|
850
|
+
# @api private
|
|
851
|
+
FORM_URLENCODED_MEDIA_TYPE_PREFIX = "#{FORM_URLENCODED_MEDIA_TYPE};".freeze
|
|
852
|
+
|
|
844
853
|
# @since 2.0.0
|
|
845
854
|
# @api private
|
|
846
855
|
ROUTE_VARIABLE_MATCHER = /:/
|
|
@@ -1034,17 +1043,12 @@ module Hanami
|
|
|
1034
1043
|
Redirect.new(destination, code, ->(*) { [code, {HTTP_HEADER_LOCATION => destination}, [body]] })
|
|
1035
1044
|
end
|
|
1036
1045
|
|
|
1037
|
-
# @since 2.0.0
|
|
1038
1046
|
# @api private
|
|
1039
|
-
def
|
|
1047
|
+
def _env_with_params(env, params)
|
|
1040
1048
|
params ||= {}
|
|
1041
1049
|
env[PARAMS] ||= {}
|
|
1042
1050
|
|
|
1043
|
-
|
|
1044
|
-
env[PARAMS].merge!(::Rack::Utils.parse_nested_query(input.read))
|
|
1045
|
-
input.rewind
|
|
1046
|
-
end
|
|
1047
|
-
|
|
1051
|
+
env[PARAMS].merge!(_form_urlencoded_body(env))
|
|
1048
1052
|
env[PARAMS].merge!(::Rack::Utils.parse_nested_query(env[::Rack::QUERY_STRING]))
|
|
1049
1053
|
env[PARAMS].merge!(params)
|
|
1050
1054
|
env[PARAMS] = Params.deep_symbolize(env[PARAMS])
|
|
@@ -1052,6 +1056,28 @@ module Hanami
|
|
|
1052
1056
|
env
|
|
1053
1057
|
end
|
|
1054
1058
|
|
|
1059
|
+
# @api private
|
|
1060
|
+
def _form_urlencoded_body(env)
|
|
1061
|
+
return EMPTY_HASH if env.key?(ROUTER_PARSED_BODY)
|
|
1062
|
+
return EMPTY_HASH unless _form_urlencoded?(env)
|
|
1063
|
+
return EMPTY_HASH unless (input = env[::Rack::RACK_INPUT])
|
|
1064
|
+
|
|
1065
|
+
input.rewind
|
|
1066
|
+
body = ::Rack::Utils.parse_nested_query(input.read)
|
|
1067
|
+
input.rewind # leave the stream readable for downstream consumers
|
|
1068
|
+
body
|
|
1069
|
+
end
|
|
1070
|
+
|
|
1071
|
+
# @api private
|
|
1072
|
+
def _form_urlencoded?(env)
|
|
1073
|
+
content_type = env[CONTENT_TYPE]
|
|
1074
|
+
return false unless content_type
|
|
1075
|
+
|
|
1076
|
+
content_type = content_type.downcase
|
|
1077
|
+
content_type == FORM_URLENCODED_MEDIA_TYPE ||
|
|
1078
|
+
content_type.start_with?(FORM_URLENCODED_MEDIA_TYPE_PREFIX)
|
|
1079
|
+
end
|
|
1080
|
+
|
|
1055
1081
|
# @since 2.0.0
|
|
1056
1082
|
# @api private
|
|
1057
1083
|
def _not_allowed_fixed(env)
|