Skip to content

Commit e1948fc

Browse files
committed
MC-20394: [Magento Cloud] Redirect URL is getting cut off after 3 slashes
- Fix redirect to base URL
1 parent f35c6eb commit e1948fc

File tree

2 files changed

+193
-12
lines changed

2 files changed

+193
-12
lines changed

app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Store\App\FrontController\Plugin;
77

8+
/**
9+
* Class RequestPreprocessor
10+
*/
811
class RequestPreprocessor
912
{
1013
/**
@@ -52,6 +55,7 @@ public function __construct(
5255

5356
/**
5457
* Auto-redirect to base url (without SID) if the requested url doesn't match it.
58+
*
5559
* By default this feature is enabled in configuration.
5660
*
5761
* @param \Magento\Framework\App\FrontController $subject
@@ -72,10 +76,11 @@ public function aroundDispatch(
7276
$this->_storeManager->getStore()->isCurrentlySecure()
7377
);
7478
if ($baseUrl) {
79+
// phpcs:disable Magento2.Functions.DiscouragedFunction
7580
$uri = parse_url($baseUrl);
7681
if (!$this->getBaseUrlChecker()->execute($uri, $request)) {
7782
$redirectUrl = $this->_url->getRedirectUrl(
78-
$this->_url->getUrl(ltrim($request->getPathInfo(), '/'), ['_nosid' => true])
83+
$this->_url->getDirectUrl(ltrim($request->getPathInfo(), '/'), ['_nosid' => true])
7984
);
8085
$redirectCode = (int)$this->_scopeConfig->getValue(
8186
'web/url/redirect_to_base',

dev/tests/integration/testsuite/Magento/Store/App/FrontController/Plugin/RequestPreprocessorTest.php

Lines changed: 187 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Zend\Stdlib\Parameters;
1515

1616
/**
17-
* Class RequestPreprocessorTest @covers \Magento\Store\App\FrontController\Plugin\RequestPreprocessor.
17+
* Tests \Magento\Store\App\FrontController\Plugin\RequestPreprocessor.
1818
*/
1919
class RequestPreprocessorTest extends \Magento\TestFramework\TestCase\AbstractController
2020
{
@@ -24,6 +24,28 @@ class RequestPreprocessorTest extends \Magento\TestFramework\TestCase\AbstractCo
2424
* @var string
2525
*/
2626
private $baseUrl;
27+
/**
28+
* @var array;
29+
*/
30+
private $config;
31+
32+
/**
33+
* @inheritDoc
34+
*/
35+
protected function setUp()
36+
{
37+
parent::setUp();
38+
$this->config = [];
39+
}
40+
41+
/**
42+
* @inheritDoc
43+
*/
44+
protected function tearDown()
45+
{
46+
$this->setConfig($this->config);
47+
parent::tearDown();
48+
}
2749

2850
/**
2951
* Test non-secure POST request is redirected right away on completely secure frontend.
@@ -62,6 +84,115 @@ public function testHttpsPassSecureLoginPost()
6284
$this->setFrontendCompletelySecureRollback();
6385
}
6486

87+
/**
88+
* Test auto redirect to base URL
89+
*
90+
* @param array $config
91+
* @param string $requestUrl
92+
* @param string $redirectUrl
93+
* @dataProvider autoRedirectToBaseURLDataProvider
94+
*/
95+
public function testAutoRedirectToBaseURL(array $config, string $requestUrl, string $redirectUrl)
96+
{
97+
$request = [
98+
'REQUEST_SCHEME' => parse_url($requestUrl, PHP_URL_SCHEME),
99+
'SERVER_NAME' => parse_url($requestUrl, PHP_URL_HOST),
100+
'SCRIPT_NAME' => '/index.php',
101+
'SCRIPT_FILENAME' => 'index.php',
102+
'REQUEST_URI' => parse_url($requestUrl, PHP_URL_PATH),
103+
];
104+
$this->setConfig($config);
105+
$this->setServer($request);
106+
$app = $this->_objectManager->create(\Magento\Framework\App\Http::class, ['_request' => $this->getRequest()]);
107+
$this->_response = $app->launch();
108+
$this->assertRedirect($this->equalTo($redirectUrl));
109+
}
110+
111+
/**
112+
* @return array
113+
*/
114+
public function autoRedirectToBaseURLDataProvider(): array
115+
{
116+
$baseConfig = [
117+
'web/unsecure/base_url' => 'http://magento.com/us/',
118+
'web/session/use_frontend_sid' => 0,
119+
'web/seo/use_rewrites' => 1,
120+
];
121+
122+
return [
123+
[
124+
'config' => $baseConfig,
125+
'request' => 'http://magento.com/a/b/c/d/e.html',
126+
'redirectUrl' => 'http://magento.com/us/a/b/c/d/e.html'
127+
],
128+
[
129+
'config' => $baseConfig,
130+
'request' => 'http://magento.com/a/b/c/d.html',
131+
'redirectUrl' => 'http://magento.com/us/a/b/c/d.html'
132+
],
133+
[
134+
'config' => $baseConfig,
135+
'request' => 'http://magento.com/a/b/c.html',
136+
'redirectUrl' => 'http://magento.com/us/a/b/c.html'
137+
],
138+
[
139+
'config' => $baseConfig,
140+
'request' => 'http://magento.com/a/b.html',
141+
'redirectUrl' => 'http://magento.com/us/a/b.html'
142+
],
143+
[
144+
'config' => $baseConfig,
145+
'request' => 'http://magento.com/a.html',
146+
'redirectUrl' => 'http://magento.com/us/a.html'
147+
],
148+
[
149+
'config' => $baseConfig,
150+
'request' => 'http://magento.com/a/b/c/d/e',
151+
'redirectUrl' => 'http://magento.com/us/a/b/c/d/e'
152+
],
153+
[
154+
'config' => $baseConfig,
155+
'request' => 'http://magento.com/a/b/c/d',
156+
'redirectUrl' => 'http://magento.com/us/a/b/c/d'
157+
],
158+
[
159+
'config' => $baseConfig,
160+
'request' => 'http://magento.com/a/b/c',
161+
'redirectUrl' => 'http://magento.com/us/a/b/c'
162+
],
163+
[
164+
'config' => $baseConfig,
165+
'request' => 'http://magento.com/a/b',
166+
'redirectUrl' => 'http://magento.com/us/a/b'
167+
],
168+
[
169+
'config' => $baseConfig,
170+
'request' => 'http://magento.com/a',
171+
'redirectUrl' => 'http://magento.com/us/a'
172+
],
173+
[
174+
'config' => $baseConfig,
175+
'request' => 'http://magento.com/',
176+
'redirectUrl' => 'http://magento.com/us/'
177+
],
178+
[
179+
'config' => array_merge($baseConfig, ['web/seo/use_rewrites' => 0]),
180+
'request' => 'http://magento.com/',
181+
'redirectUrl' => 'http://magento.com/us/index.php/'
182+
],
183+
[
184+
'config' => array_merge($baseConfig, ['web/seo/use_rewrites' => 0]),
185+
'request' => 'http://magento.com/a/b/c/d.html',
186+
'redirectUrl' => 'http://magento.com/us/index.php/a/b/c/d.html'
187+
],
188+
[
189+
'config' => array_merge($baseConfig, ['web/seo/use_rewrites' => 0]),
190+
'request' => 'http://magento.com/a/b/c/d',
191+
'redirectUrl' => 'http://magento.com/us/index.php/a/b/c/d'
192+
],
193+
];
194+
}
195+
65196
/**
66197
* Assert response is redirect with https protocol.
67198
*
@@ -83,22 +214,26 @@ private function assertResponseRedirect(Response $response, string $redirectUrl)
83214
*/
84215
private function prepareRequest(bool $isSecure = false)
85216
{
86-
$post = new Parameters([
87-
'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
88-
'login' => [
89-
'username' => 'customer@example.com',
90-
'password' => 'password'
217+
$post = new Parameters(
218+
[
219+
'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
220+
'login' => [
221+
'username' => 'customer@example.com',
222+
'password' => 'password'
223+
]
91224
]
92-
]);
225+
);
93226
$request = $this->getRequest();
94227
$request->setMethod(\Magento\TestFramework\Request::METHOD_POST);
95228
$request->setRequestUri('customer/account/loginPost/');
96229
$request->setPost($post);
97230
if ($isSecure) {
98-
$server = new Parameters([
99-
'HTTPS' => 'on',
100-
'SERVER_PORT' => 443
101-
]);
231+
$server = new Parameters(
232+
[
233+
'HTTPS' => 'on',
234+
'SERVER_PORT' => 443
235+
]
236+
);
102237
$request->setServer($server);
103238
}
104239

@@ -151,4 +286,45 @@ private function setFrontendCompletelySecureRollback()
151286
$reinitibleConfig = $this->_objectManager->create(ReinitableConfigInterface::class);
152287
$reinitibleConfig->reinit();
153288
}
289+
290+
private function setConfig(array $config): void
291+
{
292+
foreach ($config as $path => $value) {
293+
$model = $this->_objectManager->create(Value::class);
294+
$model->load($path, 'path');
295+
if (!isset($this->config[$path])) {
296+
$this->config[$path] = $model->getValue();
297+
}
298+
if (!$model->getPath()) {
299+
$model->setPath($path);
300+
}
301+
if ($value !== null) {
302+
$model->setValue($value);
303+
$model->save();
304+
} elseif ($model->getId()) {
305+
$model->delete();
306+
}
307+
}
308+
$this->_objectManager->create(ReinitableConfigInterface::class)->reinit();
309+
}
310+
311+
private function setServer(array $server)
312+
{
313+
$request = $this->getRequest();
314+
$properties = [
315+
'baseUrl',
316+
'basePath',
317+
'requestUri',
318+
'originalPathInfo',
319+
'pathInfo',
320+
];
321+
$reflection = new \ReflectionClass($request);
322+
323+
foreach ($properties as $name) {
324+
$property = $reflection->getProperty($name);
325+
$property->setAccessible(true);
326+
$property->setValue($request, null);
327+
}
328+
$request->setServer(new Parameters($server));
329+
}
154330
}

0 commit comments

Comments
 (0)