-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Use Forwarded, X-Forwarded-Scheme and X-Forwarded-Host for better scheme and host resolution #1881
Changes from 5 commits
b1043b4
85fcdfc
be95cb4
9554ce0
3799f85
76b1624
1f79171
c2848ed
6d37b83
73d4121
0cb4b22
eee65a4
e5c7bfe
2b33c7d
15462c2
b672b16
105c9ed
145f31f
b2a0cc5
09cd914
df470cd
5560bab
ef0c597
cd643a7
d1ba86b
8ede7d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -150,16 +150,31 @@ def secure(self): | |
""" | ||
return self.url.scheme == 'https' | ||
|
||
@reify | ||
def _forwarded(self): | ||
forwarded = self._message.headers.get(hdrs.FORWARDED) | ||
if forwarded is not None: | ||
parsed = re.findall( | ||
r'^by=([^;]*); +for=([^;]*); +host=([^;]*); +proto=(https?)$', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suspect the parser should be more complicated.
It means the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please note: the lase example contains two |
||
forwarded) | ||
if parsed: | ||
return parsed[0] | ||
return None | ||
|
||
@reify | ||
def _scheme(self): | ||
proto = 'http' | ||
if self._transport.get_extra_info('sslcontext'): | ||
return 'https' | ||
secure_proxy_ssl_header = self._secure_proxy_ssl_header | ||
if secure_proxy_ssl_header is not None: | ||
header, value = secure_proxy_ssl_header | ||
proto = 'https' | ||
elif self._secure_proxy_ssl_header is not None: | ||
header, value = self._secure_proxy_ssl_header | ||
if self.headers.get(header) == value: | ||
return 'https' | ||
return 'http' | ||
proto = 'https' | ||
elif self._forwarded: | ||
_, _, _, proto = self._forwarded | ||
elif hdrs.X_FORWARDED_PROTO in self._message.headers: | ||
proto = self._message.headers[hdrs.X_FORWARDED_PROTO] | ||
return proto | ||
|
||
@property | ||
def method(self): | ||
|
@@ -179,16 +194,29 @@ def version(self): | |
|
||
@reify | ||
def host(self): | ||
"""Read only property for getting *HOST* header of request. | ||
""" Hostname of the request. | ||
|
||
Hostname is resolved through the following headers, in this order: | ||
|
||
- Forwarded | ||
- X-Forwarded-Host | ||
- Host | ||
|
||
Returns str or None if HTTP request has no HOST header. | ||
Returns str, or None if no hostname is found in the headers. | ||
""" | ||
return self._message.headers.get(hdrs.HOST) | ||
host = None | ||
if self._forwarded: | ||
_, _, host, _ = self._forwarded | ||
elif hdrs.X_FORWARDED_HOST in self._message.headers: | ||
host = self._message.headers[hdrs.X_FORWARDED_HOST] | ||
elif hdrs.HOST in self._message.headers: | ||
host = self._message.headers[hdrs.HOST] | ||
return host | ||
|
||
@reify | ||
def url(self): | ||
return URL('{}://{}{}'.format(self._scheme, | ||
self._message.headers.get(hdrs.HOST), | ||
self.host, | ||
str(self._rel_url))) | ||
|
||
@property | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PEP8 here. Please split this to 2 lines or more of up to 79 characters per line. For more information on PEP8 see the www.python.org page on PEP8.