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:
@@ -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 '
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user