Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add proxy-headers support to runserver #505

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions daphne/management/commands/runserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,71 @@ def add_arguments(self, parser):
"seconds (default: 5)"
),
)
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",
)
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",
)
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",
)

def _get_forwarded_host(self, options):
"""
Return the default host header from which the remote hostname/ip
will be extracted.
"""
proxy_headers = options.get("proxy_headers", None)
proxy_headers_host = options.get("proxy_headers_host", None)
if (proxy_headers is not None) and (proxy_headers_host is not None):
return proxy_headers_host
elif proxy_headers is not None:
return "X-Forwarded-For"
else:
return None

def _get_forwarded_port(self, options):
"""
Return the default host header from which the remote hostname/ip
will be extracted.
"""
proxy_headers = options.get("proxy_headers", None)
proxy_headers_port = options.get("proxy_headers_port", None)
if (proxy_headers is not None) and (proxy_headers_port is not None):
return proxy_headers_port
elif proxy_headers is not None:
return "X-Forwarded-Port"
else:
return None

def _get_forwarded_proto(self, options):
"""
Return the proper value for forwarded_proto.
"""
proxy_headers = options.get("proxy_headers", None)
if proxy_headers is not None:
return "X-Forwarded-Proto"
else:
return None

def handle(self, *args, **options):
self.http_timeout = options.get("http_timeout", None)
Expand Down Expand Up @@ -132,6 +197,9 @@ def inner_run(self, *args, **options):
http_timeout=self.http_timeout,
root_path=getattr(settings, "FORCE_SCRIPT_NAME", "") or "",
websocket_handshake_timeout=self.websocket_handshake_timeout,
proxy_forwarded_address_header=self._get_forwarded_host(options),
proxy_forwarded_port_header=self._get_forwarded_port(options),
proxy_forwarded_proto_header=self._get_forwarded_proto(options),
).run()
logger.debug("Daphne exited")
except KeyboardInterrupt:
Expand Down