def test_get_host_multiple_forwarded(self): env = {'HTTP_X_FORWARDED_HOST': 'example.com, example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit'} self.assert_equal(wsgi.get_host(env), 'example.com') self.assert_equal( wsgi.get_host(create_environ('/', 'http://example.com')), 'example.com')
def test_get_host_by_http_host(): env = {'HTTP_HOST': 'example.org', 'wsgi.url_scheme': 'http'} assert wsgi.get_host(env) == 'example.org' env['HTTP_HOST'] = 'example.org:8080' assert wsgi.get_host(env) == 'example.org:8080' env['HOST_NAME'] = 'ignore me' assert wsgi.get_host(env) == 'example.org:8080'
def test_get_host(): """Host lookup""" env = {'HTTP_X_FORWARDED_HOST': 'example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit'} assert get_host(env) == 'example.org' assert get_host(create_environ('/', 'http://example.org')) \ == 'example.org'
def test_get_host_multiple_forwarded(self): env = { "HTTP_X_FORWARDED_HOST": "example.com, example.org", "SERVER_NAME": "bullshit", "HOST_NAME": "ignore me dammit", } self.assert_equal(wsgi.get_host(env), "example.com") self.assert_equal(wsgi.get_host(create_environ("/", "http://example.com")), "example.com")
def open(self, *args, **kwargs): as_tuple = kwargs.pop('as_tuple', False) buffered = kwargs.pop('buffered', False) follow_redirects = kwargs.pop('follow_redirects', False) environ = None if not kwargs and len(args) == 1: if isinstance(args[0], EnvironBuilder): environ = args[0].get_environ() elif isinstance(args[0], dict): environ = args[0] if environ is None: builder = EnvironBuilder(*args, **kwargs) try: environ = builder.get_environ() finally: builder.close() if self.cookie_jar is not None: self.cookie_jar.inject_wsgi(environ) rv = run_wsgi_app(self.application, environ, buffered=buffered) if self.cookie_jar is not None: self.cookie_jar.extract_wsgi(environ, rv[2]) redirect_chain = [] status_code = int(rv[1].split(None, 1)[0]) while status_code in (301, 302, 303, 305, 307) and follow_redirects: if not self.redirect_client: self.redirect_client = Client(self.application) self.redirect_client.cookie_jar = self.cookie_jar redirect = dict(rv[2])['Location'] scheme, netloc, script_root, qs, anchor = urlparse.urlsplit( redirect) base_url = urlparse.urlunsplit( (scheme, netloc, '', '', '')).rstrip('/') + '/' host = get_host(create_environ('/', base_url, query_string=qs)).split(':', 1)[0] if get_host(environ).split(':', 1)[0] != host: raise RuntimeError( '%r does not support redirect to external targets' % self.__class__) redirect_chain.append((redirect, status_code)) redirect_kwargs = {} redirect_kwargs.update({ 'path': script_root, 'base_url': base_url, 'query_string': qs, 'as_tuple': True, 'buffered': buffered, 'follow_redirects': False }) environ, rv = self.redirect_client.open(**redirect_kwargs) status_code = int(rv[1].split(None, 1)[0]) if redirect_chain[-1] in redirect_chain[0:-1]: raise ClientRedirectError('loop detected') response = self.response_wrapper(*rv) if as_tuple: return (environ, response) return response
def test_get_host_fallback(): assert ( wsgi.get_host({"SERVER_NAME": "foobar.example.com", "wsgi.url_scheme": "http", "SERVER_PORT": "80"}) == "foobar.example.com" ) assert ( wsgi.get_host({"SERVER_NAME": "foobar.example.com", "wsgi.url_scheme": "http", "SERVER_PORT": "81"}) == "foobar.example.com:81" )
def test_get_host(self): env = { 'HTTP_X_FORWARDED_HOST': 'example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit' } self.assert_equal(wsgi.get_host(env), 'example.org') assert wsgi.get_host(create_environ('/', 'http://example.org')) \ == 'example.org'
def test_get_host_fallback(self): self.assert_equal( wsgi.get_host({"SERVER_NAME": "foobar.example.com", "wsgi.url_scheme": "http", "SERVER_PORT": "80"}), "foobar.example.com", ) self.assert_equal( wsgi.get_host({"SERVER_NAME": "foobar.example.com", "wsgi.url_scheme": "http", "SERVER_PORT": "81"}), "foobar.example.com:81", )
def test_get_host(): env = { 'HTTP_X_FORWARDED_HOST': 'example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit' } assert wsgi.get_host(env) == 'example.org' assert wsgi.get_host(create_environ('/', 'http://example.org')) == \ 'example.org'
def test_get_host_validate_trusted_hosts(): env = {"SERVER_NAME": "example.org", "SERVER_PORT": "80", "wsgi.url_scheme": "http"} assert wsgi.get_host(env, trusted_hosts=[".example.org"]) == "example.org" pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=["example.com"]) env["SERVER_PORT"] = "8080" assert wsgi.get_host(env, trusted_hosts=[".example.org:8080"]) == "example.org:8080" pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=[".example.com"]) env = {"HTTP_HOST": "example.org", "wsgi.url_scheme": "http"} assert wsgi.get_host(env, trusted_hosts=[".example.org"]) == "example.org" pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=["example.com"])
def open(self, *args, **kwargs): as_tuple = kwargs.pop('as_tuple', False) buffered = kwargs.pop('buffered', False) follow_redirects = kwargs.pop('follow_redirects', False) environ = None if not kwargs and len(args) == 1: if isinstance(args[0], EnvironBuilder): environ = args[0].get_environ() elif isinstance(args[0], dict): environ = args[0] if environ is None: builder = EnvironBuilder(*args, **kwargs) try: environ = builder.get_environ() finally: builder.close() if self.cookie_jar is not None: self.cookie_jar.inject_wsgi(environ) rv = run_wsgi_app(self.application, environ, buffered=buffered) if self.cookie_jar is not None: self.cookie_jar.extract_wsgi(environ, rv[2]) redirect_chain = [] status_code = int(rv[1].split(None, 1)[0]) while status_code in (301, 302, 303, 305, 307) and follow_redirects: if not self.redirect_client: self.redirect_client = Client(self.application) self.redirect_client.cookie_jar = self.cookie_jar redirect = dict(rv[2])['Location'] scheme, netloc, script_root, qs, anchor = urlparse.urlsplit(redirect) base_url = urlparse.urlunsplit((scheme, netloc, '', '', '')).rstrip('/') + '/' host = get_host(create_environ('/', base_url, query_string=qs)).split(':', 1)[0] if get_host(environ).split(':', 1)[0] != host: raise RuntimeError('%r does not support redirect to external targets' % self.__class__) redirect_chain.append((redirect, status_code)) redirect_kwargs = {} redirect_kwargs.update({'path': script_root, 'base_url': base_url, 'query_string': qs, 'as_tuple': True, 'buffered': buffered, 'follow_redirects': False}) environ, rv = self.redirect_client.open(**redirect_kwargs) status_code = int(rv[1].split(None, 1)[0]) if redirect_chain[-1] in redirect_chain[0:-1]: raise ClientRedirectError('loop detected') response = self.response_wrapper(*rv) if as_tuple: return (environ, response) return response
def test_get_host_fallback(self): self.assert_equal(wsgi.get_host({ 'SERVER_NAME': 'foobar.example.com', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '80' }), 'foobar.example.com') self.assert_equal(wsgi.get_host({ 'SERVER_NAME': 'foobar.example.com', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '81' }), 'foobar.example.com:81')
def test_get_host_fallback(): assert wsgi.get_host({ 'SERVER_NAME': 'foobar.example.com', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '80' }) == 'foobar.example.com' assert wsgi.get_host({ 'SERVER_NAME': 'foobar.example.com', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '81' }) == 'foobar.example.com:81'
def test_get_host_fallback(): assert (wsgi.get_host({ "SERVER_NAME": "foobar.example.com", "wsgi.url_scheme": "http", "SERVER_PORT": "80", }) == "foobar.example.com") assert (wsgi.get_host({ "SERVER_NAME": "foobar.example.com", "wsgi.url_scheme": "http", "SERVER_PORT": "81", }) == "foobar.example.com:81")
def test_get_host_fallback(): """Test non Host header server name guessing""" assert get_host({ 'SERVER_NAME': 'foobar.example.com', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '80' }) == 'foobar.example.com' assert get_host({ 'SERVER_NAME': 'foobar.example.com', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '81' }) == 'foobar.example.com:81'
def test_get_host_by_server_name_and_port(): env = { 'SERVER_NAME': 'example.org', 'SERVER_PORT': '80', 'wsgi.url_scheme': 'http' } assert wsgi.get_host(env) == 'example.org' env['wsgi.url_scheme'] = 'https' assert wsgi.get_host(env) == 'example.org:80' env['SERVER_PORT'] = '8080' assert wsgi.get_host(env) == 'example.org:8080' env['SERVER_PORT'] = '443' assert wsgi.get_host(env) == 'example.org'
def test_get_host_validate_trusted_hosts(): env = {'SERVER_NAME': 'example.org', 'SERVER_PORT': '80', 'wsgi.url_scheme': 'http'} assert wsgi.get_host(env, trusted_hosts=['.example.org']) == 'example.org' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['example.com']) env['SERVER_PORT'] = '8080' assert wsgi.get_host(env, trusted_hosts=['.example.org:8080']) == 'example.org:8080' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['.example.com']) env = {'HTTP_HOST': 'example.org', 'wsgi.url_scheme': 'http'} assert wsgi.get_host(env, trusted_hosts=['.example.org']) == 'example.org' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['example.com'])
def resolve_redirect(self, response, new_location, environ, buffered=False): """Resolves a single redirect and triggers the request again directly on this redirect client. """ scheme, netloc, script_root, qs, anchor = url_parse(new_location) base_url = url_unparse((scheme, netloc, "", "", "")).rstrip("/") + "/" cur_server_name = netloc.split(":", 1)[0].split(".") real_server_name = get_host(environ).rsplit(":", 1)[0].split(".") if self.allow_subdomain_redirects: allowed = cur_server_name[-len(real_server_name) :] == real_server_name else: allowed = cur_server_name == real_server_name if not allowed: raise RuntimeError("%r does not support redirect to " "external targets" % self.__class__) # For redirect handling we temporarily disable the response # wrapper. This is not threadsafe but not a real concern # since the test client must not be shared anyways. old_response_wrapper = self.response_wrapper self.response_wrapper = None try: return self.open(path=script_root, base_url=base_url, query_string=qs, as_tuple=True, buffered=buffered) finally: self.response_wrapper = old_response_wrapper
def resolve_redirect(self, response, new_location, environ, buffered=False): """Resolves a single redirect and triggers the request again directly on this redirect client. """ scheme, netloc, script_root, qs, anchor = url_parse(new_location) base_url = url_unparse((scheme, netloc, '', '', '')).rstrip('/') + '/' cur_server_name = netloc.split(':', 1)[0].split('.') real_server_name = get_host(environ).rsplit(':', 1)[0].split('.') if self.allow_subdomain_redirects: allowed = cur_server_name[-len(real_server_name):] == real_server_name else: allowed = cur_server_name == real_server_name if not allowed: raise RuntimeError('%r does not support redirect to ' 'external targets' % self.__class__) # For redirect handling we temporarily disable the response # wrapper. This is not threadsafe but not a real concern # since the test client must not be shared anyways. old_response_wrapper = self.response_wrapper self.response_wrapper = None try: return self.open(path=script_root, base_url=base_url, query_string=qs, as_tuple=True, buffered=buffered) finally: self.response_wrapper = old_response_wrapper
def test_get_host_validation(self): env = {'HTTP_X_FORWARDED_HOST': 'example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit'} self.assert_equal(wsgi.get_host(env, trusted_hosts=['.example.org']), 'example.org') self.assert_raises(BadRequest, wsgi.get_host, env, trusted_hosts=['example.com'])
def app(request): return Response('%s|%s' % ( request.remote_addr, # do not use request.host as this fixes too :) request.environ['wsgi.url_scheme'] + '://' + get_host(request.environ) ))
def test_get_host_ignore_x_forwarded_for(): env = { 'HTTP_X_FORWARDED_HOST': 'forwarded', 'HTTP_HOST': 'example.org', 'wsgi.url_scheme': 'http' } assert wsgi.get_host(env) == 'example.org'
def test_get_host_validation(): env = { 'HTTP_X_FORWARDED_HOST': 'example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit' } assert wsgi.get_host(env, trusted_hosts=['.example.org']) == 'example.org' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['example.com'])
def resolve_redirect(self, response, new_location, environ, buffered=False): """Resolves a single redirect and triggers the request again directly on this redirect client. """ scheme, netloc, script_root, qs, anchor = url_parse(new_location) base_url = url_unparse((scheme, netloc, "", "", "")).rstrip("/") + "/" cur_server_name = netloc.split(":", 1)[0].split(".") real_server_name = get_host(environ).rsplit(":", 1)[0].split(".") if cur_server_name == [""]: # this is a local redirect having autocorrect_location_header=False cur_server_name = real_server_name base_url = EnvironBuilder(environ).base_url if self.allow_subdomain_redirects: allowed = cur_server_name[-len(real_server_name ):] == real_server_name else: allowed = cur_server_name == real_server_name if not allowed: raise RuntimeError("%r does not support redirect to " "external targets" % self.__class__) status_code = int(response[1].split(None, 1)[0]) if status_code == 307: method = environ["REQUEST_METHOD"] else: method = "GET" # For redirect handling we temporarily disable the response # wrapper. This is not threadsafe but not a real concern # since the test client must not be shared anyways. old_response_wrapper = self.response_wrapper self.response_wrapper = None try: return self.open( path=script_root, base_url=base_url, query_string=qs, as_tuple=True, buffered=buffered, method=method, ) finally: self.response_wrapper = old_response_wrapper
def test_get_host_validate_trusted_hosts(): env = { 'SERVER_NAME': 'example.org', 'SERVER_PORT': '80', 'wsgi.url_scheme': 'http' } assert wsgi.get_host(env, trusted_hosts=['.example.org']) == 'example.org' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['example.com']) env['SERVER_PORT'] = '8080' assert wsgi.get_host(env, trusted_hosts=['.example.org:8080' ]) == 'example.org:8080' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['.example.com']) env = {'HTTP_HOST': 'example.org', 'wsgi.url_scheme': 'http'} assert wsgi.get_host(env, trusted_hosts=['.example.org']) == 'example.org' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['example.com'])
def dispatcher(environ, start_response, handlers={'conf': conf_app}): host = drop_last(get_host(environ)) if not os.path.exists(os.path.join(BASE_DIR, host)): if host in handlers: del handlers[host] return error_app(environ, start_response) if host in handlers: return handlers[host]()(environ, start_response) if is_django(host): app = make_django_app(host) else: app = forwarding_app make_apache_confs(host) handlers[host] = app return app()(environ, start_response)
def resolve_redirect(self, response, new_location, environ, buffered=False): """Resolves a single redirect and triggers the request again directly on this redirect client. """ scheme, netloc, script_root, qs, anchor = url_parse(new_location) base_url = url_unparse((scheme, netloc, '', '', '')).rstrip('/') + '/' cur_server_name = netloc.split(':', 1)[0].split('.') real_server_name = get_host(environ).rsplit(':', 1)[0].split('.') if cur_server_name == ['']: # this is a local redirect having autocorrect_location_header=False cur_server_name = real_server_name base_url = EnvironBuilder(environ).base_url if self.allow_subdomain_redirects: allowed = cur_server_name[-len(real_server_name):] == real_server_name else: allowed = cur_server_name == real_server_name if not allowed: raise RuntimeError('%r does not support redirect to ' 'external targets' % self.__class__) status_code = int(response[1].split(None, 1)[0]) if status_code == 307: method = environ['REQUEST_METHOD'] else: method = 'GET' # For redirect handling we temporarily disable the response # wrapper. This is not threadsafe but not a real concern # since the test client must not be shared anyways. old_response_wrapper = self.response_wrapper self.response_wrapper = None try: return self.open(path=script_root, base_url=base_url, query_string=qs, as_tuple=True, buffered=buffered, method=method) finally: self.response_wrapper = old_response_wrapper
def test_get_host(environ, expect): environ.setdefault("wsgi.url_scheme", "http") assert wsgi.get_host(environ) == expect
def test_get_host(): env = {"HTTP_X_FORWARDED_HOST": "example.org", "SERVER_NAME": "bullshit", "HOST_NAME": "ignore me dammit"} assert wsgi.get_host(env) == "example.org" assert wsgi.get_host(create_environ("/", "http://example.org")) == "example.org"
def test_get_host(environ, expect): environ.setdefault('wsgi.url_scheme', 'http') assert wsgi.get_host(environ) == expect
def test_get_host(self): env = {'HTTP_X_FORWARDED_HOST': 'example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit'} self.assert_equal(wsgi.get_host(env), 'example.org') assert wsgi.get_host(create_environ('/', 'http://example.org')) \ == 'example.org'
def test_get_host_validation(): env = {'HTTP_X_FORWARDED_HOST': 'example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit'} assert wsgi.get_host(env, trusted_hosts=['.example.org']) == 'example.org' pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=['example.com'])
def test_get_host_multiple_forwarded(): env = {'HTTP_X_FORWARDED_HOST': 'example.com, example.org', 'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit'} assert wsgi.get_host(env) == 'example.com' assert wsgi.get_host(create_environ('/', 'http://example.com')) == \ 'example.com'
def test_get_host_validation(self): env = {"HTTP_X_FORWARDED_HOST": "example.org", "SERVER_NAME": "bullshit", "HOST_NAME": "ignore me dammit"} self.assert_equal(wsgi.get_host(env, trusted_hosts=[".example.org"]), "example.org") self.assert_raises(BadRequest, wsgi.get_host, env, trusted_hosts=["example.com"])
def host(self): return get_host(self.environ)
def __call__(self, environ, start_response): # type: (Mapping, Callable) -> Iterable[bytes] host = get_host(environ) app = self.hosts.get(host, self.default) return app(environ, start_response)
def open(self, *args, **kwargs): """Takes the same arguments as the :class:`EnvironBuilder` class with some additions: You can provide a :class:`EnvironBuilder` or a WSGI environment as only argument instead of the :class:`EnvironBuilder` arguments and two optional keyword arguments (`as_tuple`, `buffered`) that change the type of the return value or the way the application is executed. .. versionchanged:: 0.5 If a dict is provided as file in the dict for the `data` parameter the content type has to be called `content_type` now instead of `mimetype`. This change was made for consistency with :class:`werkzeug.FileWrapper`. The `follow_redirects` parameter was added to :func:`open`. Additional parameters: :param as_tuple: Returns a tuple in the form ``(environ, result)`` :param buffered: Set this to True to buffer the application run. This will automatically close the application for you as well. :param follow_redirects: Set this to True if the `Client` should follow HTTP redirects. """ as_tuple = kwargs.pop('as_tuple', False) buffered = kwargs.pop('buffered', False) follow_redirects = kwargs.pop('follow_redirects', False) environ = None if not kwargs and len(args) == 1: if isinstance(args[0], EnvironBuilder): environ = args[0].get_environ() elif isinstance(args[0], dict): environ = args[0] if environ is None: builder = EnvironBuilder(*args, **kwargs) try: environ = builder.get_environ() finally: builder.close() if self.cookie_jar is not None: self.cookie_jar.inject_wsgi(environ) rv = run_wsgi_app(self.application, environ, buffered=buffered) if self.cookie_jar is not None: self.cookie_jar.extract_wsgi(environ, rv[2]) # handle redirects redirect_chain = [] status_code = int(rv[1].split(None, 1)[0]) while status_code in (301, 302, 303, 305, 307) and follow_redirects: if not self.redirect_client: # assume that we're not using the user defined response wrapper # so that we don't need any ugly hacks to get the status # code from the response. self.redirect_client = Client(self.application) self.redirect_client.cookie_jar = self.cookie_jar redirect = dict(rv[2])['Location'] scheme, netloc, script_root, qs, anchor = urlparse.urlsplit(redirect) base_url = urlparse.urlunsplit((scheme, netloc, '', '', '')).rstrip('/') + '/' host = get_host(create_environ('/', base_url, query_string=qs)).split(':', 1)[0] if get_host(environ).split(':', 1)[0] != host: raise RuntimeError('%r does not support redirect to ' 'external targets' % self.__class__) redirect_chain.append((redirect, status_code)) # the redirect request should be a new request, and not be based on # the old request redirect_kwargs = {} redirect_kwargs.update({ 'path': script_root, 'base_url': base_url, 'query_string': qs, 'as_tuple': True, 'buffered': buffered, 'follow_redirects': False, }) environ, rv = self.redirect_client.open(**redirect_kwargs) status_code = int(rv[1].split(None, 1)[0]) # Prevent loops if redirect_chain[-1] in redirect_chain[0:-1]: raise ClientRedirectError("loop detected") response = self.response_wrapper(*rv) if as_tuple: return environ, response return response
def test_get_host_validation(): env = {"HTTP_X_FORWARDED_HOST": "example.org", "SERVER_NAME": "bullshit", "HOST_NAME": "ignore me dammit"} assert wsgi.get_host(env, trusted_hosts=[".example.org"]) == "example.org" pytest.raises(BadRequest, wsgi.get_host, env, trusted_hosts=["example.com"])