Author SHA1 Message Date
klemek 46a23d2ed0 chore: release 1.1.0
Docker CI / build (push) Failing after 3m6s
Python CI / ruff-format-check (push) Successful in 1m29s
Python CI / ruff (push) Successful in 2m10s
Python CI / ty (push) Failing after 22s
Python CI / coverage (push) Failing after 24s
2026-04-21 23:03:51 +02:00
klemek 7c824ff1c0 fix(handlers): handle http certbot request 2026-04-21 23:02:16 +02:00
5 changed files with 46 additions and 13 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "stapler" name = "stapler"
version = "1.0.0" version = "1.1.0"
description = "Static pages as simple as a gzip file" description = "Static pages as simple as a gzip file"
requires-python = ">=3.14" requires-python = ">=3.14"
dependencies = [ dependencies = [
@@ -11,7 +11,7 @@ dependencies = [
stapler = "stapler.__main__:main" stapler = "stapler.__main__:main"
[build-system] [build-system]
requires = ["uv_build>=0.11.7"] requires = ["uv_build>=0.11.7,<0.12"]
build-backend = "uv_build" build-backend = "uv_build"
[tool.uv.build-backend] [tool.uv.build-backend]
+5 -2
View File
@@ -538,7 +538,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler, BaseHandler):
return self.registry.get_from_host(self.host) return self.registry.get_from_host(self.host)
class UpgradeHandler(BaseHandler): class UpgradeHandler(RequestHandler):
server_version = "StaplerUpgradeServer/" + PKG_VERSION server_version = "StaplerUpgradeServer/" + PKG_VERSION
def do_HEAD(self) -> None: def do_HEAD(self) -> None:
@@ -546,4 +546,7 @@ class UpgradeHandler(BaseHandler):
self.send_redirect(f"https://{self.host}{self.path}") self.send_redirect(f"https://{self.host}{self.path}")
def do_GET(self) -> None: def do_GET(self) -> None:
self.do_HEAD() if self.path.startswith(self.CERTBOT_CHALLENGE_PATH):
super().do_GET()
else:
self.do_HEAD()
+2
View File
@@ -97,6 +97,8 @@ class StaplerServer:
return UpgradeHandler( return UpgradeHandler(
*args, *args,
params=self.params, params=self.params,
registry=self.registry,
token_manager=self.token_manager,
) )
def __start_upgrade_server(self) -> http.server.ThreadingHTTPServer: def __start_upgrade_server(self) -> http.server.ThreadingHTTPServer:
+36 -8
View File
@@ -1168,6 +1168,11 @@ class TestRequestHandler(BaseHandlerTestCase):
class TestUpgradeHandler(BaseHandlerTestCase): class TestUpgradeHandler(BaseHandlerTestCase):
@typing.override
def setUp(self) -> None:
self.data_dir = self.new_mock()
super().setUp()
def _get_handler( def _get_handler(
self, self,
path: str = "/", path: str = "/",
@@ -1183,6 +1188,8 @@ class TestUpgradeHandler(BaseHandlerTestCase):
"127.0.0.1", "127.0.0.1",
unittest.mock.MagicMock(), unittest.mock.MagicMock(),
params=Parameters(), params=Parameters(),
registry=self.new_mock(),
token_manager=self.new_mock(),
) )
handler.address_string = lambda: "127.0.0.1" # ty:ignore[invalid-assignment] handler.address_string = lambda: "127.0.0.1" # ty:ignore[invalid-assignment]
handler.requestline = f"{method} {path}" handler.requestline = f"{method} {path}"
@@ -1193,22 +1200,43 @@ class TestUpgradeHandler(BaseHandlerTestCase):
handler.rfile = rfile if rfile is not None else io.BytesIO() handler.rfile = rfile if rfile is not None else io.BytesIO()
handler.wfile = io.BytesIO() handler.wfile = io.BytesIO()
handler.logger = unittest.mock.Mock(logging.Logger) handler.logger = unittest.mock.Mock(logging.Logger)
handler.data_dir = self.data_dir
return handler return handler
def test_do_get(self) -> None: def test_do_get(self) -> None:
handler = self._get_handler("/file") handler = self._get_handler("/file")
with self.expects_status_only( with (
handler, self.expects_status_only(
http.HTTPStatus.MOVED_PERMANENTLY, handler,
headers={"Location": "https://localhost/file"}, http.HTTPStatus.MOVED_PERMANENTLY,
headers={"Location": "https://localhost/file"},
),
self.patch(
"http.server.SimpleHTTPRequestHandler.do_GET",
count=0,
),
self.seal_mocks(),
):
handler.do_GET()
def test_do_get_certbot(self) -> None:
handler = self._get_handler("/.well-known/acme-challenge/abcde")
with (
self.patch(
"http.server.SimpleHTTPRequestHandler.do_GET",
),
self.seal_mocks(),
): ):
handler.do_GET() handler.do_GET()
def test_do_head(self) -> None: def test_do_head(self) -> None:
handler = self._get_handler("/file") handler = self._get_handler("/file")
with self.expects_status_only( with (
handler, self.expects_status_only(
http.HTTPStatus.MOVED_PERMANENTLY, handler,
headers={"Location": "https://localhost/file"}, http.HTTPStatus.MOVED_PERMANENTLY,
headers={"Location": "https://localhost/file"},
),
self.seal_mocks(),
): ):
handler.do_HEAD() handler.do_HEAD()
Generated
+1 -1
View File
@@ -142,7 +142,7 @@ wheels = [
[[package]] [[package]]
name = "stapler" name = "stapler"
version = "1.0.0" version = "1.1.0"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "requests" }, { name = "requests" },