Merge pull request #703 from croneter/fix-websocket

Allow websocket redirects. Never allow insecure HTTPs connections for Kodi Leia
This commit is contained in:
croneter 2019-02-05 18:59:04 +01:00 committed by GitHub
commit d8770603ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 16 deletions

View file

@ -105,6 +105,19 @@ class WebSocketTimeoutException(WebSocketException):
pass
class WebsocketRedirect(WebSocketException):
"""
WebsocketRedirect will be raised if a status code 301 is returned
The Exception will be instantiated with a dict containing all response
headers; which should contain the redirect address under the key 'location'
Access the headers via the attribute headers
"""
def __init__(self, headers):
self.headers = headers
super(WebsocketRedirect, self).__init__()
DEFAULT_TIMEOUT = None
TRACE_ENABLED = False
@ -162,10 +175,10 @@ def _parse_url(url):
port = parsed.port
is_secure = False
if scheme == "ws":
if scheme == "ws" or scheme == 'http':
if not port:
port = 80
elif scheme == "wss":
elif scheme == "wss" or scheme == 'https':
is_secure = True
if not port:
port = 443
@ -500,6 +513,9 @@ class WebSocket(object):
LOG.debug("-----------------------")
status, resp_headers = self._read_headers()
if status == 301:
# Redirect
raise WebsocketRedirect(resp_headers)
if status != 101:
self.close()
raise WebSocketException("Handshake Status %d" % status)

View file

@ -18,6 +18,7 @@ class WebSocket(backgroundthread.KillableThread):
def __init__(self):
self.ws = None
self.redirect_uri = None
super(WebSocket, self).__init__()
def process(self, opcode, message):
@ -91,6 +92,16 @@ class WebSocket(backgroundthread.KillableThread):
self.__class__.__name__)
self.ws = None
app.APP.monitor.waitForAbort(1)
except websocket.WebsocketRedirect as e:
LOG.info('301 redirect detected')
self.redirect_uri = e.headers.get('location', e.headers.get('Location'))
if self.redirect_uri:
self.redirect_uri.decode('utf-8')
counter += 1
if counter >= 10:
LOG.info('%s: Repeated WebsocketRedirect detected. Stopping now',
self.__class__.__name__)
break
except websocket.WebSocketException as e:
LOG.info('%s: WebSocketException: %s',
self.__class__.__name__, e)
@ -141,18 +152,22 @@ class PMS_Websocket(WebSocket):
app.SYNC.background_sync_disabled)
def getUri(self):
server = app.CONN.server
# Get the appropriate prefix for the websocket
if server.startswith('https'):
server = "wss%s" % server[5:]
if self.redirect_uri:
uri = self.redirect_uri
self.redirect_uri = None
else:
server = "ws%s" % server[4:]
uri = "%s/:/websockets/notifications" % server
# Need to use plex.tv token, if any. NOT user token
if app.ACCOUNT.plex_token:
uri += '?X-Plex-Token=%s' % app.ACCOUNT.plex_token
server = app.CONN.server
# Get the appropriate prefix for the websocket
if server.startswith('https'):
server = "wss%s" % server[5:]
else:
server = "ws%s" % server[4:]
uri = "%s/:/websockets/notifications" % server
# Need to use plex.tv token, if any. NOT user token
if app.ACCOUNT.plex_token:
uri += '?X-Plex-Token=%s' % app.ACCOUNT.plex_token
sslopt = {}
if utils.settings('sslverify') == "false":
if v.KODIVERSION == 17 and utils.settings('sslverify') == "false":
sslopt["cert_reqs"] = CERT_NONE
LOG.debug("%s: Uri: %s, sslopt: %s",
self.__class__.__name__, uri, sslopt)
@ -209,10 +224,14 @@ class Alexa_Websocket(WebSocket):
app.ACCOUNT.restricted_user)
def getUri(self):
uri = ('wss://pubsub.plex.tv/sub/websockets/%s/%s?X-Plex-Token=%s'
% (app.ACCOUNT.plex_user_id,
v.PKC_MACHINE_IDENTIFIER,
app.ACCOUNT.plex_token))
if self.redirect_uri:
uri = self.redirect_uri
self.redirect_uri = None
else:
uri = ('wss://pubsub.plex.tv/sub/websockets/%s/%s?X-Plex-Token=%s'
% (app.ACCOUNT.plex_user_id,
v.PKC_MACHINE_IDENTIFIER,
app.ACCOUNT.plex_token))
sslopt = {}
LOG.debug("%s: Uri: %s, sslopt: %s",
self.__class__.__name__, uri, sslopt)