hanami-router 2.3.0 → 2.3.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: 5bc038728052f6719d7a3c7ecfbfbb02a5b5d730ab95bafdb1a8415602faa861
4
- data.tar.gz: 961ad5a29c273a42526261c5305d41dc21530c16baf20ed01c106ab7c8b635ff
3
+ metadata.gz: c9a6b9498cdc6f09a3792b52accbe0fda997f5de907fb0e523408a0a8437465c
4
+ data.tar.gz: 40fc3193dcd6e471f1464852844456748f1ef8deb53ad630290e1343abdfbbbd
5
5
  SHA512:
6
- metadata.gz: 723502c7e0e4dd4beba5de8a1c3e77dd8e912103f833dc709f7c8f001702a54b93128222768721b4391ce4ee3e1a7d951046bdcb67132b406d6582159394bdd6
7
- data.tar.gz: 646f78f7b642bffc4ff8be39e6c7fff011ade92ee8154651d66aafe1b803de0e4901151a01a962af6832c3ace23d4f27167186cdac26de1a29cc3453f02b2ca2
6
+ metadata.gz: b514e367ea3eb3b3be40f89d19b5a00388365b1a39fd0dc5bc98c1f971ff2831a4fcc80c3c463079d4a61773e0375504cfd9afa198aae7d1c42d762fb2e56def
7
+ data.tar.gz: ef993a463b78db8deba2a6b6304aeb408961ee6ae89e92e62f8b79e52f662a6c0d7155921aee78c1ddce67055fa218294b09afefb19674d27aa1edb32622c0e8
data/CHANGELOG.md CHANGED
@@ -1,6 +1,47 @@
1
1
  # Hanami::Router
2
2
 
