Skip to content

Commit 049fe78

Browse files
author
Igor Melnikov
committed
Merge remote-tracking branch 'origin/MAGETWO-52923-Varnish-ssl' into pr
2 parents 81b4fc4 + 3446a1e commit 049fe78

File tree

13 files changed

+174
-87
lines changed

13 files changed

+174
-87
lines changed

app/code/Magento/PageCache/Model/Config.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,13 @@ protected function _getReplacements()
147147
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
148148
),
149149
'/* {{ ips }} */' => $this->_getAccessList(),
150-
'/* {{ design_exceptions_code }} */' => $this->_getDesignExceptions()
150+
'/* {{ design_exceptions_code }} */' => $this->_getDesignExceptions(),
151+
// http headers get transformed by php `X-Forwarded-Proto: https` becomes $SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'
152+
// Apache and Nginx drop all headers with underlines by default.
153+
'/* {{ ssl_offloaded_header }} */' => str_replace('_', '-', $this->_scopeConfig->getValue(
154+
\Magento\Framework\HTTP\PhpEnvironment\Request::XML_PATH_OFFLOADER_HEADER,
155+
\Magento\Store\Model\ScopeInterface::SCOPE_STORE))
156+
151157
];
152158
}
153159

app/code/Magento/PageCache/Observer/ProcessLayoutRenderElement.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ protected function _wrapEsi(
5959
'handles' => json_encode($layout->getUpdate()->getHandles())
6060
]
6161
);
62+
// Varnish does not support esi over https must change to http
63+
$url = (substr($url, 0, 5) === 'https') ? 'http' . substr($url, 5) : $url;
6264
return sprintf('<esi:include src="%s" />', $url);
6365
}
6466

app/code/Magento/PageCache/etc/varnish3.vcl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import std;
22
# The minimal Varnish version is 3.0.5
3+
# For SSL offloading, pass the following header in your proxy server or load balancer: '/* {{ ssl_offloaded_header }} */: https'
4+
35

46
backend default {
57
.host = "/* {{ host }} */";
@@ -61,6 +63,7 @@ sub vcl_recv {
6163
# static files are always cacheable. remove SSL flag and cookie
6264
if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") {
6365
unset req.http.Https;
66+
unset req.http./* {{ ssl_offloaded_header }} */;
6467
unset req.http.Cookie;
6568
}
6669

@@ -73,6 +76,10 @@ sub vcl_hash {
7376
if (req.http.cookie ~ "X-Magento-Vary=") {
7477
hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "\1"));
7578
}
79+
80+
if (req.http./* {{ ssl_offloaded_header }} */) {
81+
hash_data(req.http./* {{ ssl_offloaded_header }} */);
82+
}
7683
/* {{ design_exceptions_code }} */
7784
}
7885

app/code/Magento/PageCache/etc/varnish4.vcl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ vcl 4.0;
22

33
import std;
44
# The minimal Varnish version is 4.0
5+
# For SSL offloading, pass the following header in your proxy server or load balancer: '/* {{ ssl_offloaded_header }} */: https'
56

