-
-
Save seyhunak/8920682 to your computer and use it in GitHub Desktop.
Varnish - Mobile Dedection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
backend default { | |
.host = "127.0.0.1"; | |
.port = "8080"; | |
.connect_timeout = 600s; | |
.first_byte_timeout = 600s; | |
.between_bytes_timeout = 600s; | |
} | |
acl purge { | |
"localhost"; | |
"127.0.0.1"; | |
} | |
sub vcl_recv { | |
if (req.request == "GET" && req.url ~ "^/varnishcheck$") { | |
error 200 "Varnish is Ready"; | |
} | |
# Add a unique header containing the client address. | |
set req.http.X-Forwarded-For = client.ip; | |
if (req.request != "GET" && | |
req.request != "HEAD" && | |
req.request != "PUT" && | |
req.request != "POST" && | |
req.request != "TRACE" && | |
req.request != "OPTIONS" && | |
req.request != "PURGE" && | |
req.request != "DELETE") { | |
# Non-RFC2616 or CONNECT which is weird. | |
return (pipe); | |
} | |
# We only deal with GET, PURGE and HEAD by default. | |
if (req.request != "GET" && req.request != "HEAD" && req.request != "PURGE") { | |
return (pass); | |
} | |
# --- PURGE --- | |
if (req.request == "PURGE") { | |
# Check if the ip coresponds with the acl purge | |
if (!client.ip ~ purge) { | |
# Return error code 405 (Forbidden) when not | |
error 405 "Not allowed."; | |
} | |
return (lookup); | |
} | |
# --- PASSTHROUGH --- | |
# Always cache things with these extensions. | |
if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") { | |
unset req.http.cookie; | |
return (lookup); | |
} | |
# Do not cache if HTTP authorized. | |
if (req.http.Authorization) { | |
return (pass); | |
} | |
# Skip the Varnish cache for install, update, and cron. | |
if (req.url ~ "install\.php|update\.php|cron\.php") { | |
return (pass); | |
} | |
# Skip the Varnish cache for Springboard standalone cron. | |
if (req.url ~ "queue_processor_cron|fundraiser_cron") { | |
return (pass); | |
} | |
# Pass server-status. | |
if (req.url ~ ".*/server-status$") { | |
return (pass); | |
} | |
# Check for mobile. | |
call mobile_detection; | |
# Support for Pressflow Cookie-Cache Bypass. | |
if (req.http.cookie ~ "NO_CACHE") { | |
return (pass); | |
} | |
# Force lookup if the request is a no-cache request from the client. | |
if (req.http.Cache-Control ~ "no-cache") { | |
return (pass); | |
} | |
# Don't check cache if Drupal SESSION is set. | |
if (req.http.cookie ~ "SESS") { | |
return (pass); | |
} | |
# We "hide" the non-session cookies. | |
if (req.http.cookie) { | |
set req.http.X-Varnish-Cookie = req.http.cookie; | |
unset req.http.cookie; | |
} | |
# --- MISC --- | |
# Normalize the Accept-Encoding header | |
# as per: http://varnish-cache.org/wiki/FAQ/Compression | |
if (req.http.Accept-Encoding) { | |
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { | |
# No point in compressing these. | |
unset req.http.Accept-Encoding; | |
} | |
else if (req.http.Accept-Encoding ~ "gzip") { | |
set req.http.Accept-Encoding = "gzip"; | |
} | |
else if (req.http.Accept-Encoding ~ "deflate") { | |
# Next, try deflate if it is supported. | |
set req.http.Accept-Encoding = "deflate"; | |
} | |
else { | |
# Unknown or deflate algorithm. | |
unset req.http.Accept-Encoding; | |
} | |
} | |
# Let's have a little grace. | |
set req.grace = 5m; | |
return (lookup); | |
} | |
sub vcl_hash { | |
if (req.http.cookie) { | |
hash_data(req.http.cookie); | |
} | |
} | |
# Strip any cookies before an image/js/css is inserted into cache. | |
sub vcl_fetch { | |
set beresp.grace = 5m; | |
# These status codes should always pass through and never cache. | |
if (beresp.status == 503 || beresp.status == 500) { | |
set beresp.http.X-Cacheable = "NO: obj.status"; | |
set beresp.http.X-Cacheable-status = beresp.status; | |
return (hit_for_pass); | |
} | |
if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)(\?[a-z0-9]+)?$") { | |
unset beresp.http.set-cookie; | |
} | |
else if (beresp.http.Cache-Control) { | |
unset beresp.http.Expires; | |
} | |
if (beresp.status == 301) { | |
set beresp.ttl = 1h; | |
return(deliver); | |
} | |
# All tests passed, therefore item is cacheable | |
set beresp.http.X-Cacheable = "YES"; | |
} | |
include "devicedetect.vcl"; | |
sub mobile_detection { | |
# Set the default to PC. | |
set req.http.X-Varnish-Device = "pc"; | |
# Test the user agent for mobile devices. | |
# @see https://github.com/varnish/varnish-devicedetect | |
call devicedetect; | |
if (req.http.X-UA-Device ~ "^mobile") { | |
# Lump all mobile-style devices together. | |
set req.http.X-Varnish-Device = "mobile"; | |
} | |
# Test the URL for mobile paths. | |
if (req.http.X-Varnish-Device == "mobile" && req.url !~ "^/((secure|donate|blog)/?.*)?$") { | |
# If not in the allowed paths, change back to PC. | |
set req.http.X-Varnish-Device = "pc"; | |
} | |
# Force to PC when skipMobileDetection cookie is set. | |
if (req.http.cookie ~ "skipMobileDetection") { | |
set req.http.X-Varnish-Device = "pc"; | |
} | |
# Redirect to mobile site if not already there. | |
if (req.http.X-Varnish-Device == "mobile" && req.http.host !~ "^m\.") { | |
error 750 "m.irc" + req.url; | |
} | |
# Redirect to normal site if not already there. | |
else if (req.http.X-Varnish-Device == "pc" && req.http.host ~ "^m\.") { | |
error 750 "irc" + req.url; | |
} | |
} | |
# Set a header to track a cache HIT/MISS. | |
sub vcl_deliver { | |
if (obj.hits > 0) { | |
set resp.http.X-Varnish-Cache = "HIT"; | |
set resp.http.X-Varnish-Hits = obj.hits; | |
} | |
else { | |
set resp.http.X-Varnish-Cache = "MISS"; | |
} | |
# Set a header to track the webhead. | |
set resp.http.X-Varnish-IP = server.ip; | |
} | |
sub vcl_hit { | |
if (req.request == "PURGE") { | |
purge; | |
error 200 "Purged."; | |
} | |
} | |
sub vcl_miss { | |
if (req.http.X-Varnish-Cookie) { | |
set bereq.http.cookie = req.http.X-Varnish-Cookie; | |
unset bereq.http.X-Varnish-Cookie; | |
} | |
if (req.request == "PURGE") { | |
purge; | |
error 200 "Purged."; | |
} | |
} | |
sub vcl_error { | |
# Do any redirects necessary. | |
if (obj.status == 750) { | |
set obj.http.Location = "http://" + obj.response; | |
set obj.status = 302; | |
return (deliver); | |
} | |
# Let's deliver a friendlier error page. | |
set obj.http.Content-Type = "text/html; charset=utf-8"; | |
synthetic {" | |
<?xml version="1.0" encoding="utf-8"?> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
<html> | |
<head> | |
<title>"} + obj.status + " " + obj.response + {"</title> | |
</head> | |
<body> | |
<div id="page"> | |
<h1>Page Could Not Be Loaded</h1> | |
<p>We're very sorry, but the page could not be loaded properly. This should be fixed very soon, and we apologize for any inconvenience.</p> | |
<hr /> | |
<h4>Debug Info:</h4> | |
<pre>Status: "} + obj.status + {" | |
Response: "} + obj.response + {" | |
XID: "} + req.xid + {"</pre> | |
</div> | |
</body> | |
</html> | |
"}; | |
return (deliver); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# detectdevice.vcl - regex based device detection for Varnish | |
# http://github.com/varnish/varnish-devicedetect/ | |
# | |
# Author: Lasse Karstensen <[email protected]> | |
sub devicedetect { | |
unset req.http.X-UA-Device; | |
set req.http.X-UA-Device = "pc"; | |
if (req.http.User-Agent ~ "(?i)(ads|google|bing|msn|yandex|baidu|ro|career|)bot" || | |
req.http.User-Agent ~ "(?i)(baidu|symantec)spider" || | |
req.http.User-Agent ~ "(?i)scanner" || | |
req.http.User-Agent ~ "(?i)(web)crawler") { | |
set req.http.X-UA-Device = "bot"; } | |
elsif (req.http.User-Agent ~ "(?i)ip(hone|od)") { set req.http.X-UA-Device = "mobile-iphone"; } | |
elsif (req.http.User-Agent ~ "(?i)ipad") { set req.http.X-UA-Device = "tablet-ipad"; } | |
# how do we differ between an android phone and an android tablet? | |
# http://stackoverflow.com/questions/5341637/how-do-detect-android-tablets-in-general-useragent | |
elsif (req.http.User-Agent ~ "(?i)android.*(mobile|mini)") { set req.http.X-UA-Device = "mobile-android"; } | |
# android 3/honeycomb was just about tablet-only, and any phones will probably handle a bigger page layout. | |
elsif (req.http.User-Agent ~ "(?i)android 3") { set req.http.X-UA-Device = "tablet-android"; } | |
# may very well give false positives towards android tablets. Suggestions welcome. | |
elsif (req.http.User-Agent ~ "(?i)android") { set req.http.X-UA-Device = "tablet-android"; } | |
elsif (req.http.User-Agent ~ "^HTC" || | |
req.http.User-Agent ~ "Fennec" || | |
req.http.User-Agent ~ "IEMobile" || | |
req.http.User-Agent ~ "BlackBerry" || | |
req.http.User-Agent ~ "SymbianOS.*AppleWebKit" || | |
req.http.User-Agent ~ "Opera Mobi") { | |
set req.http.X-UA-Device = "mobile-smartphone"; | |
} | |
elsif (req.http.User-Agent ~ "(?i)symbian" || | |
req.http.User-Agent ~ "(?i)^sonyericsson" || | |
req.http.User-Agent ~ "(?i)^nokia" || | |
req.http.User-Agent ~ "(?i)^samsung" || | |
req.http.User-Agent ~ "(?i)^lg" || | |
req.http.User-Agent ~ "(?i)bada" || | |
req.http.User-Agent ~ "(?i)blazer" || | |
req.http.User-Agent ~ "(?i)cellphone" || | |
req.http.User-Agent ~ "(?i)iemobile" || | |
req.http.User-Agent ~ "(?i)midp-2.0" || | |
req.http.User-Agent ~ "(?i)u990" || | |
req.http.User-Agent ~ "(?i)netfront" || | |
req.http.User-Agent ~ "(?i)opera mini" || | |
req.http.User-Agent ~ "(?i)palm" || | |
req.http.User-Agent ~ "(?i)nintendo wii" || | |
req.http.User-Agent ~ "(?i)playstation portable" || | |
req.http.User-Agent ~ "(?i)portalmmm" || | |
req.http.User-Agent ~ "(?i)proxinet" || | |
req.http.User-Agent ~ "(?i)sonyericsson" || | |
req.http.User-Agent ~ "(?i)symbian" || | |
req.http.User-Agent ~ "(?i)windows\ ?ce" || | |
req.http.User-Agent ~ "(?i)winwap" || | |
req.http.User-Agent ~ "(?i)eudoraweb" || | |
req.http.User-Agent ~ "(?i)htc" || | |
req.http.User-Agent ~ "(?i)240x320" || | |
req.http.User-Agent ~ "(?i)avantgo") { | |
set req.http.X-UA-Device = "mobile-generic"; | |
} | |
# handle overrides | |
if (req.http.Cookie ~ "(i?)X-UA-Device-force") { | |
# ;?? means zero or one ;, non-greedy to match the first. | |
set req.http.X-UA-Device = regsub(req.http.Cookie, "(?i).*X-UA-Device-force=([^;]+);??.*", "\1"); | |
} | |
} | |
# vim: sw=4:tw=120 # meh |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment