aboutsummaryrefslogtreecommitdiff
path: root/bulkredirect.lua
diff options
context:
space:
mode:
Diffstat (limited to 'bulkredirect.lua')
-rw-r--r--bulkredirect.lua87
1 files changed, 81 insertions, 6 deletions
diff --git a/bulkredirect.lua b/bulkredirect.lua
index 211d335..514a63b 100644
--- a/bulkredirect.lua
+++ b/bulkredirect.lua
@@ -35,6 +35,56 @@ local function prevsegm (t)
end
end
+-- Translation table for percent encoding.
+local urltrans = {
+ '%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08',
+ '%09', '%0A', '%0B', '%0C', '%0D', '%0E', '%0F', '%10',
+ '%11', '%12', '%13', '%14', '%15', '%16', '%17', '%18',
+ '%19', '%1A', '%1B', '%1C', '%1D', '%1E', '%1F', '%20',
+ '%21', '%22', '%23', '%24', '%25', '%26', '%27', '%28',
+ '%29', '%2A', '%2B', '%2C', '-', '.', '/', '0',
+ '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', '%3A', '%3B', '%3C', '%3D', '%3E', '%3F', '%40',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', '%5B', '%5C', '%5D', '%5E', '_', '%60',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '%7B', '%7C', '%7D', '~', '%7F', '%80',
+ '%81', '%82', '%83', '%84', '%85', '%86', '%87', '%88',
+ '%89', '%8A', '%8B', '%8C', '%8D', '%8E', '%8F', '%90',
+ '%91', '%92', '%93', '%94', '%95', '%96', '%97', '%98',
+ '%99', '%9A', '%9B', '%9C', '%9D', '%9E', '%9F', '%A0',
+ '%A1', '%A2', '%A3', '%A4', '%A5', '%A6', '%A7', '%A8',
+ '%A9', '%AA', '%AB', '%AC', '%AD', '%AE', '%AF', '%B0',
+ '%B1', '%B2', '%B3', '%B4', '%B5', '%B6', '%B7', '%B8',
+ '%B9', '%BA', '%BB', '%BC', '%BD', '%BE', '%BF', '%C0',
+ '%C1', '%C2', '%C3', '%C4', '%C5', '%C6', '%C7', '%C8',
+ '%C9', '%CA', '%CB', '%CC', '%CD', '%CE', '%CF', '%D0',
+ '%D1', '%D2', '%D3', '%D4', '%D5', '%D6', '%D7', '%D8',
+ '%D9', '%DA', '%DB', '%DC', '%DD', '%DE', '%DF', '%E0',
+ '%E1', '%E2', '%E3', '%E4', '%E5', '%E6', '%E7', '%E8',
+ '%E9', '%EA', '%EB', '%EC', '%ED', '%EE', '%EF', '%F0',
+ '%F1', '%F2', '%F3', '%F4', '%F5', '%F6', '%F7', '%F8',
+ '%F9', '%FA', '%FB', '%FC', '%FD', '%FE', '%FF',
+}
+
+-- Apply percent encoding to the path part of S.
+local function url_path_encode (s)
+ local t = {}
+ local p, q = s:match('^(.+)(?.+)')
+ if p then
+ t[#p+1] = q
+ s = p
+ end
+ for i = 1, #s do
+ t[i] = urltrans[s:byte(i)]
+ end
+ return table.concat(t)
+end
+
--
-- Module global variables:
--
@@ -110,13 +160,19 @@ stripquery = false
temporary = false
-- Whether to return temporary (302) or permanent (301) reply.
+urlencode = true
+--[[ Encode special characters in path parts of both source and destination
+ URLs as specified in RFC 3986 ("percent encoding"). By default,
+ bulkencode assumes all URLs are already properly encoded.
+]]
+
--
-- Redirect the request if it matches one of the entries in the RT table.
--
function bulkredirect.request (txn)
local headers = txn.http:req_get_headers()
local reply = txn:reply()
- local path = txn.f:path():sub(2)
+ local path = txn.f:path():sub(2):gsub('%%%x%x', string.upper)
local host = headers["host"][0]
-- Get the per-host redirection table
@@ -157,6 +213,10 @@ function bulkredirect.request (txn)
dt = dt[1]
end
+ if type(dt) == 'string' then
+ dt = { dt }
+ end
+
location = dt[1]
if dt[2] ~= nil then
exact = dt[2]
@@ -174,13 +234,13 @@ function bulkredirect.request (txn)
location = rthost[i]
end
end
-
+
if location then
if not (location:match('^http://') or location:match('^https://')
or location:match('^/')) then
location = '/'..location
end
-
+
if not exact or i == path or i..'/' == path then
if not strippath then
location = location .. path:sub(i:len() + 1)
@@ -225,7 +285,8 @@ local function parseopt (s, t, loc)
['exact'] = true,
['strippath'] = true,
['stripquery'] = true,
- ['temporary'] = true
+ ['temporary'] = true,
+ ['urlencode'] = true
}
function options (str, loc)
@@ -276,6 +337,7 @@ local function set_dst (dt, src, dst)
elseif type(dt[path]) == 'string' then
dt[path] = { { dt[path] }, {} }
end
+-- core.Info(require('inspect')(dt[path]))
dt[path][2][query] = dst
elseif type(dt[src]) == 'table' then
dt[src][1] = dst
@@ -333,7 +395,7 @@ local function load_redirect_file (f, filename)
local ln = 1
local rt = {}
- local domopt = {}
+ local domopt
local parsetab = {
{ '^#', function () end },
@@ -353,6 +415,12 @@ local function load_redirect_file (f, filename)
function (s)
domain = s
if not rt[domain] then rt[domain] = {} end
+ domopt = {
+ exact = exact,
+ strippath = strippath,
+ stripquery = stripquery,
+ temporary = temporary
+ }
end
},
{ '^%s*([^%s]+)%s+([^%s]+)%s*(.*)$',
@@ -369,12 +437,19 @@ local function load_redirect_file (f, filename)
dst = dst:sub(2)
end
- local optab = domopt
+ local optab = domopt
if optlist ~= '' then
optab = clone(domopt)
parseopt(optlist, optab, filename .. ':' .. ln)
end
+ if optab['urlencode'] then
+ src = url_path_encode(src)
+ dst = url_path_encode(dst)
+ else
+ src = src:gsub('%%%x%x', string.upper)
+ end
+
local dpath, dquery = dst:match('^(.+)?(.*)')
if dpath then
if optab['strippath'] == false and optab['strippath'] ~= domopt['strippath'] then

Return to:

Send suggestions and report system problems to the System administrator.