--- /dev/null
+#!/usr/bin/env python
+
+from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase
+from tornado.web import authenticated, Application, RequestHandler
+import re
+import unittest
+import urllib
+
+class AuthRedirectRequestHandler(RequestHandler):
+ def initialize(self, login_url):
+ self.login_url = login_url
+
+ def get_login_url(self):
+ return self.login_url
+
+ @authenticated
+ def get(self):
+ # we'll never actually get here because the test doesn't follow redirects
+ self.send_error(500)
+
+class AuthRedirectTest(AsyncHTTPTestCase, LogTrapTestCase):
+ def get_app(self):
+ return Application([('/relative', AuthRedirectRequestHandler,
+ dict(login_url='/login')),
+ ('/absolute', AuthRedirectRequestHandler,
+ dict(login_url='http://example.com/login'))])
+
+ def test_relative_auth_redirect(self):
+ self.http_client.fetch(self.get_url('/relative'), self.stop,
+ follow_redirects=False)
+ response = self.wait()
+ self.assertEqual(response.code, 302)
+ self.assertEqual(response.headers['Location'], '/login?next=%2Frelative')
+
+ def test_absolute_auth_redirect(self):
+ self.http_client.fetch(self.get_url('/absolute'), self.stop,
+ follow_redirects=False)
+ response = self.wait()
+ self.assertEqual(response.code, 302)
+ self.assertTrue(re.match(
+ 'http://example.com/login\?next=http%3A%2F%2Flocalhost%3A[0-9]+%2Fabsolute',
+ response.headers['Location']), response.headers['Location'])
TEST_MODULES = [
'tornado.httputil.doctests',
+ 'tornado.test.httpserver_test',
'tornado.test.ioloop_test',
'tornado.test.stack_context_test',
'tornado.test.testing_test',
if self.request.method == "GET":
url = self.get_login_url()
if "?" not in url:
- url += "?" + urllib.urlencode(dict(next=self.request.uri))
+ if urlparse.urlsplit(url).scheme:
+ # if login url is absolute, make next absolute too
+ next_url = self.request.full_url()
+ else:
+ next_url = self.request.uri
+ url += "?" + urllib.urlencode(dict(next=next_url))
self.redirect(url)
return
raise HTTPError(403)