annotate libervia/web/server/websockets.py @ 1532:106945841fbc

_browser (album): moved code to upload file to a separate `file_uploader` module: this way, uploading logic can be re-used elsewhere.
author Goffi <goffi@goffi.org>
date Thu, 22 Jun 2023 16:36:01 +0200
parents eb00d593801d
children
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
1518
eb00d593801d refactoring: rename `libervia` to `libervia.web` + update imports following backend changes
Goffi <goffi@goffi.org>
parents: 1513
diff changeset
26 from libervia.backend.core import exceptions
eb00d593801d refactoring: rename `libervia` to `libervia.web` + update imports following backend changes
Goffi <goffi@goffi.org>
parents: 1513
diff changeset
27 from libervia.backend.core.i18n import _
eb00d593801d refactoring: rename `libervia` to `libervia.web` + update imports following backend changes
Goffi <goffi@goffi.org>
parents: 1513
diff changeset
28 from libervia.backend.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
1506
ce879da7fcf7 server: fix `on_signal` callback
Goffi <goffi@goffi.org>
parents: 1504
diff changeset
44 self.__session: Optional[session_iface.WebSession] = None
1504
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 "
1506
ce879da7fcf7 server: fix `on_signal` callback
Goffi <goffi@goffi.org>
parents: 1504
diff changeset
55 "WebSession.send which takes care of sending correctly the data to all "
1504
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()
1506
ce879da7fcf7 server: fix `on_signal` callback
Goffi <goffi@goffi.org>
parents: 1504
diff changeset
105 session_data = session.getComponent(session_iface.IWebSession)
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
106 if session_data.ws_socket is not None:
1513
ff95501abe74 server (websocket): don't crash when a force-close is failing
Goffi <goffi@goffi.org>
parents: 1509
diff changeset
107 log.warning(f"Session socket is already set {session_data.ws_socket=} {self=}], force closing it")
ff95501abe74 server (websocket): don't crash when a force-close is failing
Goffi <goffi@goffi.org>
parents: 1509
diff changeset
108 try:
ff95501abe74 server (websocket): don't crash when a force-close is failing
Goffi <goffi@goffi.org>
parents: 1509
diff changeset
109 session_data.ws_socket.send(
ff95501abe74 server (websocket): don't crash when a force-close is failing
Goffi <goffi@goffi.org>
parents: 1509
diff changeset
110 "force_close", {"reason": "duplicate connection detected"}
ff95501abe74 server (websocket): don't crash when a force-close is failing
Goffi <goffi@goffi.org>
parents: 1509
diff changeset
111 )
ff95501abe74 server (websocket): don't crash when a force-close is failing
Goffi <goffi@goffi.org>
parents: 1509
diff changeset
112 except Exception as e:
ff95501abe74 server (websocket): don't crash when a force-close is failing
Goffi <goffi@goffi.org>
parents: 1509
diff changeset
113 log.warning(f"Can't force close old connection: {e}")
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
114 session_data.ws_socket = self
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
115 self.__session = session_data
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
116 self.__profile = session_data.profile or C.SERVICE_PROFILE
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
117 log.debug(f"websocket connection connected for profile {self.__profile}")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
118 return "libervia-page"
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119
1509
106bae41f5c8 massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents: 1506
diff changeset
120 def on_open(self):
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
121 log.debug("websocket connection opened")
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
122
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
123 def onMessage(self, payload: bytes, isBinary: bool) -> None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
124 if self.__session is None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
125 raise exceptions.InternalError("empty session, this should never happen")
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 try:
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
127 data_full = json.loads(payload.decode())
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
128 data_type = data_full["type"]
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
129 data = data_full["data"]
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 except ValueError as e:
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
131 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
132 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
133 f"Not valid JSON, ignoring data ({e}): {payload!r}"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
134 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
135 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
136 except KeyError:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
137 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
138 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
139 'Invalid request (missing "type" or "data")'
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
140 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 return
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
142
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
143 if data_type == "init":
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
144 if self._init_ok:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
145 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
146 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
147 "double init"
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 self.sendClose(4400, "Bad Request")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
150 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
151
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
152 try:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
153 profile = data["profile"] or C.SERVICE_PROFILE
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
154 token = data["token"]
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
155 except KeyError:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
156 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
157 "bad_request",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
158 "Invalid init data (missing profile or token)"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
159 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
160 self.sendClose(4400, "Bad Request")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
161 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
162 if ((
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
163 profile != self.__profile
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
164 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
165 )):
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
166 log.debug(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
167 f"profile got {profile}, was expecting {self.__profile}, "
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
168 f"token got {token}, was expecting {self.__session.ws_token}, "
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
169 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
170 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
171 "Unauthorized",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
172 "Invalid profile or token"
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
173 )
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
174 self.sendClose(4401, "Unauthorized")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
175 return
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
176 else:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
177 log.debug(f"websocket connection initialized for {profile}")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
178 self._init_ok = True
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
179 # we now send all cached data, if any
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
180 while True:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
181 try:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
182 session_kw = self.__session.ws_buffer.popleft()
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
183 except IndexError:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
184 break
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
185 else:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
186 self.send(**session_kw)
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
187
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
188 if not self._init_ok:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
189 self.error(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
190 "Unauthorized",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
191 "session not authorized"
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
192 )
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
193 self.sendClose(4401, "Unauthorized")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
194 return
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
195
1509
106bae41f5c8 massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents: 1506
diff changeset
196 def on_close(self, wasClean, code, reason):
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
197 log.debug(f"closing websocket (profile: {self.__profile}, reason: {reason})")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
198 if self.__profile is None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
199 log.error("self.__profile should not be None")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
200 self.__profile = C.SERVICE_PROFILE
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
201
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
202 if self.__session is None:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
203 log.warning("closing a socket without attached session")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
204 elif self.__session.ws_socket != self:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
205 log.error("session socket is not linked to our instance")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
206 else:
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
207 log.debug(f"reseting websocket session for {self.__profile}")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
208 self.__session.ws_socket = None
1506
ce879da7fcf7 server: fix `on_signal` callback
Goffi <goffi@goffi.org>
parents: 1504
diff changeset
209 sessions = session_iface.WebSession.get_profile_sessions(self.__profile)
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
210 log.debug(f"websocket connection for profile {self.__profile} closed")
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
211 self.__profile = None
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
212
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
213 @classmethod
1509
106bae41f5c8 massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents: 1506
diff changeset
214 def get_base_url(cls, secure):
1504
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
215 return "ws{sec}://localhost:{port}".format(
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
216 sec="s" if secure else "",
409d10211b20 server, browser: dynamic pages refactoring:
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
217 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
218 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
219
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 @classmethod
1509
106bae41f5c8 massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents: 1506
diff changeset
221 def get_resource(cls, secure):
106bae41f5c8 massive refactoring from camelCase -> snake_case. See backend commit log for more details
Goffi <goffi@goffi.org>
parents: 1506
diff changeset
222 factory = websocket.WebSocketServerFactory(cls.get_base_url(secure))
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 factory.protocol = cls
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 return resource.WebSocketResource(factory)