Compare commits

..

5 Commits

2 changed files with 34 additions and 30 deletions

View File

@@ -49,7 +49,7 @@ from sanic.application.motd import MOTD
from sanic.application.state import ApplicationServerInfo, Mode, ServerStage
from sanic.base.meta import SanicMeta
from sanic.compat import OS_IS_WINDOWS, StartMethod
from sanic.exceptions import ServerKilled
from sanic.exceptions import SanicException, ServerKilled
from sanic.helpers import Default, _default, is_atty
from sanic.http.constants import HTTP
from sanic.http.tls import get_ssl_context, process_to_context
@@ -657,9 +657,10 @@ class StartupMixin(metaclass=SanicMeta):
def get_server_location(
server_settings: Optional[Dict[str, Any]] = None
) -> str:
serve_location = ""
proto = "http"
if not server_settings:
return ""
return serve_location
host = server_settings["host"]
port = server_settings["port"]
@@ -667,33 +668,16 @@ class StartupMixin(metaclass=SanicMeta):
if server_settings.get("ssl") is not None:
proto = "https"
if server_settings.get("unix"):
return f'{server_settings["unix"]} {proto}://localhost'
if server_settings.get("sock"):
serve_location = f'{server_settings["unix"]} {proto}://...'
elif server_settings.get("sock"):
host, port, *_ = server_settings["sock"].getsockname()
if not host or not port:
return ""
# colon(:) is legal for a host only in an ipv6 address
url_host = f"[{host}]" if ":" in host else host
url_port = (
""
if (
(proto == "https" and port == 443)
or (proto == "http" and port == 80)
)
else f":{port}"
)
if not serve_location and host and port:
# colon(:) is legal for a host only in an ipv6 address
display_host = f"[{host}]" if ":" in host else host
serve_location = f"{proto}://{display_host}:{port}"
special = {
"127.0.0.1": "IPv4",
"0.0.0.0": "IPv4 wildcard",
"::1": "IPv6",
"::": "IPv6 wildcard",
}.get(host, "")
if special:
return f"({special}) {proto}://localhost{url_port}"
return f"{proto}://{url_host}{url_port}"
return serve_location
@staticmethod
def get_address(
@@ -896,12 +880,18 @@ class StartupMixin(metaclass=SanicMeta):
manager.run()
except ServerKilled:
exit_code = 1
except SanicException as e:
exit_code = 1
kwargs = primary_server_info.settings
if e.quiet:
error_logger.error(str(e))
else:
raise
except BaseException:
kwargs = primary_server_info.settings
error_logger.exception(
"Experienced exception while trying to serve"
)
raise
finally:
logger.info("Server Stopped")
for app in apps:

View File

@@ -47,10 +47,10 @@ def bind_unix_socket(path: str, *, mode=0o666, backlog=100) -> socket.socket:
path = os.path.abspath(path)
folder = os.path.dirname(path)
if not os.path.isdir(folder):
raise FileNotFoundError(f"Socket folder does not exist: {folder}")
raise FileNotFoundError("Socket folder does not exist")
try:
if not stat.S_ISSOCK(os.stat(path, follow_symlinks=False).st_mode):
raise FileExistsError(f"Existing file is not a socket: {path}")
raise FileExistsError("Existing file is not a socket")
except FileNotFoundError:
pass
# Create new socket with a random temporary name
@@ -103,7 +103,10 @@ def configure_socket(
unix = server_settings["unix"]
backlog = server_settings["backlog"]
if unix:
sock = bind_unix_socket(unix, backlog=backlog)
try:
sock = bind_unix_socket(unix, backlog=backlog)
except OSError as e:
raise ServerError(f"Error binding {unix}: {e}", quiet=True)
server_settings["unix"] = unix
if sock is None:
try:
@@ -112,6 +115,17 @@ def configure_socket(
server_settings["port"],
backlog=backlog,
)
except PermissionError:
p = server_settings["port"]
if not p or p >= 1024:
raise
addr = f"{server_settings['host']}:{p}"
error = ServerError(
f"Permission denied binding to {addr}.\n\n"
"Use `sudo sanic` to run on a privileged port.\n"
)
error.quiet = True
raise error
except OSError as e: # no cov
error = ServerError(
f"Sanic server could not start: {e}.\n\n"