@@ -93,10 +93,30 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac
93
93
*/
94
94
private function generateMatchMethod ($ supportsRedirections )
95
95
{
96
- $ code = rtrim ($ this ->compileRoutes ($ this ->getRoutes (), $ supportsRedirections ), "\n" );
97
-
98
96
return <<<EOF
99
97
public function match( \$rawPathinfo)
98
+ {
99
+ try {
100
+ return \$this->matchWithoutTrailingSlashManagement( \$rawPathinfo);
101
+ } catch (MethodNotAllowedException \$e) {
102
+ throw \$e;
103
+ } catch (ResourceNotFoundException \$e) {
104
+ return \$this->matchWithTrailingSlashManagement( \$rawPathinfo);
105
+ }
106
+ }
107
+
108
+ {$ this ->generateMatchWithTrailingSlashManagement ($ supportsRedirections )}
109
+
110
+ {$ this ->generateMatchWithoutTrailingSlashManagement ($ supportsRedirections )}
111
+ EOF ;
112
+ }
113
+
114
+ private function generateMatchWithTrailingSlashManagement ($ supportsRedirections )
115
+ {
116
+ $ code = rtrim ($ this ->compileRoutes ($ this ->getRoutes (), $ supportsRedirections , true ), "\n" );
117
+
118
+ return <<<EOF
119
+ public function matchWithTrailingSlashManagement( \$rawPathinfo)
100
120
{
101
121
\$allow = [];
102
122
\$pathinfo = rawurldecode( \$rawPathinfo);
@@ -109,6 +129,30 @@ public function match(\$rawPathinfo)
109
129
\$canonicalMethod = 'GET';
110
130
}
111
131
132
+ $ code
133
+
134
+ throw 0 < count( \$allow) ? new MethodNotAllowedException(array_unique( \$allow)) : new ResourceNotFoundException();
135
+ }
136
+ EOF ;
137
+ }
138
+
139
+ private function generateMatchWithoutTrailingSlashManagement ($ supportsRedirections )
140
+ {
141
+ $ code = rtrim ($ this ->compileRoutes ($ this ->getRoutes (), $ supportsRedirections , false ), "\n" );
142
+
143
+ return <<<EOF
144
+ public function matchWithoutTrailingSlashManagement( \$rawPathinfo)
145
+ {
146
+ \$allow = [];
147
+ \$pathinfo = rawurldecode( \$rawPathinfo);
148
+ \$context = \$this->context;
149
+ \$request = \$this->request ?: \$this->createRequest( \$pathinfo);
150
+ \$requestMethod = \$canonicalMethod = \$context->getMethod();
151
+
152
+ if ('HEAD' === \$requestMethod) {
153
+ \$canonicalMethod = 'GET';
154
+ }
155
+
112
156
$ code
113
157
114
158
throw 0 < count( \$allow) ? new MethodNotAllowedException(array_unique( \$allow)) : new ResourceNotFoundException();
@@ -124,7 +168,7 @@ public function match(\$rawPathinfo)
124
168
*
125
169
* @return string PHP code
126
170
*/
127
- private function compileRoutes (RouteCollection $ routes , $ supportsRedirections )
171
+ private function compileRoutes (RouteCollection $ routes , $ supportsRedirections, $ trailingSlashManagement = true )
128
172
{
129
173
$ fetchedHost = false ;
130
174
$ groups = $ this ->groupRoutesByHostRegex ($ routes );
@@ -141,7 +185,7 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
141
185
}
142
186
143
187
$ tree = $ this ->buildStaticPrefixCollection ($ collection );
144
- $ groupCode = $ this ->compileStaticPrefixRoutes ($ tree , $ supportsRedirections );
188
+ $ groupCode = $ this ->compileStaticPrefixRoutes ($ tree , $ supportsRedirections, $ trailingSlashManagement );
145
189
146
190
if (null !== $ regex ) {
147
191
// apply extra indention at each line (except empty ones)
@@ -184,7 +228,7 @@ private function buildStaticPrefixCollection(DumperCollection $collection)
184
228
*
185
229
* @return string PHP code
186
230
*/
187
- private function compileStaticPrefixRoutes (StaticPrefixCollection $ collection , $ supportsRedirections , $ ifOrElseIf = 'if ' )
231
+ private function compileStaticPrefixRoutes (StaticPrefixCollection $ collection , $ supportsRedirections , $ trailingSlashManagement , $ ifOrElseIf = 'if ' )
188
232
{
189
233
$ code = '' ;
190
234
$ prefix = $ collection ->getPrefix ();
@@ -200,7 +244,7 @@ private function compileStaticPrefixRoutes(StaticPrefixCollection $collection, $
200
244
$ code .= $ this ->compileStaticPrefixRoutes ($ route , $ supportsRedirections , $ ifOrElseIf );
201
245
$ ifOrElseIf = 'elseif ' ;
202
246
} else {
203
- $ code .= $ this ->compileRoute ($ route [1 ]->getRoute (), $ route [1 ]->getName (), $ supportsRedirections , $ prefix )."\n" ;
247
+ $ code .= $ this ->compileRoute ($ route [1 ]->getRoute (), $ route [1 ]->getName (), $ supportsRedirections , $ trailingSlashManagement , $ prefix )."\n" ;
204
248
$ ifOrElseIf = 'if ' ;
205
249
}
206
250
}
@@ -226,7 +270,7 @@ private function compileStaticPrefixRoutes(StaticPrefixCollection $collection, $
226
270
*
227
271
* @throws \LogicException
228
272
*/
229
- private function compileRoute (Route $ route , $ name , $ supportsRedirections , $ parentPrefix = null )
273
+ private function compileRoute (Route $ route , $ name , $ supportsRedirections , $ trailingSlashManagement , $ parentPrefix = null )
230
274
{
231
275
$ code = '' ;
232
276
$ compiledRoute = $ route ->compile ();
@@ -236,7 +280,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
236
280
$ hostMatches = false ;
237
281
$ methods = $ route ->getMethods ();
238
282
239
- $ supportsTrailingSlash = $ supportsRedirections && (!$ methods || \in_array ('GET ' , $ methods ));
283
+ $ supportsTrailingSlash = $ supportsRedirections && (!$ methods || \in_array ('GET ' , $ methods )) && $ trailingSlashManagement ;
240
284
$ regex = $ compiledRoute ->getRegex ();
241
285
242
286
if (!\count ($ compiledRoute ->getPathVariables ()) && false !== preg_match ('#^(.)\^(?P<url>.*?)\$\1# ' .('u ' === substr ($ regex , -1 ) ? 'u ' : '' ), $ regex , $ m )) {
0 commit comments