3
- Rack compatible HTTP router for Ruby
3
+ Rack compatible HTTP router for Ruby.
4
+
5
+ ## [Unreleased]
6
+
7
+ ### Added
8
+
9
+ ### Changed
10
+
11
+ ### Deprecated
12
+
13
+ ### Removed
14
+
15
+ ### Fixed
16
+
17
+ ### Security
18
+
19
+ [Unreleased]: http://github.com/hanami/hanami-router/compare/v2.3.1...main
20
+
21
+ ## [2.3.1] - 2025-12-17
22
+
23
+ ### Changed
24
+
25
+ - Require Rack version 2.2.16 or higher, which is the earliest version of Rack 2.x that will run on Ruby 4.0 as well as our currently supported Ruby versions (3.2, 3.3, 3.4). (@cllns in 2b15582)
26
+
27
+ ### Fixed
28
+
29
+ - Set correct Rack `"SCRIPT_NAME"` value for mounts under dynamic prefixes. (@timriley in #294).
30
+
31
+ For example, given a mount under `scope '/stations/:station_id'`, the "SCRIPT_NAME" will be e.g. `"/stations/42"` rather than `"/stations/:station_id"`.
32
+ - For a mount with a prefix, allow the Rack `"PATH_INFO"` value to remain an empty string when a request is made for that exact prefix only. (@timriley in #295)
33
+
34
+ Given the following:
35
+
36
+ ```ruby
37
+ mount ->(env) { [200, {}, [env["PATH_INFO"]] }, at: "/settings"
38
+ ```
39
+
40
+ When a request is made to `"/settings"`, the `"SCRIPT_NAME"` will be `"/settings"` and `"PATH_INFO"` will be `""`. This ensures that the Rack environment can be used to reconstruct the same path as used for the original request.
41
+
42
+ To ensure a mounted router instance can still route to its root, treat `""` the same as `"/"` for the purposes of matching routes.
43
+
44
+ [2.3.1]: http://github.com/hanami/hanami-router/compare/v2.3.0...v2.3.1
4
45
 
5
46
  ## v2.3.0 - 2025-11-12
6
47
 
@@ -20,15 +20,15 @@ Gem::Specification.new do |spec|
20
20
  spec.metadata["rubygems_mfa_required"] = "true"
21
21
  spec.required_ruby_version = ">= 3.2"
22
22
 
23
- spec.add_dependency "rack", ">= 2.0"
23
+ spec.add_dependency "rack", ">= 2.2.16"
24
24
  spec.add_dependency "mustermann", "~> 3.0"
25
25
  spec.add_dependency "mustermann-contrib", "~> 3.0"
26
26
  spec.add_dependency "csv", "~> 3.3"
27
27
 
28
- spec.add_development_dependency "bundler", ">= 1.6", "< 3"
29
28
  spec.add_development_dependency "rake", "~> 13"
30
29
  spec.add_development_dependency "rack-test", "~> 2.0"
31
30
  spec.add_development_dependency "rspec", "~> 3.8"
31
+ spec.add_development_dependency "ostruct" # Remove once we drop support for Rack 2
32
32
 
33
33
  spec.add_development_dependency "rubocop", "~> 1.0"
34
34
  spec.add_development_dependency "rubocop-performance", "~> 1.0"
@@ -14,9 +14,12 @@ module Hanami
14
14
  if @prefix.to_s == "/"
15
15
  env[::Rack::SCRIPT_NAME] = EMPTY_STRING
16
16
  else
17
- env[::Rack::SCRIPT_NAME] = env[::Rack::SCRIPT_NAME].to_s + @prefix.to_s
18
- env[::Rack::PATH_INFO] = env[::Rack::PATH_INFO].sub(@prefix.to_s, EMPTY_STRING)
19
- env[::Rack::PATH_INFO] = DEFAULT_PREFIX if env[::Rack::PATH_INFO] == EMPTY_STRING
17
+ # To set SCRIPT_NAME, use the actual matched portion of the path, not the prefix string
18
+ # itself. This is important for prefixes with dynamic segments like "/stations/:id". In
19
+ # this case, we want e.g. "/stations/42" as SCRIPT_NAME, not "/stations/:id".
20
+ matched_path = match.to_s
21
+ env[::Rack::SCRIPT_NAME] = env[::Rack::SCRIPT_NAME].to_s + matched_path
22
+ env[::Rack::PATH_INFO] = env[::Rack::PATH_INFO].sub(matched_path, EMPTY_STRING)
20
23
  end
21
24
 
22
25
  [@app, match.named_captures]
@@ -8,6 +8,6 @@ module Hanami
8
8
  #
9
9
  # @since 0.1.0
10
10
  # @api public
11
- VERSION = "2.3.0"
11
+ VERSION = "2.3.1"
12
12
  end
13
13
  end
data/lib/hanami/router.rb CHANGED
@@ -642,7 +642,12 @@ module Hanami
642
642
  # @since 2.0.0
643
643
  # @api private
644
644
  def fixed(env)
645
- @fixed.dig(env[::Rack::REQUEST_METHOD], env[::Rack::PATH_INFO])
645
+ path_info = env[::Rack::PATH_INFO]
646
+ # Treat empty PATH_INFO as "/" for route matching. This allows root routes (defined as "/") to
647
+ # match the empty PATH_INFO that is set for requests to a mount without a trailing slash.
648
+ path_info = DEFAULT_PREFIX if path_info == EMPTY_STRING
649
+
650
+ @fixed.dig(env[::Rack::REQUEST_METHOD], path_info)
646
651
  end
647
652
 
648
653
  # @since 2.0.0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hanakai team
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '2.0'
18
+ version: 2.2.16
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '2.0'
25
+ version: 2.2.16
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: mustermann
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -65,26 +65,6 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '3.3'
68
- - !ruby/object:Gem::Dependency
69
- name: bundler
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: '1.6'
75
- - - "<"
76
- - !ruby/object:Gem::Version
77
- version: '3'
78
- type: :development
79
- prerelease: false
80
- version_requirements: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: '1.6'
85
- - - "<"
86
- - !ruby/object:Gem::Version
87
- version: '3'
88
68
  - !ruby/object:Gem::Dependency
89
69
  name: rake
90
70
  requirement: !ruby/object:Gem::Requirement
@@ -127,6 +107,20 @@ dependencies:
127
107
  - - "~>"
128
108
  - !ruby/object:Gem::Version
129
109
  version: '3.8'
110
+ - !ruby/object:Gem::Dependency
111
+ name: ostruct
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
130
124
  - !ruby/object:Gem::Dependency
131
125
  name: rubocop
132
126
  requirement: !ruby/object:Gem::Requirement