2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-02-26 10:19:18 +00:00

Amend URL shortening

302 works for iPXE, but not for more limited UEFI
http client.

If we are dealing with UefiHttpBoot, check for a header
from nginx config and use X-Accel-Redirect to induce proxy side
redirect transparent to client.

Otherwise, give an error indicating the issue with the profile
name length and incompatibility with Apache capabilities.
This commit is contained in:
Jarrod Johnson
2025-05-13 11:41:11 -04:00
parent a7c338786e
commit fca0119331
2 changed files with 27 additions and 7 deletions

View File

@@ -169,14 +169,18 @@ pxearchs = {
shorturls = {}
def register_shorturl(url):
urlidbyurl = {}
def register_shorturl(url, can302=True, relurl=None, filename=None):
if url in urlidbyurl:
return urlidbyurl[url]
urlid = base64.urlsafe_b64encode(os.urandom(3))
while urlid in shorturls:
urlid = base64.urlsafe_b64encode(os.urandom(3))
urlid = urlid.decode()
shorturls[urlid] = url
shorturls[urlid] = (url, can302, relurl, filename)
returl = '/'.join(url.split('/')[:3])
returl += '/confluent-api/boot/su/' + urlid + '/' + os.path.basename(url)
urlidbyurl[url] = returl
return returl
@@ -830,16 +834,20 @@ def reply_dhcp4(node, info, packet, cfg, reqview, httpboot, cfd, profile, sock=N
if niccfg['ipv4_address'] == myipn:
log.log({'error': 'Unable to serve {0} due to duplicated address between node and interface index "{}"'.format(node, info['netinfo']['ifidx'])})
return
can302 = True
if httpboot:
proto = 'https' if insecuremode == 'never' else 'http'
bootfile = '{0}://{1}/confluent-public/os/{2}/boot.img'.format(
proto, myipn, profile
)
bootshorturl = '/confluent-public/os/{0}/boot.img'.format(profile)
bootfilename = '/var/lib/confluent/public/os/{0}/boot.img'.format(profile)
can302 = False
if not isinstance(bootfile, bytes):
bootfile = bootfile.encode('utf8')
if len(bootfile) > 127:
if bootfile.startswith(b'http'):
bootfile = register_shorturl(bootfile.decode('utf8')).encode('utf8')
bootfile = register_shorturl(bootfile.decode('utf8'), can302, bootshorturl, bootfilename).encode('utf8')
else:
log.log(
{'info': 'Boot offer cannot be made to {0} as the '

View File

@@ -684,14 +684,26 @@ def resourcehandler_backend(env, start_response):
if not request[0]:
request = request[1:]
if request[1] == 'su': # shorturl
targurl = pxe.shorturls.get(request[2], None)
targurl, can302, relurl, bootfilename = pxe.shorturls.get(request[2], (None, None, None, None))
if not targurl:
start_response('404 Not Found', headers)
yield ''
return
headers.append(('Location', targurl))
start_response('302 Found', headers)
yield ''
if can302: # Maximum transparency helps iPXE and whatever else know the most
headers.append(('Location', targurl))
start_response('302 Found', headers)
yield ''
else: # The user agent is too dumb, check headers for server side redirects
delegatemethod = env.get('HTTP_X_DELEGATE_METHOD', None)
if delegatemethod == 'accel':
headers = [('Content-Type', 'application/octet-stream')]
headers.append(('X-Accel-Redirect', relurl))
start_response('200 OK', headers)
yield ''
else:
start_response('502 Bad Gateway', headers)
yield 'URL shortening for a limited client without proxy advertised accel support'
log.log({'error': f'Profile name exceeded DHCP limits, and reverse proxy capabilities not detected, switch to the nginx configuration or shorten the profile name: {relurl}'})
return
if len(request) != 4:
start_response('400 Bad Request', headers)