mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 17:51:08 -05:00
okay fine
This commit is contained in:
285
.venv/lib/python3.12/site-packages/daphne/cli.py
Normal file
285
.venv/lib/python3.12/site-packages/daphne/cli.py
Normal file
@@ -0,0 +1,285 @@
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
from argparse import ArgumentError, Namespace
|
||||
|
||||
from asgiref.compatibility import guarantee_single_callable
|
||||
|
||||
from .access import AccessLogGenerator
|
||||
from .endpoints import build_endpoint_description_strings
|
||||
from .server import Server
|
||||
from .utils import import_by_path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_HOST = "127.0.0.1"
|
||||
DEFAULT_PORT = 8000
|
||||
|
||||
|
||||
class CommandLineInterface:
|
||||
"""
|
||||
Acts as the main CLI entry point for running the server.
|
||||
"""
|
||||
|
||||
description = "Django HTTP/WebSocket server"
|
||||
|
||||
server_class = Server
|
||||
|
||||
def __init__(self):
|
||||
self.parser = argparse.ArgumentParser(description=self.description)
|
||||
self.parser.add_argument(
|
||||
"-p", "--port", type=int, help="Port number to listen on", default=None
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-b",
|
||||
"--bind",
|
||||
dest="host",
|
||||
help="The host/address to bind to",
|
||||
default=None,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--websocket_timeout",
|
||||
type=int,
|
||||
help="Maximum time to allow a websocket to be connected. -1 for infinite.",
|
||||
default=86400,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--websocket_connect_timeout",
|
||||
type=int,
|
||||
help="Maximum time to allow a connection to handshake. -1 for infinite",
|
||||
default=5,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-u",
|
||||
"--unix-socket",
|
||||
dest="unix_socket",
|
||||
help="Bind to a UNIX socket rather than a TCP host/port",
|
||||
default=None,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--fd",
|
||||
type=int,
|
||||
dest="file_descriptor",
|
||||
help="Bind to a file descriptor rather than a TCP host/port or named unix socket",
|
||||
default=None,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-e",
|
||||
"--endpoint",
|
||||
dest="socket_strings",
|
||||
action="append",
|
||||
help="Use raw server strings passed directly to twisted",
|
||||
default=[],
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-v",
|
||||
"--verbosity",
|
||||
type=int,
|
||||
help="How verbose to make the output",
|
||||
default=1,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-t",
|
||||
"--http-timeout",
|
||||
type=int,
|
||||
help="How long to wait for worker before timing out HTTP connections",
|
||||
default=None,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--access-log",
|
||||
help="Where to write the access log (- for stdout, the default for verbosity=1)",
|
||||
default=None,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--log-fmt",
|
||||
help="Log format to use",
|
||||
default="%(asctime)-15s %(levelname)-8s %(message)s",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--ping-interval",
|
||||
type=int,
|
||||
help="The number of seconds a WebSocket must be idle before a keepalive ping is sent",
|
||||
default=20,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--ping-timeout",
|
||||
type=int,
|
||||
help="The number of seconds before a WebSocket is closed if no response to a keepalive ping",
|
||||
default=30,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--application-close-timeout",
|
||||
type=int,
|
||||
help="The number of seconds an ASGI application has to exit after client disconnect before it is killed",
|
||||
default=10,
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--root-path",
|
||||
dest="root_path",
|
||||
help="The setting for the ASGI root_path variable",
|
||||
default="",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--proxy-headers",
|
||||
dest="proxy_headers",
|
||||
help="Enable parsing and using of X-Forwarded-For and X-Forwarded-Port headers and using that as the "
|
||||
"client address",
|
||||
default=False,
|
||||
action="store_true",
|
||||
)
|
||||
self.arg_proxy_host = self.parser.add_argument(
|
||||
"--proxy-headers-host",
|
||||
dest="proxy_headers_host",
|
||||
help="Specify which header will be used for getting the host "
|
||||
"part. Can be omitted, requires --proxy-headers to be specified "
|
||||
'when passed. "X-Real-IP" (when passed by your webserver) is a '
|
||||
"good candidate for this.",
|
||||
default=False,
|
||||
action="store",
|
||||
)
|
||||
self.arg_proxy_port = self.parser.add_argument(
|
||||
"--proxy-headers-port",
|
||||
dest="proxy_headers_port",
|
||||
help="Specify which header will be used for getting the port "
|
||||
"part. Can be omitted, requires --proxy-headers to be specified "
|
||||
"when passed.",
|
||||
default=False,
|
||||
action="store",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"application",
|
||||
help="The application to dispatch to as path.to.module:instance.path",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-s",
|
||||
"--server-name",
|
||||
dest="server_name",
|
||||
help="specify which value should be passed to response header Server attribute",
|
||||
default="daphne",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--no-server-name", dest="server_name", action="store_const", const=""
|
||||
)
|
||||
|
||||
self.server = None
|
||||
|
||||
@classmethod
|
||||
def entrypoint(cls):
|
||||
"""
|
||||
Main entrypoint for external starts.
|
||||
"""
|
||||
cls().run(sys.argv[1:])
|
||||
|
||||
def _check_proxy_headers_passed(self, argument: str, args: Namespace):
|
||||
"""Raise if the `--proxy-headers` weren't specified."""
|
||||
if args.proxy_headers:
|
||||
return
|
||||
raise ArgumentError(
|
||||
argument=argument,
|
||||
message="--proxy-headers has to be passed for this parameter.",
|
||||
)
|
||||
|
||||
def _get_forwarded_host(self, args: Namespace):
|
||||
"""
|
||||
Return the default host header from which the remote hostname/ip
|
||||
will be extracted.
|
||||
"""
|
||||
if args.proxy_headers_host:
|
||||
self._check_proxy_headers_passed(argument=self.arg_proxy_host, args=args)
|
||||
return args.proxy_headers_host
|
||||
if args.proxy_headers:
|
||||
return "X-Forwarded-For"
|
||||
|
||||
def _get_forwarded_port(self, args: Namespace):
|
||||
"""
|
||||
Return the default host header from which the remote hostname/ip
|
||||
will be extracted.
|
||||
"""
|
||||
if args.proxy_headers_port:
|
||||
self._check_proxy_headers_passed(argument=self.arg_proxy_port, args=args)
|
||||
return args.proxy_headers_port
|
||||
if args.proxy_headers:
|
||||
return "X-Forwarded-Port"
|
||||
|
||||
def run(self, args):
|
||||
"""
|
||||
Pass in raw argument list and it will decode them
|
||||
and run the server.
|
||||
"""
|
||||
# Decode args
|
||||
args = self.parser.parse_args(args)
|
||||
# Set up logging
|
||||
logging.basicConfig(
|
||||
level={
|
||||
0: logging.WARN,
|
||||
1: logging.INFO,
|
||||
2: logging.DEBUG,
|
||||
3: logging.DEBUG, # Also turns on asyncio debug
|
||||
}[args.verbosity],
|
||||
format=args.log_fmt,
|
||||
)
|
||||
# If verbosity is 1 or greater, or they told us explicitly, set up access log
|
||||
access_log_stream = None
|
||||
if args.access_log:
|
||||
if args.access_log == "-":
|
||||
access_log_stream = sys.stdout
|
||||
else:
|
||||
access_log_stream = open(args.access_log, "a", 1)
|
||||
elif args.verbosity >= 1:
|
||||
access_log_stream = sys.stdout
|
||||
|
||||
# Import application
|
||||
sys.path.insert(0, ".")
|
||||
application = import_by_path(args.application)
|
||||
application = guarantee_single_callable(application)
|
||||
|
||||
# Set up port/host bindings
|
||||
if not any(
|
||||
[
|
||||
args.host,
|
||||
args.port is not None,
|
||||
args.unix_socket,
|
||||
args.file_descriptor is not None,
|
||||
args.socket_strings,
|
||||
]
|
||||
):
|
||||
# no advanced binding options passed, patch in defaults
|
||||
args.host = DEFAULT_HOST
|
||||
args.port = DEFAULT_PORT
|
||||
elif args.host and args.port is None:
|
||||
args.port = DEFAULT_PORT
|
||||
elif args.port is not None and not args.host:
|
||||
args.host = DEFAULT_HOST
|
||||
# Build endpoint description strings from (optional) cli arguments
|
||||
endpoints = build_endpoint_description_strings(
|
||||
host=args.host,
|
||||
port=args.port,
|
||||
unix_socket=args.unix_socket,
|
||||
file_descriptor=args.file_descriptor,
|
||||
)
|
||||
endpoints = sorted(args.socket_strings + endpoints)
|
||||
# Start the server
|
||||
logger.info("Starting server at {}".format(", ".join(endpoints)))
|
||||
self.server = self.server_class(
|
||||
application=application,
|
||||
endpoints=endpoints,
|
||||
http_timeout=args.http_timeout,
|
||||
ping_interval=args.ping_interval,
|
||||
ping_timeout=args.ping_timeout,
|
||||
websocket_timeout=args.websocket_timeout,
|
||||
websocket_connect_timeout=args.websocket_connect_timeout,
|
||||
websocket_handshake_timeout=args.websocket_connect_timeout,
|
||||
application_close_timeout=args.application_close_timeout,
|
||||
action_logger=AccessLogGenerator(access_log_stream)
|
||||
if access_log_stream
|
||||
else None,
|
||||
root_path=args.root_path,
|
||||
verbosity=args.verbosity,
|
||||
proxy_forwarded_address_header=self._get_forwarded_host(args=args),
|
||||
proxy_forwarded_port_header=self._get_forwarded_port(args=args),
|
||||
proxy_forwarded_proto_header="X-Forwarded-Proto"
|
||||
if args.proxy_headers
|
||||
else None,
|
||||
server_name=args.server_name,
|
||||
)
|
||||
self.server.run()
|
||||
Reference in New Issue
Block a user