Merge pull request #757 from jodal/feature/http-apps-without-slash
HTTP: Redirect /app to /app/
This commit is contained in:
commit
47ca709c6a
@ -84,6 +84,10 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
|
|||||||
def _get_app_request_handlers(self):
|
def _get_app_request_handlers(self):
|
||||||
result = []
|
result = []
|
||||||
for app in self.apps:
|
for app in self.apps:
|
||||||
|
result.append((
|
||||||
|
r'/%s' % app['name'],
|
||||||
|
handlers.AddSlashHandler
|
||||||
|
))
|
||||||
request_handlers = app['factory'](self.config, self.core)
|
request_handlers = app['factory'](self.config, self.core)
|
||||||
for handler in request_handlers:
|
for handler in request_handlers:
|
||||||
handler = list(handler)
|
handler = list(handler)
|
||||||
@ -96,7 +100,11 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
|
|||||||
result = []
|
result = []
|
||||||
for static in self.statics:
|
for static in self.statics:
|
||||||
result.append((
|
result.append((
|
||||||
r'/%s/?(.*)' % static['name'],
|
r'/%s' % static['name'],
|
||||||
|
handlers.AddSlashHandler
|
||||||
|
))
|
||||||
|
result.append((
|
||||||
|
r'/%s/(.*)' % static['name'],
|
||||||
handlers.StaticFileHandler,
|
handlers.StaticFileHandler,
|
||||||
{
|
{
|
||||||
'path': static['path'],
|
'path': static['path'],
|
||||||
|
|||||||
@ -23,7 +23,7 @@ def mopidy_app_factory(config, core):
|
|||||||
(r'/rpc', JsonRpcHandler, {
|
(r'/rpc', JsonRpcHandler, {
|
||||||
'core': core,
|
'core': core,
|
||||||
}),
|
}),
|
||||||
(r'/?(.*)', StaticFileHandler, {
|
(r'/(.*)', StaticFileHandler, {
|
||||||
'path': os.path.join(os.path.dirname(__file__), 'data'),
|
'path': os.path.join(os.path.dirname(__file__), 'data'),
|
||||||
'default_filename': 'mopidy.html'
|
'default_filename': 'mopidy.html'
|
||||||
}),
|
}),
|
||||||
@ -143,3 +143,10 @@ class StaticFileHandler(tornado.web.StaticFileHandler):
|
|||||||
self.set_header('Cache-Control', 'no-cache')
|
self.set_header('Cache-Control', 'no-cache')
|
||||||
self.set_header(
|
self.set_header(
|
||||||
'X-Mopidy-Version', mopidy.__version__.encode('utf-8'))
|
'X-Mopidy-Version', mopidy.__version__.encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
class AddSlashHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
|
@tornado.web.addslash
|
||||||
|
def prepare(self):
|
||||||
|
return super(AddSlashHandler, self).prepare()
|
||||||
|
|||||||
@ -33,7 +33,9 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
|
|
||||||
return tornado.web.Application(http_frontend._get_request_handlers())
|
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')
|
response = self.fetch('/', method='GET')
|
||||||
|
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
@ -43,7 +45,17 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
||||||
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
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')
|
response = self.fetch('/mopidy/', method='GET')
|
||||||
|
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
@ -53,17 +65,13 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
||||||
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
||||||
|
|
||||||
def test_mopidy_should_return_index_no_slash(self):
|
def test_without_slash_should_redirect(self):
|
||||||
response = self.fetch('/mopidy', method='GET')
|
response = self.fetch('/mopidy', method='GET', follow_redirects=False)
|
||||||
|
|
||||||
self.assertIn(
|
self.assertEqual(response.code, 301)
|
||||||
'Here you can see events arriving from Mopidy in real time:',
|
self.assertEqual(response.headers['Location'], '/mopidy/')
|
||||||
tornado.escape.to_unicode(response.body))
|
|
||||||
self.assertEqual(
|
|
||||||
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
|
||||||
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
|
||||||
|
|
||||||
def test_should_return_js(self):
|
def test_should_return_static_files(self):
|
||||||
response = self.fetch('/mopidy/mopidy.js', method='GET')
|
response = self.fetch('/mopidy/mopidy.js', method='GET')
|
||||||
|
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
@ -73,6 +81,8 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
||||||
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
||||||
|
|
||||||
|
|
||||||
|
class MopidyWebSocketHandlerTest(HttpServerTest):
|
||||||
def test_should_return_ws(self):
|
def test_should_return_ws(self):
|
||||||
response = self.fetch('/mopidy/ws', method='GET')
|
response = self.fetch('/mopidy/ws', method='GET')
|
||||||
|
|
||||||
@ -87,6 +97,8 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
'Can "Upgrade" only to "WebSocket".',
|
'Can "Upgrade" only to "WebSocket".',
|
||||||
tornado.escape.to_unicode(response.body))
|
tornado.escape.to_unicode(response.body))
|
||||||
|
|
||||||
|
|
||||||
|
class MopidyRPCHandlerTest(HttpServerTest):
|
||||||
def test_should_return_rpc_error(self):
|
def test_should_return_rpc_error(self):
|
||||||
cmd = tornado.escape.json_encode({'action': 'get_version'})
|
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())
|
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):
|
def test_can_serve_static_files(self):
|
||||||
response = self.fetch('/static/test_server.py', method='GET')
|
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())
|
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):
|
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.assertEqual(200, response.code)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user