From 97158d8b6470954224098c12ad38d3ccfa04c03e Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Thu, 17 Feb 2022 12:11:47 +0200 Subject: [PATCH] Add altsvs --- sanic/touchup/schemes/altsvc.py | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 sanic/touchup/schemes/altsvc.py diff --git a/sanic/touchup/schemes/altsvc.py b/sanic/touchup/schemes/altsvc.py new file mode 100644 index 00000000..05e7269b --- /dev/null +++ b/sanic/touchup/schemes/altsvc.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from ast import Assign, Constant, NodeTransformer, Subscript +from typing import TYPE_CHECKING, Any, List + +from sanic.http.constants import HTTP + +from .base import BaseScheme + + +if TYPE_CHECKING: + from sanic import Sanic + + +class AltSvcCheck(BaseScheme): + ident = "ALTSVC" + + def visitors(self) -> List[NodeTransformer]: + return [RemoveAltSvc(self.app, self.app.state.verbosity)] + + +class RemoveAltSvc(NodeTransformer): + def __init__(self, app: Sanic, verbosity: int = 0) -> None: + self._app = app + self._verbosity = verbosity + self._versions = { + info.settings["version"] for info in app.state.server_info + } + + def visit_Assign(self, node: Assign) -> Any: + if any(self._matches(target) for target in node.targets): + if self._should_remove(): + return None + assert isinstance(node.value, Constant) + node.value.value = self.value() + return node + + def _should_remove(self) -> bool: + return len(self._versions) == 1 + + @staticmethod + def _matches(node) -> bool: + return ( + isinstance(node, Subscript) + and isinstance(node.slice, Constant) + and node.slice.value == "alt-svc" + ) + + def value(self): + values = [] + for info in self._app.state.server_info: + port = info.settings["port"] + version = info.settings["version"] + if version is HTTP.VERSION_3: + values.append(f'h3=":{port}"') + return ", ".join(values)