Merge pull request #757 from jodal/feature/http-apps-without-slash

HTTP: Redirect /app to /app/
This commit is contained in:
Thomas Adamcik 2014-06-21 16:57:47 +02:00
commit 47ca709c6a
3 changed files with 53 additions and 14 deletions

View File

@ -84,6 +84,10 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
def _get_app_request_handlers(self):
result = []
for app in self.apps:
result.append((
r'/%s' % app['name'],
handlers.AddSlashHandler
))
request_handlers = app['factory'](self.config, self.core)
for handler in request_handlers:
handler = list(handler)
@ -96,7 +100,11 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
result = []
for static in self.statics:
result.append((
r'/%s/?(.*)' % static['name'],
r'/%s' % static['name'],
handlers.AddSlashHandler
))
result.append((
r'/%s/(.*)' % static['name'],
handlers.StaticFileHandler,
{
'path': static['path'],

View File

@ -23,7 +23,7 @@ def mopidy_app_factory(config, core):
(r'/rpc', JsonRpcHandler, {
'core': core,
}),
(r'/?(.*)', StaticFileHandler, {
(r'/(.*)', StaticFileHandler, {
'path': os.path.join(os.path.dirname(__file__), 'data'),
'default_filename': 'mopidy.html'
}),
@ -143,3 +143,10 @@ class StaticFileHandler(tornado.web.StaticFileHandler):
self.set_header('Cache-Control', 'no-cache')
self.set_header(
'X-Mopidy-Version', mopidy.__version__.encode('utf-8'))
class AddSlashHandler(tornado.web.RequestHandler):
@tornado.web.addslash
def prepare(self):
return super(AddSlashHandler, self).prepare()

View File

@ -33,7 +33,9 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
return tornado.web.Application(http_frontend._get_request_handlers())
def test_root_should_return_index(self):
class RootAppTest(HttpServerTest):
def test_should_return_index(self):
response = self.fetch('/', method='GET')
self.assertIn(
@ -43,7 +45,17 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
response.headers['X-Mopidy-Version'], mopidy.__version__)
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
def test_mopidy_should_return_index(self):
def test_should_return_static_files(self):
response = self.fetch('/mopidy.css', method='GET')
self.assertIn('html {', tornado.escape.to_unicode(response.body))
self.assertEqual(
response.headers['X-Mopidy-Version'], mopidy.__version__)
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
class MopidyAppTest(HttpServerTest):
def test_should_return_index(self):
response = self.fetch('/mopidy/', method='GET')
self.assertIn(
@ -53,17 +65,13 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
response.headers['X-Mopidy-Version'], mopidy.__version__)
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
def test_mopidy_should_return_index_no_slash(self):
response = self.fetch('/mopidy', method='GET')
def test_without_slash_should_redirect(self):
response = self.fetch('/mopidy', method='GET', follow_redirects=False)
self.assertIn(
'Here you can see events arriving from Mopidy in real time:',
tornado.escape.to_unicode(response.body))
self.assertEqual(
response.headers['X-Mopidy-Version'], mopidy.__version__)
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
self.assertEqual(response.code, 301)
self.assertEqual(response.headers['Location'], '/mopidy/')
def test_should_return_js(self):
def test_should_return_static_files(self):
response = self.fetch('/mopidy/mopidy.js', method='GET')
self.assertIn(
@ -73,6 +81,8 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
response.headers['X-Mopidy-Version'], mopidy.__version__)
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
class MopidyWebSocketHandlerTest(HttpServerTest):
def test_should_return_ws(self):
response = self.fetch('/mopidy/ws', method='GET')
@ -87,6 +97,8 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
'Can "Upgrade" only to "WebSocket".',
tornado.escape.to_unicode(response.body))
class MopidyRPCHandlerTest(HttpServerTest):
def test_should_return_rpc_error(self):
cmd = tornado.escape.json_encode({'action': 'get_version'})
@ -150,6 +162,12 @@ class HttpServerWithStaticFilesTest(tornado.testing.AsyncHTTPTestCase):
return tornado.web.Application(http_frontend._get_request_handlers())
def test_without_slash_should_redirect(self):
response = self.fetch('/static', method='GET', follow_redirects=False)
self.assertEqual(response.code, 301)
self.assertEqual(response.headers['Location'], '/static/')
def test_can_serve_static_files(self):
response = self.fetch('/static/test_server.py', method='GET')
@ -195,8 +213,14 @@ class HttpServerWithWsgiAppTest(tornado.testing.AsyncHTTPTestCase):
return tornado.web.Application(http_frontend._get_request_handlers())
def test_without_slash_should_redirect(self):
response = self.fetch('/wsgi', method='GET', follow_redirects=False)
self.assertEqual(response.code, 301)
self.assertEqual(response.headers['Location'], '/wsgi/')
def test_can_wrap_wsgi_apps(self):
response = self.fetch('/wsgi', method='GET')
response = self.fetch('/wsgi/', method='GET')
self.assertEqual(200, response.code)
self.assertIn(