Skip to content

Instantly share code, notes, and snippets.

@a-vasyliev
Created March 25, 2015 11:42
Show Gist options
  • Save a-vasyliev/de8ffc6c6aa74cdeadfe to your computer and use it in GitHub Desktop.
Save a-vasyliev/de8ffc6c6aa74cdeadfe to your computer and use it in GitHub Desktop.
Nginx: proxy cache without utm_* parameters (remove query parameter, remove utm tags nginx)
server {
listen 443;
server_name example.com;
error_log /var/log/nginx/example_com_error.log warn;
ssl on;
ssl_certificate /etc/nginx/ssl/your.crt; #certificate chains
ssl_certificate_key /etc/nginx/ssl/your.key; #private key
# enable compressing if needed
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
root /var/www/your/root;
# most interesting part
# here I remove utm_source, utm_content, utm_term, utm_campaign, utm_medium query parameters
set $c_uri $args; # e.g. "param1=true&param4=false"
if ($c_uri ~ (.*)(?:&|^)utm_source=[^&]*(.*)) {
set $c_uri $1$2;
}
if ($c_uri ~ (.*)(?:&|^)utm_term=[^&]*(.*)) {
set $c_uri $1$2;
}
if ($c_uri ~ (.*)(?:&|^)utm_campaign=[^&]*(.*)) {
set $c_uri $1$2;
}
if ($c_uri ~ (.*)(?:&|^)utm_medium=[^&]*(.*)) {
set $c_uri $1$2;
}
if ($c_uri ~ (.*)(?:&|^)utm_content=[^&]*(.*)) {
set $c_uri $1$2;
}
if ($c_uri ~ ^&(.*)) {
set $c_uri $1;
}
set $c_uri $is_args$c_uri;
if ($c_uri ~ ^\?$) {
set $c_uri "";
}
# finally we have stripped out utms and has nice cache key
set $c_uri $uri$c_uri;
# my injected script, hosted on frontend (nginx)
location /hack.js {
}
# never cache /checkout/*
location /checkout/ {
proxy_pass http://backend-server.com:80/checkout/;
include proxy.conf;
proxy_no_cache 1;
}
# cache every page and static file
location / {
# I'm using "cleaned_uri" ($c_uri) for backend also
proxy_pass http://backend-server.com:80$c_uri;
# our proxy config
include proxy.conf;
# for debugging, just to ensure that $c_uri is correct
add_header X-CACHE-KEY $c_uri;
# set $c_uri as cache_key
proxy_cache_key $c_uri;
}
}
# server to force http -> https redirect
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
# server to remove www
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
### .... ###
# Enable cache in /etc/nginx/nginx.conf
proxy_cache_path /usr/data/nginx/cache levels=1:2 keys_zone=cache:8m max_size=1000m inactive=180m;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
proxy_cache_valid 404 1m;
proxy_cache_valid 200 360m;
### .... ###
# change backend redirects (http -> https)
proxy_redirect http://example.com https://example.com;
# proxy host, real IP address, etc. for backend
# Accept-Encoding is set to "" because in my case content is gzipped, but I need to apply subs_filter directives
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Accept-Encoding "";
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
# replace content received from backend
# I'm replacing all http: to https:
subs_filter_types application/json; # to replace json also
subs_filter "http:" "https:" gi;
# inject some Javascript, for example
subs_filter "</body>" "<script type=\"text/javascript\" src=\"//example.com/hack.js\"></script></body>";
# output cache status element, I'm hidding it afterwards, but my injected Javascript uses this data
subs_filter "</body>" "<div id='cache-status'>$upstream_cache_status</div></body>";
# setup cache zone
proxy_cache cache;
# cache all pages from backend, ignore headers. This headers prevents caching. Be carefull with it.
proxy_ignore_headers Cache-Control Expires;
# Bypass page cache if header "SECRET_HEADER 1" was sent to Nginx
proxy_cache_bypass $http_secret_header;
# Service information, adds header with page cache status (MISS, HIT, BYPASS, etc.)
add_header X-Cache-Status $upstream_cache_status;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment