diff --git a/flask/app.py b/flask/app.py index 2ca641e3..aa6371d6 100644 --- a/flask/app.py +++ b/flask/app.py @@ -704,7 +704,7 @@ class Flask(_PackageBoundObject): raise req.routing_exception rule = req.url_rule # if we provide automatic options for this URL and the - # request came with the OPTIONS method, reply automatically + # request came with the OPTIONS method, reply automatically if rule.provide_automatic_options and req.method == 'OPTIONS': return self.make_default_options_response() # otherwise dispatch to the handler for that endpoint @@ -867,8 +867,10 @@ class Flask(_PackageBoundObject): if self.config.get('SERVER_NAME'): server_name = self.config.get('SERVER_NAME') if ':' not in server_name: - server_name += ':80' - http_host, http_port = server_name.split(':') + http_host, http_port = server_name, '80' + else: + http_host, http_port = server_name.split(':', 1) + environ_overrides.setdefault('SERVER_NAME', server_name) environ_overrides.setdefault('HTTP_HOST', server_name) environ_overrides.setdefault('SERVER_PORT', http_port) diff --git a/flask/testing.py b/flask/testing.py index ee4bd28e..84237336 100644 --- a/flask/testing.py +++ b/flask/testing.py @@ -10,7 +10,7 @@ :license: BSD, see LICENSE for more details. """ -from werkzeug import Client +from werkzeug import Client, EnvironBuilder from flask import _request_ctx_stack @@ -29,9 +29,31 @@ class FlaskClient(Client): self.context_preserved = False kwargs.setdefault('environ_overrides', {}) \ ['flask._preserve_context'] = self.preserve_context + + as_tuple = kwargs.pop('as_tuple', False) + buffered = kwargs.pop('buffered', False) + follow_redirects = kwargs.pop('follow_redirects', False) + + builder = EnvironBuilder(*args, **kwargs) + + if self.application.config.get('SERVER_NAME'): + server_name = self.application.config.get('SERVER_NAME') + if ':' not in server_name: + http_host, http_port = server_name, None + else: + http_host, http_port = server_name.split(':', 1) + if builder.base_url == 'http://localhost/': + # Default Generated Base URL + if http_port != None: + builder.host = http_host + ':' + http_port + else: + builder.host = http_host old = _request_ctx_stack.top try: - return Client.open(self, *args, **kwargs) + return Client.open(self, builder, + as_tuple=as_tuple, + buffered=buffered, + follow_redirects=follow_redirects) finally: self.context_preserved = _request_ctx_stack.top is not old diff --git a/tests/flask_tests.py b/tests/flask_tests.py index eac3efca..dddabf21 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -510,13 +510,114 @@ class BasicFunctionalityTestCase(unittest.TestCase): def index(): return None + @app.route('/', subdomain='foo') + def sub(): + return None + with app.test_request_context('/'): assert flask.url_for('index', _external=True) == 'http://localhost.localdomain:5000/' - def testit(): + with app.test_request_context('/'): + assert flask.url_for('sub', _external=True) == 'http://foo.localhost.localdomain:5000/' + + try: with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}): pass - self.assertRaises(ValueError, testit) + except Exception, e: + assert isinstance(e, ValueError) + assert str(e) == "the server name provided " + \ + "('localhost.localdomain:5000') does not match the " + \ + "server name from the WSGI environment ('localhost')", str(e) + + try: + app.config.update(SERVER_NAME='localhost') + with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost'}): + pass + except ValueError, e: + raise ValueError( + "No ValueError exception should have been raised \"%s\"" % e + ) + + try: + app.config.update(SERVER_NAME='localhost:80') + with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost:80'}): + pass + except ValueError, e: + raise ValueError( + "No ValueError exception should have been raised \"%s\"" % e + ) + + + def test_test_app_proper_environ(self): + app = flask.Flask(__name__) + app.config.update( + SERVER_NAME='localhost.localdomain:5000' + ) + @app.route('/') + def index(): + return 'Foo' + + @app.route('/', subdomain='foo') + def subdomain(): + return 'Foo SubDomain' + + try: + rv = app.test_client().get('/') + assert rv.data == 'Foo' + except ValueError, e: + raise ValueError( + "No ValueError exception should have been raised \"%s\"" % e + ) + + try: + rv = app.test_client().get('/', 'http://localhost.localdomain:5000') + assert rv.data == 'Foo' + except ValueError, e: + raise ValueError( + "No ValueError exception should have been raised \"%s\"" % e + ) + + try: + rv = app.test_client().get('/', 'https://localhost.localdomain:5000') + assert rv.data == 'Foo' + except ValueError, e: + raise ValueError( + "No ValueError exception should have been raised \"%s\"" % e + ) + + try: + app.config.update(SERVER_NAME='localhost.localdomain') + rv = app.test_client().get('/', 'https://localhost.localdomain') + assert rv.data == 'Foo' + except ValueError, e: + raise ValueError( + "No ValueError exception should have been raised \"%s\"" % e + ) + + try: + app.config.update(SERVER_NAME='localhost.localdomain:443') + rv = app.test_client().get('/', 'https://localhost.localdomain') + assert rv.data == 'Foo' + except ValueError, e: + assert str(e) == "the server name provided " + \ + "('localhost.localdomain:443') does not match the " + \ + "server name from the WSGI environment ('localhost.localdomain')", str(e) + + try: + app.config.update(SERVER_NAME='localhost.localdomain') + app.test_client().get('/', 'http://foo.localhost') + except ValueError, e: + assert str(e) == "the server name provided " + \ + "('localhost.localdomain') does not match the " + \ + "server name from the WSGI environment ('foo.localhost')", str(e) + + try: + rv = app.test_client().get('/', 'http://foo.localhost.localdomain') + assert rv.data == 'Foo SubDomain' + except ValueError, e: + raise ValueError( + "No ValueError exception should have been raised \"%s\"" % e + ) class JSONTestCase(unittest.TestCase):