@@ -54,10 +54,16 @@ def wsgi_decoding_dance(s, charset="utf-8", errors="replace"):
5454 return s .encode ("latin1" ).decode (charset , errors )
5555
5656
57- def get_host (environ ):
58- # type: (Dict[str, str]) -> str
57+ def get_host (environ , use_x_forwarded_for = False ):
58+ # type: (Dict[str, str], bool ) -> str
5959 """Return the host for the given WSGI environment. Yanked from Werkzeug."""
60- if environ .get ("HTTP_HOST" ):
60+ if use_x_forwarded_for and "HTTP_X_FORWARDED_HOST" in environ :
61+ rv = environ ["HTTP_X_FORWARDED_HOST" ]
62+ if environ ["wsgi.url_scheme" ] == "http" and rv .endswith (":80" ):
63+ rv = rv [:- 3 ]
64+ elif environ ["wsgi.url_scheme" ] == "https" and rv .endswith (":443" ):
65+ rv = rv [:- 4 ]
66+ elif environ .get ("HTTP_HOST" ):
6167 rv = environ ["HTTP_HOST" ]
6268 if environ ["wsgi.url_scheme" ] == "http" and rv .endswith (":80" ):
6369 rv = rv [:- 3 ]
@@ -77,23 +83,24 @@ def get_host(environ):
7783 return rv
7884
7985
80- def get_request_url (environ ):
81- # type: (Dict[str, str]) -> str
86+ def get_request_url (environ , use_x_forwarded_for = False ):
87+ # type: (Dict[str, str], bool ) -> str
8288 """Return the absolute URL without query string for the given WSGI
8389 environment."""
8490 return "%s://%s/%s" % (
8591 environ .get ("wsgi.url_scheme" ),
86- get_host (environ ),
92+ get_host (environ , use_x_forwarded_for ),
8793 wsgi_decoding_dance (environ .get ("PATH_INFO" ) or "" ).lstrip ("/" ),
8894 )
8995
9096
9197class SentryWsgiMiddleware (object ):
92- __slots__ = ("app" ,)
98+ __slots__ = ("app" , "use_x_forwarded_for" )
9399
94- def __init__ (self , app ):
95- # type: (Callable[[Dict[str, str], Callable[..., Any]], Any]) -> None
100+ def __init__ (self , app , use_x_forwarded_for = False ):
101+ # type: (Callable[[Dict[str, str], Callable[..., Any]], Any], bool ) -> None
96102 self .app = app
103+ self .use_x_forwarded_for = use_x_forwarded_for
97104
98105 def __call__ (self , environ , start_response ):
99106 # type: (Dict[str, str], Callable[..., Any]) -> _ScopedResponse
@@ -110,7 +117,9 @@ def __call__(self, environ, start_response):
110117 scope .clear_breadcrumbs ()
111118 scope ._name = "wsgi"
112119 scope .add_event_processor (
113- _make_wsgi_event_processor (environ )
120+ _make_wsgi_event_processor (
121+ environ , self .use_x_forwarded_for
122+ )
114123 )
115124
116125 transaction = Transaction .continue_from_environ (
@@ -269,8 +278,8 @@ def close(self):
269278 reraise (* _capture_exception (self ._hub ))
270279
271280
272- def _make_wsgi_event_processor (environ ):
273- # type: (Dict[str, str]) -> EventProcessor
281+ def _make_wsgi_event_processor (environ , use_x_forwarded_for ):
282+ # type: (Dict[str, str], bool ) -> EventProcessor
274283 # It's a bit unfortunate that we have to extract and parse the request data
275284 # from the environ so eagerly, but there are a few good reasons for this.
276285 #
@@ -284,7 +293,7 @@ def _make_wsgi_event_processor(environ):
284293 # https://github.com/unbit/uwsgi/issues/1950
285294
286295 client_ip = get_client_ip (environ )
287- request_url = get_request_url (environ )
296+ request_url = get_request_url (environ , use_x_forwarded_for )
288297 query_string = environ .get ("QUERY_STRING" )
289298 method = environ .get ("REQUEST_METHOD" )
290299 env = dict (_get_environ (environ ))
0 commit comments