Browse Source

Merge pull request #11912 from JoepRoebroek/JoepRoebroek-patch-11415

Patch issue #11415
Mark Story 8 years ago
parent
commit
ea7fb565ac
2 changed files with 47 additions and 14 deletions
  1. 13 13
      src/Routing/Route/Route.php
  2. 34 1
      tests/TestCase/Routing/Route/RouteTest.php

+ 13 - 13
src/Routing/Route/Route.php

@@ -609,19 +609,6 @@ class Route
         unset($context['params']);
         $hostOptions = array_intersect_key($url, $context);
 
-        // Check for properties that will cause an
-        // absolute url. Copy the other properties over.
-        if (isset($hostOptions['_scheme']) ||
-            isset($hostOptions['_port']) ||
-            isset($hostOptions['_host'])
-        ) {
-            $hostOptions += $context;
-
-            if ($hostOptions['_port'] == $context['_port']) {
-                unset($hostOptions['_port']);
-            }
-        }
-
         // Apply the _host option if possible
         if (isset($this->options['_host'])) {
             if (!isset($hostOptions['_host']) && strpos($this->options['_host'], '*') === false) {
@@ -637,6 +624,19 @@ class Route
             }
         }
 
+        // Check for properties that will cause an
+        // absolute url. Copy the other properties over.
+        if (isset($hostOptions['_scheme']) ||
+            isset($hostOptions['_port']) ||
+            isset($hostOptions['_host'])
+        ) {
+            $hostOptions += $context;
+
+            if (getservbyname($hostOptions['_scheme'], 'tcp') === $hostOptions['_port']) {
+                unset($hostOptions['_port']);
+            }
+        }
+
         // If no base is set, copy one in.
         if (!isset($hostOptions['_base']) && isset($context['_base'])) {
             $hostOptions['_base'] = $context['_base'];

+ 34 - 1
tests/TestCase/Routing/Route/RouteTest.php

@@ -564,13 +564,15 @@ class RouteTest extends TestCase
             ['controller' => 'posts', 'action' => 'index', '_host' => 'example.com'],
             $context
         );
+        // Http has port 80 as default, do not include it in the url
         $this->assertEquals('http://example.com/posts/index', $result);
 
         $result = $route->match(
             ['controller' => 'posts', 'action' => 'index', '_scheme' => 'webcal'],
             $context
         );
-        $this->assertEquals('webcal://foo.com/posts/index', $result);
+        // Webcal is not on port 80 by default, include it in url
+        $this->assertEquals('webcal://foo.com:80/posts/index', $result);
 
         $result = $route->match(
             ['controller' => 'posts', 'action' => 'index', '_port' => '8080'],
@@ -596,6 +598,26 @@ class RouteTest extends TestCase
             $context
         );
         $this->assertEquals('https://example.com:8080/dir/posts/index', $result);
+
+        $context = [
+            '_host' => 'foo.com',
+            '_scheme' => 'http',
+            '_port' => 8080,
+            '_base' => ''
+        ];
+        $result = $route->match(
+            [
+                'controller' => 'posts',
+                'action' => 'index',
+                '_port' => '8080',
+                '_host' => 'example.com',
+                '_scheme' => 'https',
+                '_base' => '/dir'
+            ],
+            $context
+        );
+        // Https scheme is not on port 8080 by default, include the port
+        $this->assertEquals('https://example.com:8080/dir/posts/index', $result);
     }
 
     /**
@@ -662,6 +684,17 @@ class RouteTest extends TestCase
             '_host' => 'foo.example.com'
         ]);
         $this->assertSame('http://foo.example.com/fallback', $result);
+
+        $result = $route->match([
+            'controller' => 'Articles',
+            'action' => 'index',
+        ], [
+            '_scheme' => 'https',
+            '_host' => 'foo.example.com',
+            '_port' => 8080
+        ]);
+        // When the port and scheme in the context are not present in the original url, they should be added
+        $this->assertSame('https://foo.example.com:8080/fallback', $result);
     }
 
     /**