ソースを参照

Fix _ssl and _full not working well together.

When _ssl=true and _full=true we should generate URLs with SSL
protocols, and not HTTP ones.

Add tests to cover cases described in #11583 & #11582
Mark Story 8 年 前
コミット
82acd2beef
2 ファイル変更49 行追加11 行削除
  1. 9 11
      src/Routing/Router.php
  2. 40 0
      tests/TestCase/Routing/RouterTest.php

+ 9 - 11
src/Routing/Router.php

@@ -618,19 +618,16 @@ class Router
         }
         if (is_array($url)) {
             if (isset($url['_ssl'])) {
-                if (!isset($url['_full'])) {
-                    $url['_scheme'] = ($url['_ssl'] === true) ? 'https' : 'http';
-                }
-                unset($url['_ssl']);
+                $url['_scheme'] = ($url['_ssl'] === true) ? 'https' : 'http';
             }
+
             if (isset($url['_full']) && $url['_full'] === true) {
                 $full = true;
-                unset($url['_full']);
             }
             if (isset($url['#'])) {
                 $frag = '#' . $url['#'];
-                unset($url['#']);
             }
+            unset($url['_ssl'], $url['_full'], $url['#']);
 
             $url = static::_applyUrlFilters($url);
 
@@ -655,6 +652,12 @@ class Router
                 ];
             }
 
+            // If a full URL is requested with a scheme the host should default
+            // to App.fullBaseUrl to avoid corrupt URLs
+            if ($full && isset($url['_scheme']) && !isset($url['_host'])) {
+                $url['_host'] = parse_url(static::fullBaseUrl(), PHP_URL_HOST);
+            }
+
             $output = static::$_collection->match($url, static::$_requestContext + ['params' => $params]);
         } else {
             $plainString = (
@@ -681,11 +684,6 @@ class Router
             }
         }
 
-        $protocolError = preg_match('#^[a-z][a-z0-9+\-.]*\:///#i', $output);
-        if ($protocolError === 1) {
-            $output = str_replace(':///', '://', $output);
-        }
-
         return $output . $frag;
     }
 

+ 40 - 0
tests/TestCase/Routing/RouterTest.php

@@ -2060,6 +2060,46 @@ class RouterTest extends TestCase
     }
 
     /**
+     * Test that the _ssl + _full options work together.
+     *
+     * @return void
+     */
+    public function testGenerationWithSslAndFullOption()
+    {
+        Configure::write('App.fullBaseUrl', 'http://app.localhost');
+        Router::connect('/:controller/:action/*');
+
+        $request = new ServerRequest([
+            'environment' => ['HTTP_HOST' => 'localhost']
+        ]);
+        Router::pushRequest($request);
+
+        $result = Router::url([
+            'controller' => 'images',
+            'action' => 'index',
+            '_ssl' => true,
+            '_full' => true
+        ]);
+        $this->assertEquals('https://app.localhost/images/index', $result);
+
+        $result = Router::url([
+            'controller' => 'images',
+            'action' => 'index',
+            '_ssl' => false,
+            '_full' => true,
+        ]);
+        $this->assertEquals('http://app.localhost/images/index', $result);
+
+        $result = Router::url([
+            'controller' => 'images',
+            'action' => 'index',
+            '_full' => false,
+            '_ssl' => false
+        ]);
+        $this->assertEquals('http://localhost/images/index', $result);
+    }
+
+    /**
      * Test ssl option when the current request is ssl.
      *
      * @return void