67
backend default {
78
.host = "/* {{ host }} */";
@@ -74,6 +75,7 @@ sub vcl_recv {
7475
# static files are always cacheable. remove SSL flag and cookie
7576
if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") {
7677
unset req.http.Https;
78+
unset req.http./* {{ ssl_offloaded_header }} */;
7779
unset req.http.Cookie;
7880
}
7981

@@ -93,8 +95,8 @@ sub vcl_hash {
9395
}
9496

9597
# To make sure http users don't see ssl warning
96-
if (req.http.X-Forwarded-Proto) {
97-
hash_data(req.http.X-Forwarded-Proto);
98+
if (req.http./* {{ ssl_offloaded_header }} */) {
99+
hash_data(req.http./* {{ ssl_offloaded_header }} */);
98100
}
99101
/* {{ design_exceptions_code }} */
100102
}

app/code/Magento/Store/etc/config.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
<base_link_url>{{secure_base_url}}</base_link_url>
7777
<use_in_frontend>0</use_in_frontend>
7878
<use_in_adminhtml>0</use_in_adminhtml>
79-
<offloader_header>SSL_OFFLOADED</offloader_header>
79+
<offloader_header>X-Forwarded-Proto</offloader_header>
8080
</secure>
8181
<session>
8282
<use_remote_addr>0</use_remote_addr>

app/code/Magento/Webapi/Test/Unit/Controller/SoapTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,16 @@ class SoapTest extends \PHPUnit_Framework_TestCase
4949
*/
5050
protected $_appStateMock;
5151

52+
53+
protected $_appconfig;
5254
/**
5355
* Set up Controller object.
5456
*/
5557
protected function setUp()
5658
{
5759
parent::setUp();
60+
61+
$objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
5862

5963
$this->_soapServerMock = $this->getMockBuilder('Magento\Webapi\Model\Soap\Server')
6064
->disableOriginalConstructor()
@@ -95,6 +99,15 @@ protected function setUp()
9599
->method('getHeaders')
96100
->will($this->returnValue(new \Zend\Http\Headers()));
97101

102+
$appconfig = $this->getMock(\Magento\Framework\App\Config::class, [], [], '' , false);
103+
$objectManagerHelper->setBackwardCompatibleProperty(
104+
$this->_requestMock,
105+
'appConfig',
106+
$appconfig
107+
);
108+
109+
110+
98111
$this->_soapServerMock->expects($this->any())->method('setWSDL')->will($this->returnSelf());
99112
$this->_soapServerMock->expects($this->any())->method('setEncoding')->will($this->returnSelf());
100113
$this->_soapServerMock->expects($this->any())->method('setReturnResponse')->will($this->returnSelf());

dev/tests/integration/testsuite/Magento/Store/Model/StoreTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ public function isUseStoreInUrlDataProvider()
372372
*
373373
* @param bool $expected
374374
* @param array $serverValues
375-
* @magentoConfigFixture current_store web/secure/offloader_header SSL_OFFLOADED
375+
* @magentoConfigFixture current_store web/secure/offloader_header X_FORWARDED_PROTO
376376
* @magentoConfigFixture current_store web/secure/base_url https://example.com:80
377377
*/
378378
public function testIsCurrentlySecure($expected, $serverValues)
@@ -391,8 +391,8 @@ public function isCurrentlySecureDataProvider()
391391
{
392392
return [
393393
[true, ['HTTPS' => 'on']],
394-
[true, ['SSL_OFFLOADED' => 'https']],
395-
[true, ['HTTP_SSL_OFFLOADED' => 'https']],
394+
[true, ['X_FORWARDED_PROTO' => 'https']],
395+
[true, ['HTTP_X_FORWARDED_PROTO' => 'https']],
396396
[true, ['HTTPS' => 'on', 'SERVER_PORT' => 80]],
397397
[false, ['SERVER_PORT' => 80]],
398398
[false, []],

lib/internal/Magento/Framework/App/Config/ScopePool.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,14 @@ private function getRequest()
9191
public function getScope($scopeType, $scopeCode = null)
9292
{
9393
$scopeCode = $this->_getScopeCode($scopeType, $scopeCode);
94-
$baseUrl = $this->getRequest()->getDistroBaseUrl();
95-
$code = $scopeType . '|' . $scopeCode . '|' . $baseUrl;
94+
95+
//Key by url to support dynamic {{base_url}} and port assignments
96+
$host = $this->getRequest()->getHttpHost();
97+
$port = $this->getRequest()->getServer('SERVER_PORT');
98+
$path = $this->getRequest()->getBasePath();
99+
$urlInfo = $host . $port . trim($path, '/');
100+
$code = $scopeType . '|' . $scopeCode . '|' . $urlInfo;
101+
96102
if (!isset($this->_scopes[$code])) {
97103
$cacheKey = $this->_cacheId . '|' . $code;
98104
$data = $this->_cache->load($cacheKey);

lib/internal/Magento/Framework/App/Request/Http.php

Lines changed: 7 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
namespace Magento\Framework\App\Request;
77

8-
use Magento\Framework\App\Config\ScopeConfigInterface;
98
use Magento\Framework\App\RequestInterface;
109
use Magento\Framework\App\RequestSafetyInterface;
1110
use Magento\Framework\App\Route\ConfigInterface\Proxy as ConfigInterface;
@@ -318,16 +317,14 @@ public function getDistroBaseUrl()
318317
{
319318
$headerHttpHost = $this->getServer('HTTP_HOST');
320319
$headerHttpHost = $this->converter->cleanString($headerHttpHost);
321-
$headerServerPort = $this->getServer('SERVER_PORT');
322320
$headerScriptName = $this->getServer('SCRIPT_NAME');
323-
$headerHttps = $this->getServer('HTTPS');
324321

325322
if (isset($headerScriptName) && isset($headerHttpHost)) {
326-
$secure = !empty($headerHttps)
327-
&& $headerHttps != 'off'
328-
|| isset($headerServerPort)
329-
&& $headerServerPort == '443';
330-
$scheme = ($secure ? 'https' : 'http') . '://';
323+
if ($secure = $this->isSecure()) {
324+
$scheme = 'https://';
325+
} else {
326+
$scheme = 'http://';
327+
}
331328

332329
$hostArr = explode(':', $headerHttpHost);
333330
$host = $hostArr[0];
@@ -403,29 +400,7 @@ public function __sleep()
403400
return [];
404401
}
405402

406-
/**
407-
* {@inheritdoc}
408-
*
409-
* @return bool
410-
*/
411-
public function isSecure()
412-
{
413-
if ($this->immediateRequestSecure()) {
414-
return true;
415-
}
416-
/* TODO: Untangle Config dependence on Scope, so that this class can be instantiated even if app is not
417-
installed MAGETWO-31756 */
418-
// Check if a proxy sent a header indicating an initial secure request
419-
$config = $this->objectManager->get('Magento\Framework\App\Config');
420-
$offLoaderHeader = trim(
421-
(string)$config->getValue(
422-
self::XML_PATH_OFFLOADER_HEADER,
423-
ScopeConfigInterface::SCOPE_TYPE_DEFAULT
424-
)
425-
);
426-
427-
return $this->initialRequestSecure($offLoaderHeader);
428-
}
403+
429404

430405
/**
431406
* {@inheritdoc}
@@ -442,28 +417,5 @@ public function isSafeMethod()
442417
return $this->isSafeMethod;
443418
}
444419

445-
/**
446-
* Checks if the immediate request is delivered over HTTPS
447-
*
448-
* @return bool
449-
*/
450-
protected function immediateRequestSecure()
451-
{
452-
$https = $this->getServer('HTTPS');
453-
return !empty($https) && ($https != 'off');
454-
}
455-
456-
/**
457-
* In case there is a proxy server, checks if the initial request to the proxy was delivered over HTTPS
458-
*
459-
* @param string $offLoaderHeader
460-
* @return bool
461-
*/
462-
protected function initialRequestSecure($offLoaderHeader)
463-
{
464-
$header = $this->getServer($offLoaderHeader);
465-
$httpHeader = $this->getServer('HTTP_' . $offLoaderHeader);
466-
return !empty($offLoaderHeader)
467-
&& (isset($header) && ($header === 'https') || isset($httpHeader) && ($httpHeader === 'https'));
468-
}
420+
469421
}

lib/internal/Magento/Framework/App/Test/Unit/Config/ScopePoolTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ protected function setUp()
5858
->disableOriginalConstructor()
5959
->setMethods(
6060
[
61-
'getDistroBaseUrl',
61+
'getBasePath',
6262
'getModuleName',
6363
'setModuleName',
6464
'getActionName',
@@ -68,14 +68,15 @@ protected function setUp()
6868
'setParams',
6969
'getCookie',
7070
'isSecure',
71+
'getServer'
7172
]
7273
)->getMock();
7374
$reflection = new \ReflectionClass(get_class($this->_object));
7475
$reflectionProperty = $reflection->getProperty('request');
7576
$reflectionProperty->setAccessible(true);
7677
$reflectionProperty->setValue($this->_object, $requestMock);
7778
$requestMock->expects($this->any())
78-
->method('getDistroBaseUrl')
79+
->method('getBasePath')
7980
->willReturn('baseUrl');
8081
}
8182

0 commit comments

Comments
 (0)