Instantly share code, notes, and snippets.

Embed
What would you like to do?
using nginx + lua + redis for redirects and rewrites
# using such a setup requires `apt-get install lua-nginx-redis` under Ubuntu Trusty
# more info @ http://wiki.nginx.org/HttpLuaModule#access_by_lua
http {
lua_package_path "/etc/nginx/include.d/?.lua;;";
lua_socket_pool_size 100;
lua_socket_connect_timeout 10ms;
lua_socket_read_timeout 10ms;
server {
listen 80;
server_name www.stylight.com;
location / {
include /etc/nginx/include.d/en_US/rewrites/122_lua_st_redis_rewrites.lua;
}
}
}
access_by_lua '
local redis = require "redis"
local red = redis:new()
-- see all available redis: methods @ https://github.com/openresty/lua-resty-redis#methods
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
return ngx.exit(500)
end
red:select(1)
local redirect_candidate = ngx.var.uri
local args_remainder = ngx.null
local args = ngx.var.args
-- we store internal application rewrites as hash values in Redis for their corresponding pretty URL keys
-- if a bot crawls through asking for /search.action?brand=3210
local hash_rewrite, error = red:hgetall(ngx.var.uri)
-- 127.0.0.1:6379[1]> hgetall /search.action?brand=3210
-- (error) WRONGTYPE Operation against a key holding the wrong kind of value
-- let's find the appropriate redirect URL:
if error then
if args then
local m = ngx.re.match(args, [[^(gclid=.*)?(?<start>.*(shop|brand|tag)=[0-9]+)+&?(.*(shop|sale|searchstring|gender)=.*?&?)*(|&(?<remainder>.*))$]])
if m then
if m["start"] then
redirect_candidate = redirect_candidate .. "?" .. m["start"]
end
if m["remainder"] then
args_remainder = m["remainder"]
end
end
end
-- and ask Redis for the 301 redirect URL
local rewrite_value, err = red:get(redirect_candidate)
-- 127.0.0.1:6379[1]> get "/search.action?brand=3210"
-- "/Mexx/"
-- create/use a connection pool of size 100 with 0 idle timeout
red:set_keepalive(0, 100)
if rewrite_value ~= ngx.null then
if args_remainder ~= ngx.null then
rewrite_value = rewrite_value .. "?" .. args_remainder
end
-- and kindly ask the bot to visit /Mexx/ instead
ngx.redirect(rewrite_value, 301);
end
else
-- a request for /Sandals/Women/ however
if table.getn(hash_rewrite) > 0 then
red:set_keepalive(0, 100)
-- gives us the following hash from Redis:
-- 127.0.0.1:6379[3]> hgetall /Sandals/Women/
-- 1) "action"
-- 2) "search.action"
-- 3) "params"
-- 4) "gender=women&tag=10580&tag=10630"
-- lets transform to an internal rewrite
arr_rewrite = red:array_to_hash(hash_rewrite)
params = nil
if arr_rewrite["params"] then
params = arr_rewrite["params"]
end
if args then
if params~=nil then
params = params .. "&" .. args
else
params = args
end
end
if params~=nil then
ngx.req.set_uri_args(params)
end
-- and send off to our app server for processing
ngx.req.set_uri("/" .. arr_rewrite["action"])
end
end
';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment