aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/scadere/listen.py24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/scadere/listen.py b/src/scadere/listen.py
index aa80c32..0777f4a 100644
--- a/src/scadere/listen.py
+++ b/src/scadere/listen.py
@@ -21,7 +21,7 @@ from functools import partial
from urllib.parse import parse_qs, urljoin, urlsplit
from xml.etree.ElementTree import (Element as xml_element,
SubElement as xml_subelement,
- indent, tostring as xml_to_string)
+ indent, tostring as str_from_xml)
from . import __version__
@@ -84,13 +84,14 @@ async def handle(certs, base_url, reader, writer):
"""Handle HTTP request."""
summaries = tuple(cert.rstrip().split(maxsplit=5)
for cert in certs.read_text().splitlines())
- lookup = {f'/{path(hostname, port, issuer, serial)}':
+ lookup = {urlsplit(urljoin(base_url,
+ path(hostname, port, issuer, serial))).path:
(not_before, not_after, hostname, port, serial, issuer)
for not_before, not_after, hostname, port, serial, issuer
in summaries}
request = await reader.readuntil(b'\r\n')
url = request.removeprefix(b'GET ').rsplit(b' HTTP/', 1)[0]
- url_parts = urlsplit(url.decode())
+ url_parts = urlsplit(urljoin(base_url, url.decode()))
domains = tuple(parse_qs(url_parts.query).get('domain', ['']))
if not request.startswith(b'GET '):
@@ -99,7 +100,9 @@ async def handle(certs, base_url, reader, writer):
writer.close()
await writer.wait_closed()
return
- elif url_parts.path == '/': # Atom feed
+ elif url.startswith(b'//'): # urljoin goes haywire
+ writer.write(b'HTTP/1.1 404 Not Found\r\n')
+ elif url_parts.path == urlsplit(base_url).path: # Atom feed
writer.write(b'HTTP/1.1 200 OK\r\n')
writer.write(b'Content-Type: application/atom+xml\r\n')
feed = xml(('feed', {'xmlns': 'http://www.w3.org/2005/Atom'},
@@ -112,9 +115,10 @@ async def handle(certs, base_url, reader, writer):
'version': __version__},
'Scadere'),
*(entry(base_url, cert)
- for cert in summaries if cert[2].endswith(domains))))
- content = xml_to_string(feed, 'unicode', xml_declaration=True,
- default_namespace=None).encode()
+ for cert in lookup.values()
+ if cert[2].endswith(domains))))
+ content = str_from_xml(feed, 'unicode', xml_declaration=True,
+ default_namespace=None).encode()
writer.write(f'Content-Length: {len(content)}\r\n\r\n'.encode())
writer.write(content)
elif url_parts.path in lookup: # accessible Atom entry's link/ID
@@ -134,8 +138,8 @@ async def handle(certs, base_url, reader, writer):
('title', f'TLS certificate - {hostname}:{port}')),
('body', *body(not_before, not_after,
hostname, port, serial, issuer))))
- content = xml_to_string(page, 'unicode', xml_declaration=True,
- default_namespace=None).encode()
+ content = str_from_xml(page, 'unicode', xml_declaration=True,
+ default_namespace=None).encode()
writer.write(f'Content-Length: {len(content)}\r\n\r\n'.encode())
writer.write(content)
else:
@@ -145,7 +149,7 @@ async def handle(certs, base_url, reader, writer):
await writer.wait_closed()
-async def listen(certs, base_url, host, port):
+async def listen(certs, base_url, host, port): # pragma: no cover
"""Serve HTTP server for TLS certificate expirations' Atom feed."""
server = await start_server(partial(handle, certs, base_url), host, port)
async with server: