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 fs = require 'nixio.fs' | ||||||
| 	local json = require 'jsonc' |  | ||||||
| 	local ubus = require 'ubus' | 	local ubus = require 'ubus' | ||||||
| 	local util = require 'gluon.util' | 	local util = require 'gluon.util' | ||||||
| 
 | 
 | ||||||
| @ -44,8 +43,6 @@ | |||||||
| 
 | 
 | ||||||
| 	local interfaces = get_interfaces() | 	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) | 	local function sorted(t) | ||||||
| 		t = {unpack(t)} | 		t = {unpack(t)} | ||||||
| 		table.sort(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) | 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)) | end)) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user