http: Split socket and server creation
This commit is contained in:
parent
215dd777f6
commit
3fac0cb8de
@ -7,7 +7,9 @@ import threading
|
|||||||
|
|
||||||
import pykka
|
import pykka
|
||||||
|
|
||||||
|
import tornado.httpserver
|
||||||
import tornado.ioloop
|
import tornado.ioloop
|
||||||
|
import tornado.netutil
|
||||||
import tornado.web
|
import tornado.web
|
||||||
import tornado.websocket
|
import tornado.websocket
|
||||||
|
|
||||||
@ -26,28 +28,32 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
|
|||||||
|
|
||||||
def __init__(self, config, core):
|
def __init__(self, config, core):
|
||||||
super(HttpFrontend, self).__init__()
|
super(HttpFrontend, self).__init__()
|
||||||
self.config = config
|
|
||||||
self.core = core
|
|
||||||
|
|
||||||
self.hostname = config['http']['hostname']
|
self.hostname = network.format_hostname(config['http']['hostname'])
|
||||||
self.port = config['http']['port']
|
self.port = config['http']['port']
|
||||||
|
tornado_hostname = config['http']['hostname']
|
||||||
self.zeroconf_name = config['http']['zeroconf']
|
if tornado_hostname == '::':
|
||||||
self.zeroconf_http = None
|
tornado_hostname = None
|
||||||
self.zeroconf_mopidy_http = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.debug('Starting HTTP server')
|
logger.debug('Starting HTTP server')
|
||||||
self.app = tornado.web.Application(self._get_request_handlers())
|
sockets = tornado.netutil.bind_sockets(self.port, tornado_hostname)
|
||||||
self.app.listen(
|
self.server = HttpServer(
|
||||||
self.port, self.hostname if self.hostname != '::' else None)
|
config=config, core=core, sockets=sockets,
|
||||||
|
apps=self.apps, statics=self.statics)
|
||||||
except IOError as error:
|
except IOError as error:
|
||||||
raise exceptions.FrontendError(
|
raise exceptions.FrontendError(
|
||||||
'HTTP server startup failed: %s' %
|
'HTTP server startup failed: %s' %
|
||||||
encoding.locale_decode(error))
|
encoding.locale_decode(error))
|
||||||
|
|
||||||
|
self.zeroconf_name = config['http']['zeroconf']
|
||||||
|
self.zeroconf_http = None
|
||||||
|
self.zeroconf_mopidy_http = None
|
||||||
|
|
||||||
def on_start(self):
|
def on_start(self):
|
||||||
threading.Thread(target=self._startup).start()
|
logger.info(
|
||||||
|
'HTTP server running at [%s]:%s', self.hostname, self.port)
|
||||||
|
self.server.start()
|
||||||
|
|
||||||
if self.zeroconf_name:
|
if self.zeroconf_name:
|
||||||
self.zeroconf_http = zeroconf.Zeroconf(
|
self.zeroconf_http = zeroconf.Zeroconf(
|
||||||
@ -65,18 +71,7 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
|
|||||||
if self.zeroconf_mopidy_http:
|
if self.zeroconf_mopidy_http:
|
||||||
self.zeroconf_mopidy_http.unpublish()
|
self.zeroconf_mopidy_http.unpublish()
|
||||||
|
|
||||||
tornado.ioloop.IOLoop.instance().add_callback(self._shutdown)
|
self.server.stop()
|
||||||
|
|
||||||
def _startup(self):
|
|
||||||
logger.info(
|
|
||||||
'HTTP server running at [%s]:%s',
|
|
||||||
network.format_hostname(self.hostname), self.port)
|
|
||||||
tornado.ioloop.IOLoop.instance().start()
|
|
||||||
|
|
||||||
def _shutdown(self):
|
|
||||||
logger.debug('Stopping HTTP server')
|
|
||||||
tornado.ioloop.IOLoop.instance().stop()
|
|
||||||
logger.debug('Stopped HTTP server')
|
|
||||||
|
|
||||||
def on_event(self, name, **data):
|
def on_event(self, name, **data):
|
||||||
event = data
|
event = data
|
||||||
@ -84,6 +79,36 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
|
|||||||
message = json.dumps(event, cls=models.ModelJSONEncoder)
|
message = json.dumps(event, cls=models.ModelJSONEncoder)
|
||||||
handlers.WebSocketHandler.broadcast(message)
|
handlers.WebSocketHandler.broadcast(message)
|
||||||
|
|
||||||
|
|
||||||
|
class HttpServer(threading.Thread):
|
||||||
|
name = 'HttpServer'
|
||||||
|
|
||||||
|
def __init__(self, config, core, sockets, apps, statics):
|
||||||
|
super(HttpServer, self).__init__()
|
||||||
|
|
||||||
|
self.config = config
|
||||||
|
self.core = core
|
||||||
|
self.sockets = sockets
|
||||||
|
self.apps = apps
|
||||||
|
self.statics = statics
|
||||||
|
|
||||||
|
self.app = None
|
||||||
|
self.server = None
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.app = tornado.web.Application(self._get_request_handlers())
|
||||||
|
self.server = tornado.httpserver.HTTPServer(self.app)
|
||||||
|
self.server.add_sockets(self.sockets)
|
||||||
|
|
||||||
|
tornado.ioloop.IOLoop.instance().start()
|
||||||
|
|
||||||
|
logger.debug('Stopped HTTP server')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
logger.debug('Stopping HTTP server')
|
||||||
|
tornado.ioloop.IOLoop.instance().add_callback(
|
||||||
|
tornado.ioloop.IOLoop.instance().stop)
|
||||||
|
|
||||||
def _get_request_handlers(self):
|
def _get_request_handlers(self):
|
||||||
request_handlers = []
|
request_handlers = []
|
||||||
request_handlers.extend(self._get_app_request_handlers())
|
request_handlers.extend(self._get_app_request_handlers())
|
||||||
|
|||||||
@ -27,16 +27,19 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
core.get_version = mock.MagicMock(name='get_version')
|
core.get_version = mock.MagicMock(name='get_version')
|
||||||
core.get_version.return_value = mopidy.__version__
|
core.get_version.return_value = mopidy.__version__
|
||||||
|
|
||||||
apps = [dict(name='testapp')]
|
testapps = [dict(name='testapp')]
|
||||||
statics = [dict(name='teststatic')]
|
teststatics = [dict(name='teststatic')]
|
||||||
|
|
||||||
http_frontend = actor.HttpFrontend(config=self.get_config(), core=core)
|
apps = [{
|
||||||
http_frontend.apps = [{
|
|
||||||
'name': 'mopidy',
|
'name': 'mopidy',
|
||||||
'factory': handlers.make_mopidy_app_factory(apps, statics),
|
'factory': handlers.make_mopidy_app_factory(testapps, teststatics),
|
||||||
}]
|
}]
|
||||||
|
|
||||||
return tornado.web.Application(http_frontend._get_request_handlers())
|
http_server = actor.HttpServer(
|
||||||
|
config=self.get_config(), core=core, sockets=[],
|
||||||
|
apps=apps, statics=[])
|
||||||
|
|
||||||
|
return tornado.web.Application(http_server._get_request_handlers())
|
||||||
|
|
||||||
|
|
||||||
class RootRedirectTest(HttpServerTest):
|
class RootRedirectTest(HttpServerTest):
|
||||||
@ -172,12 +175,12 @@ class HttpServerWithStaticFilesTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
}
|
}
|
||||||
core = mock.Mock()
|
core = mock.Mock()
|
||||||
|
|
||||||
http_frontend = actor.HttpFrontend(config=config, core=core)
|
statics = [dict(name='static', path=os.path.dirname(__file__))]
|
||||||
http_frontend.statics = [
|
|
||||||
dict(name='static', path=os.path.dirname(__file__)),
|
|
||||||
]
|
|
||||||
|
|
||||||
return tornado.web.Application(http_frontend._get_request_handlers())
|
http_server = actor.HttpServer(
|
||||||
|
config=config, core=core, sockets=[], apps=[], statics=statics)
|
||||||
|
|
||||||
|
return tornado.web.Application(http_server._get_request_handlers())
|
||||||
|
|
||||||
def test_without_slash_should_redirect(self):
|
def test_without_slash_should_redirect(self):
|
||||||
response = self.fetch('/static', method='GET', follow_redirects=False)
|
response = self.fetch('/static', method='GET', follow_redirects=False)
|
||||||
@ -222,13 +225,15 @@ class HttpServerWithWsgiAppTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
}
|
}
|
||||||
core = mock.Mock()
|
core = mock.Mock()
|
||||||
|
|
||||||
http_frontend = actor.HttpFrontend(config=config, core=core)
|
apps = [{
|
||||||
http_frontend.apps = [{
|
|
||||||
'name': 'wsgi',
|
'name': 'wsgi',
|
||||||
'factory': wsgi_app_factory,
|
'factory': wsgi_app_factory,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
return tornado.web.Application(http_frontend._get_request_handlers())
|
http_server = actor.HttpServer(
|
||||||
|
config=config, core=core, sockets=[], apps=apps, statics=[])
|
||||||
|
|
||||||
|
return tornado.web.Application(http_server._get_request_handlers())
|
||||||
|
|
||||||
def test_without_slash_should_redirect(self):
|
def test_without_slash_should_redirect(self):
|
||||||
response = self.fetch('/wsgi', method='GET', follow_redirects=False)
|
response = self.fetch('/wsgi', method='GET', follow_redirects=False)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user