Mapping SSI when using proxies on nginx and dividing the cache by language
Configured caching on a bunch of nginx + apache on a server running Ubuntu. I would like to share with some of the nuances with which I encountered in the process of work. And there is the problem of displaying ssi instructions for nginx and sharing the cache based on language cookies.
I decided to use ssi to display dynamic blocks. On the local machine, everything worked fine, but after the upload to the ssi server, the blocks were not processed.
As a proxy web server, Apache is used. After a series of experiments, I found that when using fastcgi, ssi blocks were processed perfectly. That is, the problem is in the apache proxy server.
I began to analyze the Apache headers on the local machine and on the server:
Noticed an interesting title.
Found a description here . That is, I can send headers to set compression:
That is, the proxy server gave the content in a compressed form and nginx could not parse ssi instructions.
For compression on Apache, mod_deflate is responsible. All this can be treated by disabling this module:
On the site that I set up, the language is set using cookies, that is, there are no unique URLs (this is already for SEO :)).
To split the cache for different languages, I used the key:
Pay attention to the last parameter $ lang. To install it, I used ngx_http_map_module:
The first directive determines the language of the browser and then is used in the second by default in the absence of a language cookie. Note that mod needs to be added to the http context, in my case it was before the server.
Now you guarantee that the user will not receive a page from the cache in a language unknown to him.
Problems displaying SSI when using proxies on nginx
I decided to use ssi to display dynamic blocks. On the local machine, everything worked fine, but after the upload to the ssi server, the blocks were not processed.
As a proxy web server, Apache is used. After a series of experiments, I found that when using fastcgi, ssi blocks were processed perfectly. That is, the problem is in the apache proxy server.
I began to analyze the Apache headers on the local machine and on the server:
$curl -I http://apache_host:port
Noticed an interesting title.
Vary: Accept-Encoding
Found a description here . That is, I can send headers to set compression:
$curl -I -H 'Accept-Encoding: gzip,deflate' http://apache_host:port
...
Content-Encoding: gzip
...
That is, the proxy server gave the content in a compressed form and nginx could not parse ssi instructions.
For compression on Apache, mod_deflate is responsible. All this can be treated by disabling this module:
$a2dismod deflate
Module deflate disabled.
Run '/etc/init.d/apache2 restart' to activate new configuration!
$/etc/init.d/apache2 restart
Setting language cache separation
On the site that I set up, the language is set using cookies, that is, there are no unique URLs (this is already for SEO :)).
To split the cache for different languages, I used the key:
proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri|$lang";
Pay attention to the last parameter $ lang. To install it, I used ngx_http_map_module:
map $http_accept_language $browser_lang {
default en;
~ru ru;
~da da;
~de de;
}
map $cookie_name_of_language_cookie $lang {
default $browser_lang;
~en en;
~de de;
~ru ru;
~da da;
}
server {
...........
}
The first directive determines the language of the browser and then is used in the second by default in the absence of a language cookie. Note that mod needs to be added to the http context, in my case it was before the server.
Now you guarantee that the user will not receive a page from the cache in a language unknown to him.