-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Description
Description
Remote Varnish server behind Nginx or AWS Load Balancer does not receive Magento's PURGE requests. Using tcpdump I have verified that Magento is sending the purge request. See the sample request and a more detailed explanation in the Additional Information section.
Preconditions
Magento 2.1.2
Remote Varnish server behind AWS Load Balancer or Nginx
Steps to reproduce
- Configure Magento to use remote Varnish server
- Run tcpflow on Magento server to verify request/response.
Example:tcpflow -p -c -i eth0 port 80
- Execute a cache clear from Magento's CLI or Admin interface
Expected result
Magento sends PURGE request to Varnish. Varnish receives PURGE request and returns a 200.
Actual result
Varnish is not receiving PURGE request and a 400 is returned.
Additional Information
Magento purge request to Varnish behind an elastic load balancer
172.017.000.002.33792-034.192.024.059.00080: PURGE / HTTP/1.1
X-Magento-Tags-Pattern: .*
052.005.058.068.00080-172.017.000.002.38246: HTTP/1.1 400 BAD_REQUEST
Content-Length: 0
Connection: Close
Magento purge request to Varnish behind Nginx
172.017.000.002.34748-054.243.013.129.00080: PURGE / HTTP/1.1
X-Magento-Tags-Pattern: .*
054.243.013.129.00080-172.017.000.002.34748: HTTP/1.1 400 Bad Request
Server: nginx/1.11.5
Date: Tue, 29 Nov 2016 16:43:54 GMT
Content-Type: text/html
Content-Length: 173
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.11.5</center>
</body>
</html>
As you can see, a 400 is returned in both cases.
I believe this is because both Nginx and AWS's load balancers are adhering to RFC 7230 which states:
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
Proposed solution
Add the host header to the purge request.
One way of accomplishing that is to insert this code on line 61 of app/code/Magento/CacheInvalidate/Model/PurgeCache.php
$headers['Host'] = $server->getHost();
Let me know if this is an acceptable solution and I'll submit a PR.