Skip to content

Commit 39f23cc

Browse files
committed
Merge branch 'remove-www-prefix'
2 parents 63fb113 + b6be728 commit 39f23cc

File tree

8 files changed

+103
-0
lines changed

8 files changed

+103
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Features
2121
- [x] Keep headers, request method, and request body.
2222
- [x] Enable/disable HTTP Strict Transport Security Header and set its value.
2323
- [x] Allow add `www.` prefix during redirection from http or already https.
24+
- [x] Allow remove `www.` prefix during redirection from http or already https.
2425

2526
Installation
2627
------------
@@ -79,6 +80,9 @@ return [
7980
],
8081
// set to true to add "www." prefix during redirection from http or already https
8182
'add_www_prefix' => false,
83+
// remove existing "www." prefix during redirection from http or already https
84+
// only works if previous's config 'add_www_prefix' => false
85+
'remove_www_prefix' => false,
8286
],
8387
// ...
8488
];

config/expressive-force-https-module.local.php.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ return [
1616
'value' => 'max-age=31536000',
1717
],
1818
'add_www_prefix' => false,
19+
'remove_www_prefix' => false,
1920
],
2021

2122
'dependencies' => [

config/force-https-module.local.php.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ return [
1414
'value' => 'max-age=31536000',
1515
],
1616
'add_www_prefix' => false,
17+
'remove_www_prefix' => false,
1718
],
1819
];

spec/Listener/ForceHttpsSpec.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,40 @@
242242

243243
});
244244

245+
it('redirect without www prefix for already has www prefix with configurable "remove_www_prefix" on force_all_routes', function () {
246+
247+
$listener = new ForceHttps([
248+
'enable' => true,
249+
'force_all_routes' => true,
250+
'force_specific_routes' => [],
251+
'strict_transport_security' => [
252+
'enable' => true,
253+
'value' => 'max-age=31536000',
254+
],
255+
'add_www_prefix' => false,
256+
'remove_www_prefix' => true,
257+
]);
258+
259+
allow($this->uri)->toReceive('toString')->andReturn('http://www.example.com/about');
260+
allow($this->mvcEvent)->toReceive('getRequest')->andReturn($this->request);
261+
allow($this->request)->toReceive('getUri')->andReturn($this->uri);
262+
allow($this->uri)->toReceive('getScheme')->andReturn('http');
263+
allow($this->mvcEvent)->toReceive('getRouteMatch', 'getMatchedRouteName')->andReturn('about');
264+
allow($this->uri)->toReceive('setScheme')->with('https')->andReturn($this->uri);
265+
allow($this->uri)->toReceive('toString')->andReturn('https://www.example.com/about');
266+
allow($this->mvcEvent)->toReceive('getResponse')->andReturn($this->response);
267+
allow($this->response)->toReceive('getHeaders', 'addHeaderLine')
268+
->with('Location', 'https://example.com/about')
269+
->andReturn($this->response);
270+
allow($this->response)->toReceive('setStatusCode')->with(308)->andReturn($this->response);
271+
allow($this->response)->toReceive('send');
272+
273+
$listener->forceHttpsScheme($this->mvcEvent);
274+
275+
expect($this->mvcEvent)->toReceive('getResponse');
276+
277+
});
278+
245279
it('not redirect with set strict_transport_security exists and uri already has https scheme', function () {
246280

247281
$listener = new ForceHttps([

spec/Middleware/ForceHttpsSpec.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,43 @@
248248

249249
});
250250

251+
it('return Response with 308 status with remove www prefix on http and match with configurable "remove_www_prefix"', function () {
252+
253+
Console::overrideIsConsole(false);
254+
if (method_exists(RouteResult::class, 'fromRoute')) {
255+
$match = RouteResult::fromRoute(new Route('/about', 'About'));
256+
} else {
257+
$match = RouteResult::fromRouteMatch('about', 'about', []);
258+
}
259+
260+
allow($this->request)->toReceive('getUri', '__toString')->andReturn('http://www.example.com/about');
261+
allow($this->router)->toReceive('match')->andReturn($match);
262+
allow($this->request)->toReceive('getUri', 'getScheme')->andReturn('http');
263+
allow($this->request)->toReceive('getUri', 'withScheme', '__toString')->andReturn('https://www.example.com/about');
264+
265+
allow($this->response)->toReceive('withStatus')->andReturn($this->response);
266+
267+
$listener = new ForceHttps(
268+
[
269+
'enable' => true,
270+
'force_all_routes' => true,
271+
'strict_transport_security' => [
272+
'enable' => true,
273+
'value' => 'max-age=31536000',
274+
],
275+
'add_www_prefix' => false,
276+
'remove_www_prefix' => true,
277+
],
278+
$this->router
279+
);
280+
281+
$listener->__invoke($this->request, $this->response, function () {});
282+
283+
expect($this->response)->toReceive('withStatus')->with(308);
284+
expect($this->response)->toReceive('withHeader')->with('Location', 'https://example.com/about');
285+
286+
});
287+
251288
});
252289

