|
# common.vcl - Varnish Cache 4 Common Subroutines |
|
# Copyright (C) 2015 Matous Jan Fialka, <http://mjf.cz/> |
|
# Released under the terms of "The MIT License" |
|
|
|
vcl 4.0; |
|
|
|
import std; |
|
|
|
# |
|
# OPTIONS |
|
# |
|
sub setup |
|
{ |
|
set req.url = std.querysort(req.url); |
|
} |
|
|
|
sub cleanup |
|
{ |
|
unset resp.http.X-Tag; |
|
} |
|
|
|
# |
|
# COMMON |
|
# |
|
sub common_recv |
|
{ |
|
call setup; |
|
|
|
call pipe_non_rfc2616; |
|
|
|
call mangle_encoding; |
|
call mangle_cookie; |
|
|
|
call pass_non_head_get; |
|
call pass_login; # optional |
|
call pass_cookie; # optional |
|
|
|
call tag_all; # or any tag subroutines |
|
|
|
if(req.http.X-Tag ~ "(semi)?static") { |
|
unset req.http.Cookie; |
|
} |
|
} |
|
|
|
sub common_hash |
|
{ |
|
call hash_url; |
|
call hash_side; |
|
call hash_login; |
|
call hash_cookie; |
|
} |
|
|
|
sub common_deliver |
|
{ |
|
unset resp.http.Link; |
|
unset resp.http.Server; |
|
unset resp.http.Via; |
|
unset resp.http.X-Powered-By; |
|
unset resp.http.X-Varnish; |
|
|
|
call cleanup; |
|
} |
|
|
|
# |
|
# PIPE |
|
# |
|
sub pipe_non_rfc2616 |
|
{ |
|
if(req.method !~ "DELETE|GET|HEAD|OPTIONS|P(U|OS)T|TRACE") { |
|
return(pipe); |
|
} |
|
} |
|
|
|
sub pass_non_head_get |
|
{ |
|
if(req.http.method !~ "GET|HEAD") { |
|
return(pass); |
|
} |
|
} |
|
|
|
# |
|
# PASS |
|
# |
|
sub pass_login |
|
{ |
|
if(req.http.Authorization || req.http.Authenticate) { |
|
return(pass); |
|
} |
|
} |
|
|
|
sub pass_cookie |
|
{ |
|
if(req.http.Cookie) { |
|
return(pass); |
|
} |
|
} |
|
|
|
# |
|
# HASH |
|
# |
|
sub hash_url |
|
{ |
|
hash_data(req.url); |
|
} |
|
|
|
sub hash_side |
|
{ |
|
if(req.http.Host) { |
|
hash_data(req.http.Host); |
|
} else { |
|
hash_data(client.ip); |
|
} |
|
} |
|
|
|
sub hash_cookie |
|
{ |
|
if(req.http.Cookie) { |
|
hash_data(req.http.Cookie); |
|
} |
|
} |
|
|
|
sub hash_login |
|
{ |
|
if(req.http.Authorization) { |
|
hash_data(req.http.Authorization); |
|
} |
|
} |
|
|
|
# |
|
# UNSET |
|
# |
|
sub unset_empty_cookie |
|
{ |
|
if(req.http.Cookie && req.http.Cookie ~ "^[\s;]*$") { |
|
unset req.http.Cookie; |
|
} |
|
} |
|
|
|
# |
|
# MANGLE |
|
# |
|
sub mangle_cookie |
|
{ |
|
std.collect(req.http.Cookie); |
|
|
|
if(req.http.Cookie) { |
|
set req.http.Cookie = ";" + req.http.Cookie; |
|
set req.http.Cookie = |
|
regsuball(req.http.Cookie, "; +", ";"); |
|
set req.http.Cookie = |
|
regsuball(req.http.Cookie, ";COOKIE[^=]+=", "; \1="); |
|
set req.http.Cookie = |
|
regsuball(req.http.Cookie, ";[^ ][^;]*", ""); |
|
set req.http.Cookie = |
|
regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); |
|
} |
|
|
|
call unset_empty_cookie; |
|
} |
|
|
|
sub mangle_encoding |
|
{ |
|
std.collect(req.http.Accept-Encoding); |
|
|
|
if(req.http.Accept-Encoding) { |
|
if(req.http.Accept-Encoding ~ "gzip") { |
|
set req.http.Accept-Encoding = "gzip"; |
|
} elsif(req.http.Accept-Encoding ~ "deflate" && req.http.User-Agent !~ "MSIE") { |
|
set req.http.Accept-Encoding = "deflate"; |
|
} else { |
|
unset req.http.Accept-Encoding; |
|
} |
|
} |
|
} |
|
|
|
# |
|
# TAG |
|
# |
|
sub tag_all |
|
{ |
|
call tag_static; |
|
call tag_semistatic; |
|
} |
|
|
|
sub tag_static |
|
{ |
|
call tag_document; |
|
call tag_compressed; |
|
call tag_multimedial; |
|
call tag_web; |
|
|
|
if(req.http.X-Tag ~ "document|compressed|multimedial|web") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", static"; |
|
} else { |
|
set req.http.X-Tag = "static"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_document |
|
{ |
|
if(req.url ~ "(?i)\.(d(bk|(ocx|jvu?)?|vi)|e?ps|fb2|o(d[mpt]|t[pt]|xps)|p(cl|df|ps|ptx?)|rtf|sxw|tex|wp[dp7])$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", document"; |
|
} else { |
|
set req.http.X-Tag = "document"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_compressed |
|
{ |
|
if(req.url ~ "(?i)\.(cab|7z|a(ce|r[cj])|d(eb|mg)|jar|lz(h?|ip|o|ma)|pak|r(ar|pm)|(t(ar\.)?(gz|bz2))|(tar\.)?xz)|z(oo|ip)?$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", compressed"; |
|
} else { |
|
set req.http.X-Tag = "compressed"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_multimedial |
|
{ |
|
call tag_audio; |
|
call tag_video; |
|
call tag_image; |
|
call tag_stream; |
|
call tag_compound; |
|
|
|
if(req.http.X-Tag ~ "(audi|vide)o|image|compound") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", multimedial"; |
|
} else { |
|
set req.http.X-Tag = "multimedial"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_audio |
|
{ |
|
if(req.url ~ "(?i)\.(aif|iff|m(3u|4a|id|p[3a])|ra|w(av|ma))$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", audio"; |
|
} else { |
|
set req.http.X-Tag = "audio"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_video |
|
{ |
|
if(req.url ~ "(?i)\.(3g[2p]|a(s[fx]|vi)|flv|m(ov|mpe?g)|nsv|rm|vob|wmv)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", video"; |
|
} else { |
|
set req.http.X-Tag = "video"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_image |
|
{ |
|
call tag_bitmap; |
|
call tag_vector; |
|
|
|
if(req.http.X-Tag ~ "bitmap|vector") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", image"; |
|
} else { |
|
set req.http.X-Tag = "image"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_bitmap |
|
{ |
|
if(req.url ~ "(?i)\.(b(mp|pg)|gif|ic[bo]|jpe?g|mng|p(cx|[bgnp]m|n[gs]|i?ct|ix)|raw|t(iff?|(ar)?ga)|v(da|st)|webp|xpm)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", bitmap"; |
|
} else { |
|
set req.http.X-Tag = "bitmap"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_vector |
|
{ |
|
if(req.url ~ "(?i)\.(ai|drw|e?ps|svg|wrl)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", vector"; |
|
} else { |
|
set req.http.X-Tag = "vector"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_stream |
|
{ |
|
if(req.url ~ "(?i)\.(flv|vob|nsv)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", video"; |
|
} else { |
|
set req.http.X-Tag = "video"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_compound |
|
{ |
|
if(req.url ~ "(?i)\.(e?ps|p(df|ict)|swf)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", compound"; |
|
} else { |
|
set req.http.X-Tag = "compound"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_web |
|
{ |
|
call tag_markup; |
|
call tag_stylesheet; |
|
call tag_script; |
|
call tag_feed; |
|
call tag_font; |
|
|
|
if(req.http.X-Tag ~ "markup|s(tylesheet|cript)|f(eed|ont)") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", web"; |
|
} else { |
|
set req.http.X-Tag = "web"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_markup |
|
{ |
|
if(req.url ~ "(?i)\.(html?[45]|x(ht)?ml)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", markup"; |
|
} else { |
|
set req.http.X-Tag = "markup"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_stylesheet |
|
{ |
|
if(req.url ~ "(?i)\.css[1-3]?$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", stylesheet"; |
|
} else { |
|
set req.http.X-Tag = "stylesheet"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_script |
|
{ |
|
if(req.url ~ "(?i)\.js$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", script"; |
|
} else { |
|
set req.http.X-Tag = "script"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_feed |
|
{ |
|
if(req.url ~ "(?i)\.(atom|rss)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", feed"; |
|
} else { |
|
set req.http.X-Tag = "feed"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_font |
|
{ |
|
if(req.url ~ "(?i)\.(afm|eot|f(nt|ond?)|([ot]t|pc)f|pf[abm]|t(fm|t[fc])|woff)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", font"; |
|
} else { |
|
set req.http.X-Tag = "font"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_semistatic |
|
{ |
|
call tag_parameter; |
|
call tag_interpreter; |
|
|
|
if(req.http.X-Tag ~ "(param|interpr)eter") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", semistatic"; |
|
} else { |
|
set req.http.X-Tag = "semistatic"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_parameter |
|
{ |
|
if(req.url ~ "\?") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", parameter"; |
|
} else { |
|
set req.http.X-Tag = "parameter"; |
|
} |
|
} |
|
} |
|
|
|
sub tag_interpreter |
|
{ |
|
if(req.url ~ "(?i)\.(f?cgi|[aj]sp|p(hp[3-5]s?|[yl])|rb|sh|tcl)$") { |
|
if(req.http.X-Tag) { |
|
set req.http.X-Tag = |
|
req.http.X-Tag + ", interpreter"; |
|
} else { |
|
set req.http.X-Tag = "interpreter"; |
|
} |
|
} |
|
} |