| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- """
- Copyright (c) 2007 by the Pallets team.
- Some rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- """
- from typing import TYPE_CHECKING
- if TYPE_CHECKING:
- from typing import Dict
- from typing import Iterator
- from typing import Tuple
- from typing import Optional
- #
- # `get_headers` comes from `werkzeug.datastructures.EnvironHeaders`
- # https://github.com/pallets/werkzeug/blob/0.14.1/werkzeug/datastructures.py#L1361
- #
- # We need this function because Django does not give us a "pure" http header
- # dict. So we might as well use it for all WSGI integrations.
- #
- def _get_headers(environ: "Dict[str, str]") -> "Iterator[Tuple[str, str]]":
- """
- Returns only proper HTTP headers.
- """
- for key, value in environ.items():
- key = str(key)
- if key.startswith("HTTP_") and key not in (
- "HTTP_CONTENT_TYPE",
- "HTTP_CONTENT_LENGTH",
- ):
- yield key[5:].replace("_", "-").title(), value
- elif key in ("CONTENT_TYPE", "CONTENT_LENGTH"):
- yield key.replace("_", "-").title(), value
- def _strip_default_port(host: str, scheme: "Optional[str]") -> str:
- """Strip the port from the host if it's the default for the scheme."""
- if scheme == "http" and host.endswith(":80"):
- return host[:-3]
- if scheme == "https" and host.endswith(":443"):
- return host[:-4]
- return host
- # `get_host` comes from `werkzeug.wsgi.get_host`
- # https://github.com/pallets/werkzeug/blob/1.0.1/src/werkzeug/wsgi.py#L145
- def get_host(environ: "Dict[str, str]", use_x_forwarded_for: bool = False) -> str:
- """
- Return the host for the given WSGI environment.
- """
- scheme = environ.get("wsgi.url_scheme")
- if use_x_forwarded_for:
- scheme = environ.get("HTTP_X_FORWARDED_PROTO", scheme)
- if use_x_forwarded_for and "HTTP_X_FORWARDED_HOST" in environ:
- return _strip_default_port(environ["HTTP_X_FORWARDED_HOST"], scheme)
- elif environ.get("HTTP_HOST"):
- return _strip_default_port(environ["HTTP_HOST"], scheme)
- elif environ.get("SERVER_NAME"):
- # SERVER_NAME/SERVER_PORT describe the internal server, so use
- # wsgi.url_scheme (not the forwarded scheme) for port decisions.
- rv = environ["SERVER_NAME"]
- if (environ["wsgi.url_scheme"], environ["SERVER_PORT"]) not in (
- ("https", "443"),
- ("http", "80"),
- ):
- rv += ":" + environ["SERVER_PORT"]
- return rv
- else:
- # In spite of the WSGI spec, SERVER_NAME might not be present.
- return "unknown"
|