diff --git a/CHANGES b/CHANGES index 2f47eab1..0e23b1fb 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,8 @@ Relase date to be decided, codename to be chosen. - Fixed an issue where the test client if used with the with statement did not trigger the execution of the teardown handlers. - Added finer control over the session cookie parameters. +- HEAD requests to a method view now automatically dispatch to the `get` + method if no handler was implemented. Version 0.7.3 ------------- diff --git a/flask/testsuite/views.py b/flask/testsuite/views.py index a89c44ac..c7cb0a8a 100644 --- a/flask/testsuite/views.py +++ b/flask/testsuite/views.py @@ -110,6 +110,41 @@ class ViewTestCase(FlaskTestCase): self.assert_equal(rv.headers['X-Parachute'], 'awesome') self.assert_equal(rv.data, 'Awesome') + def test_implicit_head(self): + app = flask.Flask(__name__) + + class Index(flask.views.MethodView): + def get(self): + return flask.Response('Blub', headers={ + 'X-Method': flask.request.method + }) + + app.add_url_rule('/', view_func=Index.as_view('index')) + c = app.test_client() + rv = c.get('/') + self.assert_equal(rv.data, 'Blub') + self.assert_equal(rv.headers['X-Method'], 'GET') + rv = c.head('/') + self.assert_equal(rv.data, '') + self.assert_equal(rv.headers['X-Method'], 'HEAD') + + def test_explicit_head(self): + app = flask.Flask(__name__) + + class Index(flask.views.MethodView): + def get(self): + return 'GET' + def head(self): + return flask.Response('', headers={'X-Method': 'HEAD'}) + + app.add_url_rule('/', view_func=Index.as_view('index')) + c = app.test_client() + rv = c.get('/') + self.assert_equal(rv.data, 'GET') + rv = c.head('/') + self.assert_equal(rv.data, '') + self.assert_equal(rv.headers['X-Method'], 'HEAD') + def suite(): suite = unittest.TestSuite() diff --git a/flask/views.py b/flask/views.py index 2fe34622..8f368bbc 100644 --- a/flask/views.py +++ b/flask/views.py @@ -143,5 +143,9 @@ class MethodView(View): def dispatch_request(self, *args, **kwargs): meth = getattr(self, request.method.lower(), None) - assert meth is not None, 'Not implemented method' + # if the request method is HEAD and we don't have a handler for it + # retry with GET + if meth is None and request.method == 'HEAD': + meth = getattr(self, 'get', None) + assert meth is not None, 'Not implemented method %r' % request.method return meth(*args, **kwargs)