├── .gitignore ├── LICENSE ├── README.md ├── arch.jpg ├── conf.json ├── init.lua ├── load_conf.lua ├── router.lua └── wpt.conf /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Lua sources 2 | luac.out 3 | 4 | # luarocks build files 5 | *.src.rock 6 | *.zip 7 | *.tar.gz 8 | 9 | # Object files 10 | *.o 11 | *.os 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | *.def 26 | *.exp 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Khalid Lafi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ngx_wpt 2 | 3 | ngx_wpt is a plugin for NGINX that extends it to be able to route the incoming traffic for the WebPageTest instances between multiple servers allowing WPT to scale horizontality. 4 | 5 | ## Features 6 | 7 | - Balzingly fast reverse-proxy and load balancer ( Thanks to NGINX ) 8 | - Zero-downtime reload of ngx_wpt configurations 9 | - The ability to share the test agents between more than one WPT server. By sending them to ngx_wpt instead of directly hiting a WPT server. 10 | 11 | 12 | ## Table of content 13 | - [How does it work?](#how-does-it-work-) 14 | - [Installation](#installation) 15 | - [Configuring ngx_wpt](#configuring-ngx_wpt) 16 | 17 | 18 | # How Does It Work? 19 | 20 | ![ngx_wpt architecture](https://raw.githubusercontent.com/lafikl/ngx_wpt/master/arch.jpg) 21 | 22 | All of the incoming traffic should be sent to ngx_wpt which will determine based on multiple factors who will serve that request from the pool of WPT servers. 23 | 24 | **Request routing procedure**: 25 | - If a request contains a test ID then ngx_wpt will check its WPT servers pool (as defined in /etc/wpt/conf.json) to see if it matches any, if so then it will send that request to it. 26 | - Otherwise ngx_wpt will perform a round-robin algorithm to load balance the workload. 27 | 28 | 29 | 30 | # Installation 31 | This is a guide for Ubuntu 14.04. 32 | 33 | ### Install Prerequisites 34 | 35 | - `sudo apt-get install build-essential libpcre3-dev libssl-dev git zip` 36 | - `sudo apt-get install nginx` 37 | 38 | ### Install OpenResty 39 | 40 | - `wget http://openresty.org/download/ngx_openresty-1.7.10.1.tar.gz` 41 | - `tar xzvf ngx_openresty-1.7.10.1.tar.gz` 42 | - ```cd ngx_openresty-1.7.10.1/``` 43 | 44 | ``` 45 | sudo ./configure \ 46 | --sbin-path=/usr/sbin/nginx \ 47 | --conf-path=/etc/nginx/nginx.conf \ 48 | --error-log-path=/var/log/nginx/error.log \ 49 | --http-client-body-temp-path=/var/lib/nginx/body \ 50 | --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \ 51 | --http-log-path=/var/log/nginx/access.log \ 52 | --http-proxy-temp-path=/var/lib/nginx/proxy \ 53 | --http-scgi-temp-path=/var/lib/nginx/scgi \ 54 | --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \ 55 | --lock-path=/var/lock/nginx.lock \ 56 | --pid-path=/var/run/nginx.pid \ 57 | --with-luajit \ 58 | --with-http_dav_module \ 59 | --with-http_flv_module \ 60 | --with-http_gzip_static_module \ 61 | --with-http_realip_module \ 62 | --with-http_stub_status_module \ 63 | --with-http_ssl_module \ 64 | --with-http_sub_module \ 65 | --with-ipv6 \ 66 | --with-sha1=/usr/include/openssl \ 67 | --with-md5=/usr/include/openssl \ 68 | --with-http_stub_status_module \ 69 | --with-http_secure_link_module \ 70 | --with-http_sub_module 71 | ``` 72 | 73 | - `sudo make` 74 | - `sudo make install` 75 | 76 | 77 | ### Install LuaRocks 78 | 79 | - `cd ~` 80 | - `wget http://keplerproject.github.io/luarocks/releases/luarocks-2.2.2.tar.gz` 81 | ``` 82 | sudo ./configure --prefix=/usr/local/openresty/luajit \ 83 | --with-lua=/usr/local/openresty/luajit/ \ 84 | --lua-suffix=jit-2.1.0-alpha \ 85 | --with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1 86 | ``` 87 | - `sudo make build && sudo make install` 88 | - `sudo make bootstrap` 89 | 90 | 91 | ### Install CJSON 92 | 93 | - `sudo ./usr/local/openresty/luajit/bin/luarocks install lua-cjson` 94 | 95 | ### Install ngx_wpt 96 | 97 | - `sudo mkdir /var/lib/ngx_wpt` 98 | - `sudo mkdir /etc/wpt` 99 | - `cd /var/lib/ngx_wpt` 100 | - `git clone https://github.com/lafikl/ngx_wpt.git .` 101 | - `sudo mv conf.json /etc/wpt` 102 | - `sudo mv wpt.conf /etc/nginx/conf.d/` 103 | - `sudo rm /etc/nginx/sites-enabled/default` 104 | - `sudo service nginx restart` 105 | 106 | # Configuring ngx_wpt 107 | 108 | - Edit `/etc/wpt/conf.json` by adding your WPT hosts IPs and the ID for each server. 109 | There's no limits for how many WPT hosts you can add to the config file as long as the IDs are unique. 110 | - Then run: `sudo nginx -s reload` 111 | Which will reload the configuration for ngx_wpt as well as NGINX configurations. **Without dropping requests**. 112 | 113 | 114 | 115 | # License 116 | The MIT License (MIT) 117 | 118 | Copyright (c) 2015 Khalid Lafi 119 | 120 | Permission is hereby granted, free of charge, to any person obtaining a copy 121 | of this software and associated documentation files (the "Software"), to deal 122 | in the Software without restriction, including without limitation the rights 123 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 124 | copies of the Software, and to permit persons to whom the Software is 125 | furnished to do so, subject to the following conditions: 126 | 127 | The above copyright notice and this permission notice shall be included in all 128 | copies or substantial portions of the Software. 129 | 130 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 131 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 132 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 133 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 134 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 135 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 136 | SOFTWARE. 137 | -------------------------------------------------------------------------------- /arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WPOTools/ngx_wpt/367a6681194e75dfb8e5c331c1ca43cd3cbcdcbc/arch.jpg -------------------------------------------------------------------------------- /conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosts": [ 3 | {"id": "B", "host": ""} 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | local c = require("load_conf") 2 | local config = c.get_conf("/etc/wpt/conf.json") 3 | local hosts = ngx.shared.hosts 4 | local len = 0 5 | 6 | local ch = config["hosts"] 7 | 8 | for host in ipairs(ch) do 9 | hosts:set(ch[host]["id"], ch[host]["host"]) 10 | hosts:set(host, ch[host]["host"]) 11 | len=1+len 12 | end 13 | 14 | 15 | -- set length of hosts 16 | hosts:set(0, len) 17 | -------------------------------------------------------------------------------- /load_conf.lua: -------------------------------------------------------------------------------- 1 | module("load_conf", package.seeall) 2 | function readAll(file) 3 | local f = io.open(file, "rb") 4 | local content = f:read("*all") 5 | f:close() 6 | return content 7 | end 8 | 9 | local c = nil 10 | 11 | function get_conf(conf) 12 | if c then return c end 13 | local cjson = require("cjson") 14 | local fc = readAll(conf) 15 | c = cjson.decode(fc) 16 | return c 17 | end 18 | -------------------------------------------------------------------------------- /router.lua: -------------------------------------------------------------------------------- 1 | function string:split(delimiter) 2 | local result = { } 3 | local from = 1 4 | local delim_from, delim_to = string.find( self, delimiter, from ) 5 | while delim_from do 6 | table.insert( result, string.sub( self, from , delim_from-1 ) ) 7 | from = delim_to + 1 8 | delim_from, delim_to = string.find( self, delimiter, from ) 9 | end 10 | table.insert( result, string.sub( self, from ) ) 11 | return result 12 | end 13 | 14 | 15 | function starts(String,Start) 16 | return string.sub(String,1,string.len(Start))==Start 17 | end 18 | 19 | 20 | function get_path() 21 | return ngx.var.request.split(ngx.var.request, " ")[2] 22 | end 23 | 24 | 25 | function select_sample(args, path) 26 | if args["test"] then 27 | return args["test"] 28 | elseif starts(path, "/result") then 29 | return path 30 | end 31 | 32 | return false 33 | end 34 | 35 | 36 | -- If the `test` query param exist then return it 37 | -- path. Otherwise return the request path 38 | function get_id() 39 | local args = ngx.req.get_uri_args() 40 | local path = get_path() 41 | local sample = select_sample(args, path) 42 | 43 | local id = nil 44 | if sample then 45 | local captures, err = ngx.re.match(sample, "[1-9]+_(?[A-Za-z])[A-Za-z]+_[1-9]", "iox") 46 | if captures["id"] then 47 | id = captures["id"] 48 | end 49 | end 50 | return id 51 | end 52 | 53 | 54 | local hosts = ngx.shared.hosts 55 | local id = get_id() 56 | 57 | if id and hosts.get(hosts, id) then 58 | local host = hosts.get(hosts, id) 59 | ngx.var.target = host 60 | else 61 | -- Random Round Robin algorithm 62 | local len = hosts.get(hosts, 0) 63 | math.randomseed(os.time()) 64 | local index = math.random(1, len) 65 | local host = hosts.get(hosts, index) 66 | ngx.var.target = host 67 | end 68 | -------------------------------------------------------------------------------- /wpt.conf: -------------------------------------------------------------------------------- 1 | lua_package_path '/var/lib/ngx_wpt/?.lua;/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua;./?.lua;/usr/local/openresty/luajit/share/luajit-2.1.0-alpha/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty/luajit/share/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/?/init.lua'; 2 | 3 | lua_shared_dict hosts 1m; 4 | 5 | init_worker_by_lua_file /var/lib/ngx_wpt/init.lua; 6 | 7 | server { 8 | listen 80; 9 | 10 | #webpagetest rewrite rules 11 | rewrite ^/about$ /about.php last; 12 | rewrite ^/traceroute$ /traceroute.php last; 13 | rewrite ^/mobile$ /mobile.php last; 14 | rewrite ^/tips$ /tips.php last; 15 | rewrite ^/pss$ /pss.php last; 16 | rewrite ^/compare$ /pss.php last; 17 | rewrite ^/blink$ /blink.php last; 18 | 19 | #result paths 20 | rewrite ^/result/([a-zA-Z0-9_]+)$ /result/$1/ permanent; 21 | rewrite ^/result/([a-zA-Z0-9_]+)/$ /results.php?test=$1 last; 22 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/waterfall$ /result/$1/$2/details/ permanent; 23 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/waterfall/$ /result/$1/$2/details/ permanent; 24 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/details$ /details.php?test=$1&run=$2 last; 25 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/details/$ /details.php?test=$1&run=$2 last; 26 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/waterfall/cached$ /result/$1/$2/details/cached/ permanent; 27 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/waterfall/cached/$ /result/$1/$2/details/cached/ permanent; 28 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/details/cached$ /details.php?test=$1&run=$2&cached=1 last; 29 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/details/cached/$ /details.php?test=$1&run=$2&cached=1 last; 30 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization$ /result/$1/$2/performance_optimization/ permanent; 31 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization/$ /result/$1/$2/performance_optimization/ permanent; 32 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/performance_optimization$ /performance_optimization.php?test=$1&run=$2 last; 33 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/performance_optimization/$ /performance_optimization.php?test=$1&run=$2 last; 34 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization/cached$ /result/$1/$2/performance_optimization/cached/ permanent; 35 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization/cached/$ /result/$1/$2/performance_optimization/cached/ permanent; 36 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/performance_optimization/cached$ /performance_optimization.php?test=$1&run=$2&cached=1 last; 37 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/performance_optimization/cached/$ /performance_optimization.php?test=$1&run=$2&cached=1 last; 38 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/screen_shot$ /screen_shot.php?test=$1&run=$2 last; 39 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/screen_shot/$ /screen_shot.php?test=$1&run=$2 last; 40 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/screen_shot/cached$ /screen_shot.php?test=$1&run=$2&cached=1 last; 41 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/screen_shot/cached/$ /screen_shot.php?test=$1&run=$2&cached=1 last; 42 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/breakdown$ /breakdown.php?test=$1&run=$2 last; 43 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/breakdown/$ /breakdown.php?test=$1&run=$2 last; 44 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/breakdown/cached$ /breakdown.php?test=$1&run=$2&cached=1 last; 45 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/breakdown/cached/$ /breakdown.php?test=$1&run=$2&cached=1 last; 46 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/domains$ /domains.php?test=$1&run=$2 last; 47 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/domains/$ /domains.php?test=$1&run=$2 last; 48 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/domains/cached$ /domains.php?test=$1&run=$2&cached=1 last; 49 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/domains/cached/$ /domains.php?test=$1&run=$2&cached=1 last; 50 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization_report$ /optimization_report.php?test=$1&run=$2 last; 51 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization_report/$ /optimization_report.php?test=$1&run=$2 last; 52 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization_report/cached$ /optimization_report.php?test=$1&run=$2&cached=1 last; 53 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/optimization_report/cached/$ /optimization_report.php?test=$1&run=$2&cached=1 last; 54 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/pagespeed$ /pagespeed.php?test=$1&run=$2 last; 55 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/pagespeed/$ /pagespeed.php?test=$1&run=$2 last; 56 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/pagespeed/cached$ /pagespeed.php?test=$1&run=$2&cached=1 last; 57 | rewrite ^/result/([a-zA-Z0-9_]+)/([a-zA-Z0-9]+)/pagespeed/cached/$ /pagespeed.php?test=$1&run=$2&cached=1 last; 58 | rewrite ^/testlog/([0-9]+)$ /testlog/$1/ permanent; 59 | rewrite ^/testlog/([0-9]+)/$ /testlog.php?days=$1 last; 60 | rewrite ^/xmlResult/([a-zA-Z0-9_]+)/$ /xmlResult.php?test=$1 last; 61 | rewrite ^/testlog.csv /testlog.php?f=csv last; 62 | rewrite ^/waterfall.png /waterfall.php last; 63 | 64 | #old direct path to images 65 | rewrite ^/results/([a-zA-Z0-9])([a-zA-Z0-9]+)/([a-zA-Z0-9_]+).png$ /results/old/_$1/$1$2/$3.png last; 66 | rewrite ^/results/([a-zA-Z0-9])([a-zA-Z0-9]+)/([a-zA-Z0-9_]+).jpg$ /results/old/_$1/$1$2/$3.jpg last; 67 | rewrite ^/results/old/_([a-zA-Z0-9])/([a-zA-Z0-9]+)/([a-zA-Z0-9_]+).png$ /results/old/$2/$3.png last; 68 | 69 | #csv combined results 70 | rewrite ^/result/([a-zA-Z0-9_]+)/.*page_data.csv$ /csv.php?test=$1 last; 71 | rewrite ^/result/([a-zA-Z0-9_]+)/.*requests.csv$ /csv.php?test=$1&requests=1 last; 72 | 73 | #thumbnails 74 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_screen_thumb.jpg$ /thumbnail.php?test=$1&run=$2&file=$2_screen.jpg last; 75 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_Cached_screen_thumb.jpg$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_screen.jpg last; 76 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_waterfall_thumb.png$ /thumbnail.php?test=$1&run=$2&file=$2_waterfall.png last; 77 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_Cached_waterfall_thumb.png$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_waterfall.png last; 78 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_optimization_thumb.png$ /thumbnail.php?test=$1&run=$2&file=$2_optimization.png last; 79 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_Cached_optimization_thumb.png$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_optimization.png last; 80 | 81 | #old direct thumbnail paths 82 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_screen_thumb.jpg$ /thumbnail.php?test=$1&run=$2&file=$2_screen.jpg last; 83 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_screen_thumb.jpg$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_screen.jpg last; 84 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_waterfall_thumb.png$ /thumbnail.php?test=$1&run=$2&file=$2_waterfall.png last; 85 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_waterfall_thumb.png$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_waterfall.png last; 86 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_optimization_thumb.png$ /thumbnail.php?test=$1&run=$2&file=$2_optimization.png last; 87 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_optimization_thumb.png$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_optimization.png last; 88 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_waterfall_thumb.gif$ /thumbnail.php?test=$1&run=$2&file=$2_waterfall.gif last; 89 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_waterfall_thumb.gif$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_waterfall.gif last; 90 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_optimization_thumb.gif$ /thumbnail.php?test=$1&run=$2&file=$2_optimization.gif last; 91 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_optimization_thumb.gif$ /thumbnail.php?test=$1&run=$2&cached=1&file=$2_Cached_optimization.gif last; 92 | 93 | # waterfalls 94 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_waterfall.png$ /waterfall.php?test=$1&run=$2 last; 95 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_waterfall.png$ /waterfall.php?test=$1&run=$2&cached=1 last; 96 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_waterfall.gif$ /waterfall.php?test=$1&run=$2 last; 97 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_waterfall.gif$ /waterfall.php?test=$1&run=$2&cached=1 last; 98 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([0-9]+)_waterfall.png$ /waterfall.php?test=$1$2$3_$4&run=$5 last; 99 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)_waterfall.png$ /waterfall.php?test=$1$2$3_$4_$5&run=$6 last; 100 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([0-9]+)_Cached_waterfall.png$ /waterfall.php?test=$1$2$3_$4&run=$5&cached=1 last; 101 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)_Cached_waterfall.png$ /waterfall.php?test=$1$2$3_$4_$5&run=$6&cached=1 last; 102 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([0-9]+)_connection.png$ /waterfall.php?test=$1$2$3_$4&run=$5&type=connection last; 103 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)_connection.png$ /waterfall.php?test=$1$2$3_$4_$5&run=$6&type=connection last; 104 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([0-9]+)_Cached_connection.png$ /waterfall.php?test=$1$2$3_$4&run=$5&cached=1&type=connection last; 105 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)_Cached_connection.png$ /waterfall.php?test=$1$2$3_$4_$5&run=$6&cached=1&type=connection last; 106 | 107 | # optimization checklists 108 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_optimization.png$ /optimizationChecklist.php?test=$1&run=$2 last; 109 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_optimization.png$ /optimizationChecklist.php?test=$1&run=$2&cached=1 last; 110 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_optimization.gif$ /optimizationChecklist.php?test=$1&run=$2 last; 111 | rewrite ^/results/old/([a-zA-Z0-9_]+)/([0-9]+)_Cached_optimization.gif$ /optimizationChecklist.php?test=$1&run=$2&cached=1 last; 112 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([0-9]+)_optimization.png$ /optimizationChecklist.php?test=$1$2$3_$4&run=$5 last; 113 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)_optimization.png$ /optimizationChecklist.php?test=$1$2$3_$4_$5&run=$6 last; 114 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([0-9]+)_Cached_optimization.png$ /optimizationChecklist.php?test=$1$2$3_$4&run=$5&cached=1 last; 115 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)_Cached_optimization.png$ /optimizationChecklist.php?test=$1$2$3_$4_$5&run=$6&cached=1 last; 116 | 117 | #location cookie dropping 118 | rewrite ^/loc/([a-zA-Z0-9_]+)$ /util/setloc.php?location=$1 last; 119 | rewrite ^/loc/([a-zA-Z0-9_]+)$/ /util/setloc.php?location=$1 last; 120 | 121 | #gzip compressed text result files 122 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+).(txt|csv)$ /gettext.php?test=$1$2$3_$4&file=$5.$6 last; 123 | rewrite ^/results/([0-9][0-9])/([0-9][0-9])/([0-9][0-9])/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+).(txt|csv)$ /gettext.php?test=$1$2$3_$4_$5&file=$6.$7 last; 124 | 125 | #tcpdump capture files 126 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+).cap$ /getgzip.php?test=$1&file=$2.cap last; 127 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_Cached.cap$ /getgzip.php?test=$1&file=$2_Cached.cap last; 128 | 129 | #page speed 130 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_pagespeed.txt$ /getgzip.php?test=$1&file=$2_pagespeed.txt last; 131 | rewrite ^/result/([a-zA-Z0-9_]+)/([0-9]+)_Cached_pagespeed.txt$ /getgzip.php?test=$1&file=$2_Cached_pagespeed.txt last; 132 | 133 | #embeddable video widget 134 | rewrite ^/video/embed/([a-zA-Z0-9_]+)$ /video/view.php?embed=1&id=$1 last; 135 | 136 | #widgets 137 | rewrite ^/widgets/pagespeed/tree$ /widgets/pagespeed/tree.php last; 138 | 139 | #old pages that were eliminated in the UI rewrite 140 | rewrite ^/test$ / permanent; 141 | 142 | # software update checks (to allow for rate limiting agents that go out of control) 143 | rewrite ^/installers/software.dat$ /check_installer.php?installer=software.dat last; 144 | rewrite ^/installers/browsers/([-_a-zA-Z0-9]+\.dat)$ /check_installer.php?installer=browsers%2F$1 last; 145 | location / { 146 | default_type text/plain; 147 | set $target ''; 148 | access_by_lua_file /var/lib/ngx_wpt/router.lua; 149 | proxy_pass http://$target; 150 | } 151 | } 152 | --------------------------------------------------------------------------------