@@ -46,17 +46,55 @@ public function dump(array $options = array())
4646
4747 $ rules = array ("# skip \"real \" requests \nRewriteCond %{REQUEST_FILENAME} -f \nRewriteRule .* - [QSA,L] " );
4848 $ methodVars = array ();
49+ $ hostnameRegexUnique = 0 ;
50+ $ prevHosnameRegex = '' ;
4951
5052 foreach ($ this ->getRoutes ()->all () as $ name => $ route ) {
51- $ rules [] = $ this ->dumpRoute ($ name , $ route , $ options );
52- $ methodVars = array_merge ($ methodVars , $ this ->getRouteMethods ($ route ));
53- }
5453
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+ }
5590 if (0 < count ($ methodVars )) {
5691 $ rule = array ('# 405 Method Not Allowed ' );
5792 $ methodVars = array_values (array_unique ($ methodVars ));
93+ if (in_array ('GET ' , $ methodVars ) && !in_array ('HEAD ' , $ methodVars )) {
94+ $ methodVars [] = 'HEAD ' ;
95+ }
5896 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] ' : '' );
6098 }
6199 $ rule [] = sprintf ('RewriteRule .* %s [QSA,L] ' , $ options ['script_name ' ]);
62100
@@ -66,7 +104,16 @@ public function dump(array $options = array())
66104 return implode ("\n\n" , $ rules )."\n" ;
67105 }
68106
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 )
70117 {
71118 $ compiledRoute = $ route ->compile ();
72119
@@ -79,7 +126,10 @@ private function dumpRoute($name, $route, array $options)
79126 $ hasTrailingSlash = (!$ methods || in_array ('HEAD ' , $ methods )) && '/$ ' === substr ($ regex , -2 ) && '^/$ ' !== $ regex ;
80127
81128 $ 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 ) {
83133 $ variables [] = 'E=_ROUTING_param_ ' .$ variable .':% ' .($ i + 1 );
84134 }
85135 foreach ($ route ->getDefaults () as $ key => $ value ) {
@@ -98,22 +148,35 @@ private function dumpRoute($name, $route, array $options)
98148 if (0 < count ($ methods )) {
99149 $ allow = array ();
100150 foreach ($ methods as $ method ) {
101- $ methodVars [] = $ method ;
102151 $ allow [] = 'E=_ROUTING_allow_ ' .$ method .':1 ' ;
103152 }
104153
154+ if ($ hostnameRegex = $ compiledRoute ->getHostnameRegex ()) {
155+ $ rule [] = sprintf ("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1 " , $ hostnameRegexUnique );
156+ }
157+
105158 $ rule [] = "RewriteCond %{REQUEST_URI} $ regex " ;
106159 $ rule [] = sprintf ("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC] " , implode ('| ' , $ methods ));
107160 $ rule [] = sprintf ('RewriteRule .* - [S=%d,%s] ' , $ hasTrailingSlash ? 2 : 1 , implode (', ' , $ allow ));
108161 }
109162
110163 // redirect with trailing slash appended
111164 if ($ hasTrailingSlash ) {
165+
166+ if ($ hostnameRegex = $ compiledRoute ->getHostnameRegex ()) {
167+ $ rule [] = sprintf ("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1 " , $ hostnameRegexUnique );
168+ }
169+
112170 $ rule [] = 'RewriteCond %{REQUEST_URI} ' .substr ($ regex , 0 , -2 ).'$ ' ;
113171 $ rule [] = 'RewriteRule .* $0/ [QSA,L,R=301] ' ;
114172 }
115173
116174 // the main rule
175+
176+ if ($ hostnameRegex = $ compiledRoute ->getHostnameRegex ()) {
177+ $ rule [] = sprintf ("RewriteCond %%{ENV:__ROUTING_hostname_%s} =1 " , $ hostnameRegexUnique );
178+ }
179+
117180 $ rule [] = "RewriteCond %{REQUEST_URI} $ regex " ;
118181 $ rule [] = "RewriteRule .* {$ options ['script_name ' ]} [QSA,L, $ variables] " ;
119182
0 commit comments