-
-
Save kotopes/4679855 to your computer and use it in GitHub Desktop.
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
# based on http://uberblo.gs/2011/06/high-performance-url-shortening-with-redis-backed-nginx | |
# using code from http://stackoverflow.com/questions/3554315/lua-base-converter | |
# fixes: use adresses with args, and adresses to way out site. example: /shorten/www.bn.ru/?test=shorten | |
# "database scheme" | |
# database 5: id ~> url (use 0 is not good idea) | |
# database 1: id ~> hits | |
# database 2: id ~> [{referer|user_agent}] | |
# database 3: id ~> hits (when id is not found) | |
# database 4: id ~> [{referer|user_agent}] (when id is not found) | |
# database 5: key "count" storing the number of shortened urls; the id is generated by (this number + 1) converted to base 62 | |
server { | |
location ~ ^/retrieve$ { | |
internal; | |
redis2_query select 5; | |
redis2_query get "ngx:shrt:$request_uri"; | |
redis2_pass 127.0.0.1:6379; | |
} | |
location ~ ^/count$ { | |
internal; | |
redis2_query select 5; | |
redis2_query get "ngx:shrtcount"; | |
redis2_pass 127.0.0.1:6379; | |
} | |
location ~ ^/history$ { | |
internal; | |
redis2_query select 1; | |
redis2_query incr "ngx:shrt:$request_uri"; | |
redis2_query select 2; | |
redis2_query rpush "ngx:shrt:$request_uri" "$http_referer|$http_user_agent"; | |
redis2_pass 127.0.0.1:6379; | |
} | |
location ~ ^/notfound$ { | |
internal; | |
redis2_query select 3; | |
redis2_query incr "ngx:shrt:$request_uri"; | |
redis2_query select 4; | |
redis2_query rpush "ngx:shrt:$request_uri" "$http_referer|$http_user_agent"; | |
redis2_pass 127.0.0.1:6379; | |
} | |
location ~ ^/store$ { | |
internal; | |
redis2_query select 5; | |
set_unescape_uri $id $arg_id; | |
set_unescape_uri $url $arg_url; | |
redis2_query set "ngx:shrt:$id" $url; | |
redis2_query select 5; | |
redis2_query incr "ngx:shrtcount"; | |
redis2_pass 127.0.0.1:6379; | |
} | |
location ~ ^/shorten/(?<gurl>.*)$ { | |
auth_basic "Restricted"; | |
auth_basic_user_file /etc/nginx/.htpasswd; | |
add_header Content-Type text/plain; | |
content_by_lua ' | |
local parser = require "redis.parser"; | |
local res = ngx.location.capture("/count"); | |
local results, type = parser.parse_replies(res.body, 2); | |
basen = function(n, b) | |
n = math.floor(n); | |
if not b or b == 10 then return tostring(n) end | |
local digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
local t = {}; | |
local sign = ""; | |
if n < 0 then | |
sign = "-"; | |
n = -n; | |
end | |
repeat | |
local d = (n % b) + 1; | |
n = math.floor(n / b); | |
table.insert(t, 1, digits:sub(d, d)); | |
until n == 0 | |
return sign .. table.concat(t, ""); | |
end | |
if (results[2][1]) then | |
local id = basen(results[2][1] + 1, 62); | |
else | |
local id = basen(0, 62); | |
end | |
local in_args = ngx.req.get_uri_args(); | |
local keys = {}; | |
for key, val in pairs(in_args) do | |
table.insert(keys, key .. "=" .. val); | |
end | |
table.insert(keys, "from=" .. ngx.var.host); | |
local st_args = table.concat(keys, "&"); | |
ngx.location.capture("/store", | |
{ args = { id = "/" .. tostring(id), url = ngx.encode_base64("http://" .. ngx.var.gurl .. "?" .. st_args) } } | |
); | |
ngx.say("original url: http://" .. ngx.var.gurl .. "?" .. st_args); | |
ngx.say(" shorted url: http://" .. ngx.var.host .. "/" .. id); | |
'; | |
} | |
location / { | |
content_by_lua ' | |
local parser = require "redis.parser"; | |
local res = ngx.location.capture("/retrieve"); | |
local href, type = parser.parse_reply(res.body); | |
if type == parser.ERROR_REPLY or href == nil then | |
ngx.location.capture("/notfound"); | |
-- ngx.say("Not found"); | |
ngx.exit(ngx.HTTP_NOT_FOUND); | |
else | |
ngx.location.capture("/history"); | |
ngx.redirect(ngx.decode_base64(href)); | |
end | |
'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment