annotate libervia/server/websockets.py @ 1504:409d10211b20

server, browser: dynamic pages refactoring: dynamic pages has been reworked, to change the initial basic implementation. Pages are now dynamic by default, and a websocket is established by the first connected page of a session. The socket is used to transmit bridge signals, and then the signal is broadcasted to other tabs using broadcast channel. If the connecting tab is closed, an other one is chosen. Some tests are made to retry connecting in case of problem, and sometimes reload the pages (e.g. if profile is connected). Signals (or other data) are cached during reconnection phase, to avoid lost of data. All previous partial rendering mechanism have been removed, chat page is temporarily not working anymore, but will be eventually redone (one of the goal of this work is to have proper chat).
author Goffi <goffi@goffi.org>
date Wed, 01 Mar 2023 18:02:44 +0100
parents 822bd0139769
children ce879da7fcf7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1239
f511f8fbbf8a fixed shebangs
Goffi <goffi@goffi.org>
parents: 1237
diff changeset
1 #!/usr/bin/env python3
f511f8fbbf8a fixed shebangs
Goffi <goffi@goffi.org>
parents: 1237
diff changeset
2
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia: a Salut à Toi frontend
1396
822bd0139769 date update
Goffi <goffi@goffi.org>
parents: 1239
diff changeset
4 # Copyright (C) 2011-2021 Jérôme Poisson <goffi@goffi.org>
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
19
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
20 import json
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
21 from typing import Optional
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
22
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
23 from autobahn.twisted import websocket
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
24 from autobahn.twisted import resource as resource
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
25 from autobahn.websocket import types
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
26 from sat.core import exceptions
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from sat.core.i18n import _
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from sat.core.log import getLogger
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
29
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
30 from . import session_iface
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
31 from .constants import Const as C
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
32
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 log = getLogger(__name__)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
35 host = None
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
36
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
37
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 class LiberviaPageWSProtocol(websocket.WebSocketServerProtocol):
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
39
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
40 def __init__(self):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
41 super().__init__()
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
42 self._init_ok: bool = False
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
43 self.__profile: Optional[str] = None
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
44 self.__session: Optional[session_iface.SATSession] = None
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
45
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
46 @property
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
47 def init_ok(self):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
48 return self._init_ok
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
49
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
50 def send(self, data_type: str, data: dict) -> None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
51 """Send data to frontend"""
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
52 if not self._init_ok and data_type != "error":
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
53 raise exceptions.InternalError(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
54 "send called when not initialized, this should not happend! Please use "
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
55 "SATSession.send which takes care of sending correctly the data to all "
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
56 "sessions."
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
57 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
58
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
59 data_root = {
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
60 "type": data_type,
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
61 "data": data
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
62 }
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
63 self.sendMessage(json.dumps(data_root, ensure_ascii=False).encode())
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
64
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
65 def close(self) -> None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
66 log.debug(f"closing websocket for profile {self.__profile}")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
67
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
68 def error(self, error_type: str, msg: str) -> None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
69 """Send an error message to frontend and log it locally"""
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
70 log.warning(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
71 f"websocket error {error_type}: {msg}"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
72 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
73 self.send("error", {
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
74 "type": error_type,
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
75 "msg": msg,
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
76 })
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 def onConnect(self, request):
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
79 if "libervia-page" not in request.protocols:
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
80 raise types.ConnectionDeny(
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
81 types.ConnectionDeny.NOT_IMPLEMENTED, "No supported protocol"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
82 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
83 self._init_ok = False
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
84 cookies = {}
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
85 for cookie in request.headers.get("cookie", "").split(";"):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
86 k, __, v = cookie.partition("=")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
87 cookies[k.strip()] = v.strip()
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
88 session_uid = (
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
89 cookies.get("TWISTED_SECURE_SESSION")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
90 or cookies.get("TWISTED_SESSION")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
91 or ""
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
92 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
93 if not session_uid:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
94 raise types.ConnectionDeny(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
95 types.ConnectionDeny.FORBIDDEN, "No session set"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
96 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
97 try:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
98 session = host.site.getSession(session_uid.encode())
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
99 except KeyError:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
100 raise types.ConnectionDeny(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
101 types.ConnectionDeny.FORBIDDEN, "Invalid session"
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
102 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
103
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
104 session.touch()
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
105 session_data = session.getComponent(session_iface.ISATSession)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
106 if session_data.ws_socket is not None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
107 log.warning("Session socket is already set, force closing it")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
108 session_data.ws_socket.send(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
109 "force_close", {"reason": "duplicate connection detected"}
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
110 )
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
111 session_data.ws_socket = self
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
112 self.__session = session_data
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
113 self.__profile = session_data.profile or C.SERVICE_PROFILE
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
114 log.debug(f"websocket connection connected for profile {self.__profile}")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
115 return "libervia-page"
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 def onOpen(self):
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
118 log.debug("websocket connection opened")
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
120 def onMessage(self, payload: bytes, isBinary: bool) -> None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
121 if self.__session is None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
122 raise exceptions.InternalError("empty session, this should never happen")
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 try:
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
124 data_full = json.loads(payload.decode())
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
125 data_type = data_full["type"]
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
126 data = data_full["data"]
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 except ValueError as e:
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
128 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
129 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
130 f"Not valid JSON, ignoring data ({e}): {payload!r}"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
131 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
132 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
133 except KeyError:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
134 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
135 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
136 'Invalid request (missing "type" or "data")'
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
137 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 return
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
139
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
140 if data_type == "init":
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
141 if self._init_ok:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
142 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
143 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
144 "double init"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
145 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
146 self.sendClose(4400, "Bad Request")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
147 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
148
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
149 try:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
150 profile = data["profile"] or C.SERVICE_PROFILE
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
151 token = data["token"]
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
152 except KeyError:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
153 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
154 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
155 "Invalid init data (missing profile or token)"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
156 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
157 self.sendClose(4400, "Bad Request")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
158 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
159 if ((
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
160 profile != self.__profile
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
161 or (token != self.__session.ws_token and profile != C.SERVICE_PROFILE)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
162 )):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
163 log.debug(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
164 f"profile got {profile}, was expecting {self.__profile}, "
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
165 f"token got {token}, was expecting {self.__session.ws_token}, "
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
166 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
167 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
168 "Unauthorized",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
169 "Invalid profile or token"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
170 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
171 self.sendClose(4401, "Unauthorized")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
172 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
173 else:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
174 log.debug(f"websocket connection initialized for {profile}")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
175 self._init_ok = True
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
176 # we now send all cached data, if any
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
177 while True:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
178 try:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
179 session_kw = self.__session.ws_buffer.popleft()
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
180 except IndexError:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
181 break
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
182 else:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
183 self.send(**session_kw)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
184
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
185 if not self._init_ok:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
186 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
187 "Unauthorized",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
188 "session not authorized"
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
189 )
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
190 self.sendClose(4401, "Unauthorized")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
191 return
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
192
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 def onClose(self, wasClean, code, reason):
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
194 log.debug(f"closing websocket (profile: {self.__profile}, reason: {reason})")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
195 if self.__profile is None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
196 log.error("self.__profile should not be None")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
197 self.__profile = C.SERVICE_PROFILE
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
198
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
199 if self.__session is None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
200 log.warning("closing a socket without attached session")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
201 elif self.__session.ws_socket != self:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
202 log.error("session socket is not linked to our instance")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
203 else:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
204 log.debug(f"reseting websocket session for {self.__profile}")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
205 self.__session.ws_socket = None
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
206 sessions = session_iface.SATSession.get_profile_sessions(self.__profile)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
207 log.debug(f"websocket connection for profile {self.__profile} closed")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
208 self.__profile = None
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
209
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
210 @classmethod
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
211 def getBaseURL(cls, secure):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
212 return "ws{sec}://localhost:{port}".format(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
213 sec="s" if secure else "",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
214 port=host.options["port_https" if secure else "port"],
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
215 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
216
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 @classmethod
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
218 def getResource(cls, secure):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
219 factory = websocket.WebSocketServerFactory(cls.getBaseURL(secure))
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 factory.protocol = cls
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 return resource.WebSocketResource(factory)