253290
});

src/HttpsTrait.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,24 @@ private function withWwwPrefixWhenRequired($httpsRequestUri)
8282

8383
return \substr_replace($httpsRequestUri, 'www.', 8, 0);
8484
}
85+
86+
private function withoutWwwPrefixWhenNotRequired($httpsRequestUri)
87+
{
88+
if (isset($this->config['add_www_prefix']) && $this->config['add_www_prefix'] === true) {
89+
return $httpsRequestUri;
90+
}
91+
92+
if (
93+
! isset($this->config['remove_www_prefix']) ||
94+
! $this->config['remove_www_prefix'] ||
95+
(
96+
$this->config['remove_www_prefix'] === true &&
97+
\substr($httpsRequestUri, 8, 4) !== 'www.'
98+
)
99+
) {
100+
return $httpsRequestUri;
101+
}
102+
103+
return \substr_replace($httpsRequestUri, '', 8, 4);
104+
}
85105
}

src/Listener/ForceHttps.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,16 @@ public function forceHttpsScheme(MvcEvent $e)
9494
if ($this->isSchemeHttps($uriScheme)) {
9595
$uriString = $uri->toString();
9696
$httpsRequestUri = $this->withWwwPrefixWhenRequired($uriString);
97+
$httpsRequestUri = $this->withoutWwwPrefixWhenNotRequired($httpsRequestUri);
98+
9799
if ($uriString === $httpsRequestUri) {
98100
return;
99101
}
100102
}
101103

102104
if (! isset($httpsRequestUri)) {
103105
$httpsRequestUri = $this->withWwwPrefixWhenRequired($uri->setScheme('https')->toString());
106+
$httpsRequestUri = $this->withoutWwwPrefixWhenNotRequired($httpsRequestUri);
104107
}
105108

106109
// 307 keeps headers, request method, and request body

src/Middleware/ForceHttps.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res
6969
if ($this->isSchemeHttps($uriScheme)) {
7070
$uriString = $uri->__toString();
7171
$httpsRequestUri = $this->withWwwPrefixWhenRequired($uriString);
72+
$httpsRequestUri = $this->withoutWwwPrefixWhenNotRequired($httpsRequestUri);
73+
7274
if ($uriString === $httpsRequestUri) {
7375
return $next($request, $response);
7476
}
@@ -77,6 +79,7 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res
7779
if (! isset($httpsRequestUri)) {
7880
$newUri = $uri->withScheme('https');
7981
$httpsRequestUri = $this->withWwwPrefixWhenRequired($newUri->__toString());
82+
$httpsRequestUri = $this->withoutWwwPrefixWhenNotRequired($httpsRequestUri);
8083
}
8184

8285
// 308 keeps headers, request method, and request body

0 commit comments

Comments
 (0)