HTTP/3 Support (#2378)

This commit is contained in:
Adam Hopkins
2022-06-27 11:19:26 +03:00
committed by GitHub
parent 70382f21ba
commit b59da498cc
72 changed files with 2567 additions and 437 deletions

View File

@@ -58,10 +58,13 @@ Or, a path to a directory to run as a simple HTTP server:
os.environ.get("SANIC_RELOADER_PROCESS", "") != "true"
)
self.args: List[Any] = []
self.groups: List[Group] = []
def attach(self):
for group in Group._registry:
group.create(self.parser).attach()
instance = group.create(self.parser)
instance.attach()
self.groups.append(instance)
def run(self):
# This is to provide backwards compat -v to display version
@@ -81,9 +84,13 @@ Or, a path to a directory to run as a simple HTTP server:
try:
app = self._get_app()
kwargs = self._build_run_kwargs()
app.run(**kwargs)
except ValueError:
error_logger.exception("Failed to run app")
else:
for http_version in self.args.http:
app.prepare(**kwargs, version=http_version)
Sanic.serve()
def _precheck(self):
# # Custom TLS mismatch handling for better diagnostics
@@ -163,11 +170,14 @@ Or, a path to a directory to run as a simple HTTP server:
" Example File: project/sanic_server.py -> app\n"
" Example Module: project.sanic_server.app"
)
sys.exit(1)
else:
raise e
return app
def _build_run_kwargs(self):
for group in self.groups:
group.prepare(self.args)
ssl: Union[None, dict, str, list] = []
if self.args.tlshost:
ssl.append(None)
@@ -192,6 +202,7 @@ Or, a path to a directory to run as a simple HTTP server:
"unix": self.args.unix,
"verbosity": self.args.verbosity or 0,
"workers": self.args.workers,
"auto_tls": self.args.auto_tls,
}
for maybe_arg in ("auto_reload", "dev"):
@@ -201,4 +212,5 @@ Or, a path to a directory to run as a simple HTTP server:
if self.args.path:
kwargs["auto_reload"] = True
kwargs["reload_dir"] = self.args.path
return kwargs

View File

@@ -3,9 +3,10 @@ from __future__ import annotations
from argparse import ArgumentParser, _ArgumentGroup
from typing import List, Optional, Type, Union
from sanic_routing import __version__ as __routing_version__ # type: ignore
from sanic_routing import __version__ as __routing_version__
from sanic import __version__
from sanic.http.constants import HTTP
class Group:
@@ -38,6 +39,9 @@ class Group:
"--no-" + args[0][2:], *args[1:], action="store_false", **kwargs
)
def prepare(self, args) -> None:
...
class GeneralGroup(Group):
name = None
@@ -83,6 +87,44 @@ class ApplicationGroup(Group):
)
class HTTPVersionGroup(Group):
name = "HTTP version"
def attach(self):
http_values = [http.value for http in HTTP.__members__.values()]
self.container.add_argument(
"--http",
dest="http",
action="append",
choices=http_values,
type=int,
help=(
"Which HTTP version to use: HTTP/1.1 or HTTP/3. Value should\n"
"be either 1, or 3. [default 1]"
),
)
self.container.add_argument(
"-1",
dest="http",
action="append_const",
const=1,
help=("Run Sanic server using HTTP/1.1"),
)
self.container.add_argument(
"-3",
dest="http",
action="append_const",
const=3,
help=("Run Sanic server using HTTP/3"),
)
def prepare(self, args):
if not args.http:
args.http = [1]
args.http = tuple(sorted(set(map(HTTP, args.http)), reverse=True))
class SocketGroup(Group):
name = "Socket binding"
@@ -92,7 +134,6 @@ class SocketGroup(Group):
"--host",
dest="host",
type=str,
default="127.0.0.1",
help="Host address [default 127.0.0.1]",
)
self.container.add_argument(
@@ -100,7 +141,6 @@ class SocketGroup(Group):
"--port",
dest="port",
type=int,
default=8000,
help="Port to serve on [default 8000]",
)
self.container.add_argument(
@@ -180,11 +220,7 @@ class DevelopmentGroup(Group):
"--debug",
dest="debug",
action="store_true",
help=(
"Run the server in DEBUG mode. It includes DEBUG logging,\n"
"additional context on exceptions, and other settings\n"
"not-safe for PRODUCTION, but helpful for debugging problems."
),
help="Run the server in debug mode",
)
self.container.add_argument(
"-r",
@@ -209,7 +245,16 @@ class DevelopmentGroup(Group):
"--dev",
dest="dev",
action="store_true",
help=("debug + auto reload."),
help=("debug + auto reload"),
)
self.container.add_argument(
"--auto-tls",
dest="auto_tls",
action="store_true",
help=(
"Create a temporary TLS certificate for local development "
"(requires mkcert or trustme)"
),
)