-
-
Save 0x00dec0de/ce295c0b331bcbb98ec6ed45670d756a to your computer and use it in GitHub Desktop.
using nginx + lua + redis for redirects and rewrites
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
# 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; | |
} | |
} | |
} |
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
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