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):
|
||||
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'],
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user