@@ -46,17 +46,55 @@ public function dump(array $options = array())
46
46
47
47
$ rules = array ("# skip \"real \" requests \nRewriteCond %{REQUEST_FILENAME} -f \nRewriteRule .* - [QSA,L] " );
48
48
$ methodVars = array ();
49
+ $ hostnameRegexUnique = 0 ;
50
+ $ prevHosnameRegex = '' ;
49
51
50
52
foreach ($ this ->getRoutes ()->all () as $ name => $ route ) {
51
- $ rules [] = $ this ->dumpRoute ($ name , $ route , $ options );
52
- $ methodVars = array_merge ($ methodVars , $ this ->getRouteMethods ($ route ));
53
- }
54
53
54
+ $ compiledRoute = $ route ->compile ();
55
+ $ hostnameRegex = $ compiledRoute ->getHostnameRegex ();
56
+
57
+ if (null !== $ hostnameRegex && $ prevHosnameRegex !== $ hostnameRegex ) {
58
+
59
+ $ prevHosnameRegex = $ hostnameRegex ;
60
+ $ hostnameRegexUnique ++;
61
+
62
+ $ rule = array ();
63
+
64
+ $ regex = $ this ->regexToApacheRegex ($ hostnameRegex );
65
+ $ regex = self ::escape ($ regex , ' ' , '\\' );
66
+
67
+ $ rule [] = sprintf ('RewriteCond %%{HTTP:Host} %s ' , $ regex );
68
+
69
+ $ variables = array ();
70
+ $ variables [] = sprintf ('E=__ROUTING_hostname_%s:1 ' , $ hostnameRegexUnique );
71
+
72
+ foreach ($ compiledRoute ->getHostnameVariables () as $ i => $ variable ) {
73
+ $ variables [] = sprintf ('E=__ROUTING_hostname_%s_%s:%%%d ' , $ hostnameRegexUnique , $ variable , $ i +1 );
74
+ }
75
+
76
+ $ variables = implode (', ' , $ variables );
77
+
78
+ $ rule [] = sprintf ('RewriteRule .? - [%s] ' , $ variables );
79
+
80
+ $ rules [] = implode ("\n" , $ rule );
81
+ }
82
+
83
+ $ rules [] = $ this ->dumpRoute ($ name , $ route , $ options , $ hostnameRegexUnique );
84
+
85
+ if ($ req = $ route ->getRequirement ('_method ' )) {
86
+ $ methods = explode ('| ' , strtoupper ($ req ));
87
+ $ methodVars = array_merge ($ methodVars , $ methods );
88
+ }
89
+ }
55
90
if (0 < count ($ methodVars )) {
56
91
$ rule = array ('# 405 Method Not Allowed ' );
57
92
$ methodVars = array_values (array_unique ($ methodVars ));
93
+ if (in_array ('GET ' , $ methodVars ) && !in_array ('HEAD ' , $ methodVars )) {
94
+ $ methodVars [] = 'HEAD ' ;
95
+ }
58
96
foreach ($ methodVars as $ i => $ methodVar ) {
59
- $ rule [] = sprintf ('RewriteCond %%{_ROUTING_allow_ %s} !-z %s ' , $ methodVar , isset ($ methodVars [$ i + 1 ]) ? ' [OR] ' : '' );
97
+ $ rule [] = sprintf ('RewriteCond %%{ENV:_ROUTING__allow_ %s} =1 %s ' , $ methodVar , isset ($ methodVars [$ i + 1 ]) ? ' [OR] ' : '' );
60
98
}
61
99
$ rule [] = sprintf ('RewriteRule .* %s [QSA,L] ' , $ options ['script_name ' ]);
62
100
@@ -66,7 +104,16 @@ public function dump(array $options = array())
66
104
return implode ("\n\n" , $ rules )."\n" ;
67
105
}
68
106
69
- private function dumpRoute ($ name , $ route , array $ options )
107
+ /**
108
+ * Dumps a single route
109
+ *
110
+ * @param string $name Route name
111
+ * @param Route $route The route
112
+ * @param array $options Options
113
+ * @param bool $hostnameRegexUnique Unique identifier for the hostname regex
114
+ * @return string The compiled route
115
+ */
116
+ private function dumpRoute ($ name , $ route , array $ options , $ hostnameRegexUnique )
70
117
{
71
118
$ compiledRoute = $ route ->compile ();
72
119
@@ -79,7 +126,10 @@ private function dumpRoute($name, $route, array $options)
79
126
$ hasTrailingSlash = (!$ methods || in_array ('HEAD ' , $ methods )) && '/$ ' === substr ($ regex , -2 ) && '^/$ ' !== $ regex ;
80
127
81
128
$ variables = array ('E=_ROUTING_route: ' .$ name );
82
- foreach ($ compiledRoute ->getVariables () as $ i => $ variable ) {
129
+ foreach ($ compiledRoute ->getHostnameVariables () as $ variable ) {
130
+ $ variables [] = sprintf ('E=_ROUTING_param_%s:%%{ENV:__ROUTING_hostname_%s_%s} ' , $ variable , $ hostnameRegexUnique , $ variable );
131
+ }
132
+ foreach ($ compiledRoute ->getPathVariables () as $ i => $ variable ) {
83
133
$ variables [] = 'E=_ROUTING_param_ ' .$ variable .':% ' .($ i + 1 );
84
134
}
85
135
foreach ($ route ->getDefaults () as $ key => $ value ) {
@@ -98,22 +148,35 @@ private function dumpRoute($name, $route, array $options)
98
148
if (0 < count ($ methods )) {
99
149
$ allow = array ();
100
150
foreach ($ methods as $ method ) {
101
- $ methodVars [] = $ method ;
102
151
$ allow [] = 'E=_ROUTING_allow_ ' .$ method .':1 ' ;
103
152
}
104
153
154
+ if ($ hostnameRegex = $ compiledRoute ->getHostnameRegex ()) {
155
+ $ rule [] = sprintf ("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1 " , $ hostnameRegexUnique );
156
+ }
157
+
105
158
$ rule [] = "RewriteCond %{REQUEST_URI} $ regex " ;
106
159
$ rule [] = sprintf ("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC] " , implode ('| ' , $ methods ));
107
160
$ rule [] = sprintf ('RewriteRule .* - [S=%d,%s] ' , $ hasTrailingSlash ? 2 : 1 , implode (', ' , $ allow ));
108
161
}
109
162
110
163
// redirect with trailing slash appended
111
164
if ($ hasTrailingSlash ) {
165
+
166
+ if ($ hostnameRegex = $ compiledRoute ->getHostnameRegex ()) {
167
+ $ rule [] = sprintf ("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1 " , $ hostnameRegexUnique );
168
+ }
169
+
112
170
$ rule [] = 'RewriteCond %{REQUEST_URI} ' .substr ($ regex , 0 , -2 ).'$ ' ;
113
171
$ rule [] = 'RewriteRule .* $0/ [QSA,L,R=301] ' ;
114
172
}
115
173
116
174
// the main rule
175
+
176
+ if ($ hostnameRegex = $ compiledRoute ->getHostnameRegex ()) {
177
+ $ rule [] = sprintf ("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1 " , $ hostnameRegexUnique );
178
+ }
179
+
117
180
$ rule [] = "RewriteCond %{REQUEST_URI} $ regex " ;
118
181
$ rule [] = "RewriteRule .* {$ options ['script_name ' ]} [QSA,L, $ variables] " ;
119
182
0 commit comments