2019-03-21 19:01:14 +00:00
|
|
|
from __future__ import (
|
|
|
|
print_function,
|
|
|
|
unicode_literals,
|
|
|
|
absolute_import,
|
|
|
|
division,
|
|
|
|
)
|
|
|
|
|
2019-03-21 07:37:47 +00:00
|
|
|
import json
|
|
|
|
|
2019-03-21 00:14:47 +00:00
|
|
|
from autobahn.twisted.resource import WebSocketResource
|
2019-03-21 19:01:25 +00:00
|
|
|
from autobahn.twisted.websocket import (
|
|
|
|
WebSocketServerFactory,
|
|
|
|
WebSocketServerProtocol,
|
|
|
|
)
|
2019-03-21 07:37:47 +00:00
|
|
|
import eliot
|
|
|
|
|
2019-03-21 19:00:57 +00:00
|
|
|
from twisted.web.resource import (
|
|
|
|
Resource,
|
|
|
|
)
|
2019-03-21 00:14:47 +00:00
|
|
|
|
2019-03-25 16:01:36 +00:00
|
|
|
# Hotfix work-around https://github.com/crossbario/autobahn-python/issues/1151
|
|
|
|
from . import _autobahn_1151
|
|
|
|
_autobahn_1151.patch()
|
|
|
|
del _autobahn_1151
|
|
|
|
|
2019-03-21 00:14:47 +00:00
|
|
|
|
|
|
|
class TokenAuthenticatedWebSocketServerProtocol(WebSocketServerProtocol):
|
|
|
|
"""
|
2019-03-21 07:52:45 +00:00
|
|
|
A WebSocket protocol that looks for an `Authorization:` header
|
|
|
|
with a `tahoe-lafs` scheme and a token matching our private config
|
|
|
|
for `api_auth_token`.
|
2019-03-21 00:14:47 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
def onConnect(self, req):
|
2019-03-21 07:52:45 +00:00
|
|
|
"""
|
|
|
|
WebSocket callback
|
|
|
|
"""
|
2019-03-22 17:47:32 +00:00
|
|
|
# we don't care what WebSocket sub-protocol is
|
|
|
|
# negotiated, nor do we need to send headers to the
|
|
|
|
# client, so we ask Autobahn to just allow this
|
|
|
|
# connection with the defaults. We could return a
|
|
|
|
# (headers, protocol) pair here instead if required.
|
|
|
|
return None
|
2019-03-21 00:14:47 +00:00
|
|
|
|
2019-03-21 07:37:47 +00:00
|
|
|
def _received_eliot_log(self, message):
|
2019-03-21 07:52:45 +00:00
|
|
|
"""
|
|
|
|
While this WebSocket connection is open, this function is
|
|
|
|
registered as an eliot destination
|
|
|
|
"""
|
2019-03-21 07:37:47 +00:00
|
|
|
# probably want a try/except around here? what do we do if
|
2019-03-21 07:52:45 +00:00
|
|
|
# transmission fails or anything else bad happens?
|
2019-03-21 07:37:47 +00:00
|
|
|
self.sendMessage(json.dumps(message))
|
2019-03-21 00:14:47 +00:00
|
|
|
|
2019-03-21 07:37:47 +00:00
|
|
|
def onOpen(self):
|
2019-03-21 07:52:45 +00:00
|
|
|
"""
|
|
|
|
WebSocket callback
|
|
|
|
"""
|
2019-03-21 07:37:47 +00:00
|
|
|
eliot.add_destination(self._received_eliot_log)
|
2019-03-21 00:14:47 +00:00
|
|
|
|
2019-03-21 07:37:47 +00:00
|
|
|
def onClose(self, wasClean, code, reason):
|
2019-03-21 07:52:45 +00:00
|
|
|
"""
|
|
|
|
WebSocket callback
|
|
|
|
"""
|
2019-03-21 07:37:47 +00:00
|
|
|
try:
|
|
|
|
eliot.remove_destination(self._received_eliot_log)
|
|
|
|
except ValueError:
|
|
|
|
pass
|
2019-03-21 00:14:47 +00:00
|
|
|
|
|
|
|
|
2019-03-22 17:47:32 +00:00
|
|
|
def create_log_streaming_resource():
|
2019-03-21 17:58:46 +00:00
|
|
|
factory = WebSocketServerFactory()
|
2019-03-21 07:37:47 +00:00
|
|
|
factory.protocol = TokenAuthenticatedWebSocketServerProtocol
|
|
|
|
return WebSocketResource(factory)
|
2019-03-21 19:00:57 +00:00
|
|
|
|
|
|
|
|
2019-03-22 17:47:32 +00:00
|
|
|
def create_log_resources():
|
2019-03-21 19:00:57 +00:00
|
|
|
logs = Resource()
|
2019-03-22 17:47:32 +00:00
|
|
|
logs.putChild(b"v1", create_log_streaming_resource())
|
2019-03-21 19:00:57 +00:00
|
|
|
return logs
|