"""
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
#
# `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):
# type: (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
#
# `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, use_x_forwarded_for=
False):
# type: (Dict[str, str], bool) -> str
"""
Return the host
for the given WSGI environment.
"""
if use_x_forwarded_for
and "HTTP_X_FORWARDED_HOST" in environ:
rv = environ[
"HTTP_X_FORWARDED_HOST"]
if environ[
"wsgi.url_scheme"] ==
"http" and rv.endswith(
":80"):
rv = rv[:-
3]
elif environ[
"wsgi.url_scheme"] ==
"https" and rv.endswith(
":443"):
rv = rv[:-
4]
elif environ.get(
"HTTP_HOST"):
rv = environ[
"HTTP_HOST"]
if environ[
"wsgi.url_scheme"] ==
"http" and rv.endswith(
":80"):
rv = rv[:-
3]
elif environ[
"wsgi.url_scheme"] ==
"https" and rv.endswith(
":443"):
rv = rv[:-
4]
elif environ.get(
"SERVER_NAME"):
rv = environ[
"SERVER_NAME"]
if (environ[
"wsgi.url_scheme"], environ[
"SERVER_PORT"])
not in (
(
"https",
"443"),
(
"http",
"80"),
):
rv +=
":" + environ[
"SERVER_PORT"]
else:
# In spite of the WSGI spec, SERVER_NAME might not be present.
rv =
"unknown"
return rv