gluon-status-page: when visiting via a next-node address, redirect to a unique address
A downside of this behaviour is that the page does not work for IPv4-only clients, as the redirect will always point at an IPv6 address. Still, it seems like a good idea to enforce the redirect even from the IPv4 next-node address, as switching nodes while being connected to the status page would lead to unexpected behaviour.
This commit is contained in:
parent
fdf823a3a2
commit
27f7ce444f
@ -1,6 +1,5 @@
|
||||
<%-
|
||||
local fs = require 'nixio.fs'
|
||||
local json = require 'jsonc'
|
||||
local ubus = require 'ubus'
|
||||
local util = require 'gluon.util'
|
||||
|
||||
@ -44,8 +43,6 @@
|
||||
|
||||
local interfaces = get_interfaces()
|
||||
|
||||
local nodeinfo = json.parse(util.exec('exec gluon-neighbour-info -d ::1 -p 1001 -t 1 -c 1 -r nodeinfo'))
|
||||
|
||||
local function sorted(t)
|
||||
t = {unpack(t)}
|
||||
table.sort(t)
|
||||
|
@ -1,3 +1,87 @@
|
||||
local json = require 'jsonc'
|
||||
local site = require 'gluon.site'
|
||||
local util = require 'gluon.util'
|
||||
|
||||
local function parse_ip(addr)
|
||||
if not addr then return end
|
||||
|
||||
local ip4 = {addr:match('(%d+)%.(%d+)%.(%d+)%.(%d+)')}
|
||||
if ip4[1] then
|
||||
local ret = {}
|
||||
|
||||
for i, part in ipairs(ip4) do
|
||||
ret[i] = tonumber(part)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
if not addr:match('^[:%x]+$') then
|
||||
return
|
||||
end
|
||||
|
||||
if addr:sub(0, 2) == '::' then
|
||||
addr = '0' .. addr
|
||||
end
|
||||
if addr:sub(-2) == '::' then
|
||||
addr = addr .. '0'
|
||||
end
|
||||
|
||||
addr = addr .. ':'
|
||||
|
||||
local groups, groups1 = {}, {}
|
||||
for part in addr:gmatch('([^:]*):') do
|
||||
if part == '' then
|
||||
groups1 = groups
|
||||
groups = {}
|
||||
else
|
||||
groups[#groups+1] = tonumber(part, 16)
|
||||
end
|
||||
end
|
||||
|
||||
while #groups + #groups1 < 8 do
|
||||
groups1[#groups1+1] = 0
|
||||
end
|
||||
for _, group in ipairs(groups) do
|
||||
groups1[#groups1+1] = group
|
||||
end
|
||||
|
||||
return groups1
|
||||
end
|
||||
|
||||
local function match(a, b, n)
|
||||
if not a or not b then return false end
|
||||
|
||||
for i = 1, n do
|
||||
if a[i] ~= b[i] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
entry({}, call(function(http, renderer)
|
||||
renderer.render('status-page', nil, 'gluon-status-page')
|
||||
local nodeinfo = json.parse(util.exec('exec gluon-neighbour-info -d ::1 -p 1001 -t 1 -c 1 -r nodeinfo'))
|
||||
|
||||
local node_ip = parse_ip(http:getenv('SERVER_ADDR'))
|
||||
if node_ip and (
|
||||
match(node_ip, parse_ip(site.next_node.ip4()), 8) or
|
||||
match(node_ip, parse_ip(site.next_node.ip6()), 8)
|
||||
) then
|
||||
-- The user has visited the status page via a next-node address
|
||||
-- Redirect the user the a unique address to avoid switching
|
||||
-- nodes
|
||||
local prefix = parse_ip(site.prefix6():match('^[^/]+'))
|
||||
for _, addr in ipairs(nodeinfo.network.addresses) do
|
||||
if match(prefix, parse_ip(addr), 4) then
|
||||
http:header('Cache-Control', 'no-cache, no-store, must-revalidate')
|
||||
http:redirect('http://[' .. addr .. ']' .. http:getenv('REQUEST_URI'))
|
||||
http:close()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
renderer.render('status-page', { nodeinfo = nodeinfo }, 'gluon-status-page')
|
||||
end))
|
||||
|
Loading…
Reference in New Issue
Block a user