local socks5 = require 'socks5' local ngx = require 'ngx' local onion2web = {} local hidden_base = "(" .. string.rep("%w", 16) .. ")" local hidden_onion = hidden_base .. '%.onion' local show_confirmation_form = function() local host = ngx.req.get_headers()['Host'] local onion = host:match(hidden_base) .. '.onion' if ngx.req.get_method() == 'POST' and ngx.var.uri:match('^/confirm') then ngx.header['Set-Cookie'] = 'onion2web_confirmed=true;' return ngx.redirect("/") end ngx.say(([[
]]):format(host, onion, onion))
end
onion2web.handle_onion2web = function(onion_replacement,
torhost, torport, confirmation)
if not torhost then
torhost = '127.0.0.1'
end
if not torport then
torport = 9050
end
if confirmation == nil then
confirmation = true
end
local repl = hidden_base .. onion_replacement
local host = ngx.req.get_headers()['Host']
if not host:match('^' .. repl .. '$') and
not host:match('%.' .. repl .. '$') then
ngx.say('Bad domain: ' .. host)
return
end
local cookies = ngx.req.get_headers()['Cookie']
if confirmation and
(not cookies or
not cookies:match('onion2web_confirmed=true')) then
show_confirmation_form()
return
end
local change_only_html = true
socks5.handle_request(torhost, torport,
function(clheader)
return clheader
:gsub("HTTP/1.1(%c+)", "HTTP/1.0%1")
:gsub(repl, "%1.onion")
:gsub("Connection: keep%-alive", "Connection: close")
:gsub("Accept%-Encoding: [%w%p ]+%c+", "")
end,
function(soheader)
return soheader
:gsub(hidden_onion, "%1" .. onion_replacement)
end,
change_only_html
)
end
return onion2web