annotate libervia/server/websockets.py @ 1287:1f26d8c2afc1

server: restricted_bridge first draft: bridge with a limited set of methods, where arguments are checked or removed, and security_limit is used. This bridge is used for calls from browser.
author Goffi <goffi@goffi.org>
date Fri, 19 Jun 2020 16:47:51 +0200
parents f511f8fbbf8a
children 822bd0139769
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
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Libervia: a Salut à Toi frontend
1237
987595a254b0 dates update
Goffi <goffi@goffi.org>
parents: 1216
diff changeset
5 # Copyright (C) 2011-2020 Jérôme Poisson <goffi@goffi.org>
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # 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
8 # 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
9 # the Free Software Foundation, either version 3 of the License, or
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # 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
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # 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
18 # 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
19
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
20
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
21 import json
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
22 from twisted.internet import error
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
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 log = getLogger(__name__)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
32 LIBERVIA_PROTOCOL = "libervia_page"
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
35 class WebsocketRequest(object):
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
36 """Wrapper around autobahn's ConnectionRequest and Twisted's server.Request
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
37
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
38 This is used to have a common interface in Libervia page with request object
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
39 """
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
40
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
41 def __init__(self, ws_protocol, connection_request, server_request):
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
42 """
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
43 @param connection_request: websocket request
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
44 @param serveur_request: original request of the page
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
45 """
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
46 self.ws_protocol = ws_protocol
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
47 self.ws_request = connection_request
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
48 if self.isSecure():
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
49 cookie_name = "TWISTED_SECURE_SESSION"
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
50 else:
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
51 cookie_name = "TWISTED_SESSION"
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
52 cookie_value = server_request.getCookie(cookie_name.encode('utf-8'))
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
53 try:
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
54 raw_cookies = ws_protocol.http_headers['cookie']
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
55 except KeyError:
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
56 raise ValueError("missing expected cookie header")
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
57 self.cookies = {k:v for k,v in (c.split('=') for c in raw_cookies.split(';'))}
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
58 if self.cookies[cookie_name] != cookie_value.decode('utf-8'):
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
59 raise exceptions.PermissionError(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
60 "Bad cookie value, this should never happen.\n"
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
61 "headers: {headers}".format(headers=ws_protocol.http_headers))
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
62
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
63 self.template_data = server_request.template_data
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
64 self.data = server_request.data
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
65 self.session = server_request.getSession()
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
66 self._signals_registered = server_request._signals_registered
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
67 self._signals_cache = server_request._signals_cache
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
68 # signal id is needed to link original request with signal handler
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
69 self.signal_id = server_request._signal_id
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
70
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
71 def isSecure(self):
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
72 return self.ws_protocol.factory.isSecure
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
73
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
74 def getSession(self, sessionInterface=None):
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
75 try:
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
76 self.session.touch()
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
77 except (error.AlreadyCalled, error.AlreadyCancelled):
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
78 # Session has already expired.
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
79 self.session = None
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
80
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
81 if sessionInterface:
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
82 return self.session.getComponent(sessionInterface)
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
83
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
84 return self.session
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
85
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
86 def sendData(self, type_, **data):
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
87 assert "type" not in data
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
88 data["type"] = type_
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
89 self.ws_protocol.sendMessage(json.dumps(data, ensure_ascii=False).encode("utf8"))
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
90
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
91
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 class LiberviaPageWSProtocol(websocket.WebSocketServerProtocol):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 host = None
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 tokens_map = {}
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
95
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 def onConnect(self, request):
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
97 prefix = LIBERVIA_PROTOCOL + "_"
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 for protocol in request.protocols:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 if protocol.startswith(prefix):
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
100 token = protocol[len(prefix) :].strip()
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 if token:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 break
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 else:
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
104 raise types.ConnectionDeny(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
105 types.ConnectionDeny.NOT_IMPLEMENTED, "Can't use this subprotocol"
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
106 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
107
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 if token not in self.tokens_map:
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
109 log.warning(_("Can't activate page socket: unknown token"))
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
110 raise types.ConnectionDeny(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
111 types.ConnectionDeny.FORBIDDEN, "Bad token, please reload page"
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
112 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 self.token = token
1203
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
114 token_map = self.tokens_map.pop(token)
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
115 self.page = token_map["page"]
251eba911d4d server (websockets): fixed websocket handling on HTTPS connections:
Goffi <goffi@goffi.org>
parents: 1144
diff changeset
116 self.request = WebsocketRequest(self, request, token_map["request"])
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 return protocol
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
118
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 def onOpen(self):
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
120 log.debug(
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
121 _(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
122 "Websocket opened for {page} (token: {token})".format(
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
123 page=self.page, token=self.token
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
124 )
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
125 )
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
126 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 self.page.onSocketOpen(self.request)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
128
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 def onMessage(self, payload, isBinary):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 try:
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
131 data_json = json.loads(payload.decode("utf8"))
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 except ValueError as e:
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
133 log.warning(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
134 _("Not valid JSON, ignoring data: {msg}\n{data}").format(
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
135 msg=e, data=payload
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
136 )
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
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
139 #  we request page first, to raise an AttributeError
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 # if it is not set (which should never happen)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 page = self.page
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 try:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 cb = page.on_data
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 except AttributeError:
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
145 log.warning(
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
146 _(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
147 'No "on_data" method set on dynamic page, ignoring data:\n{data}'
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
148 ).format(data=data_json)
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
149 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 else:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 cb(page, self.request, data_json)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
152
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 def onClose(self, wasClean, code, reason):
1206
d2e2bf14f2e2 server (websocket): don't crash if self.page doesn't exist while onClose is called
Goffi <goffi@goffi.org>
parents: 1203
diff changeset
154 try:
d2e2bf14f2e2 server (websocket): don't crash if self.page doesn't exist while onClose is called
Goffi <goffi@goffi.org>
parents: 1203
diff changeset
155 page = self.page
d2e2bf14f2e2 server (websocket): don't crash if self.page doesn't exist while onClose is called
Goffi <goffi@goffi.org>
parents: 1203
diff changeset
156 except AttributeError:
d2e2bf14f2e2 server (websocket): don't crash if self.page doesn't exist while onClose is called
Goffi <goffi@goffi.org>
parents: 1203
diff changeset
157 log.debug(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
158 "page is not available, the socket was probably not opened cleanly.\n"
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
159 "reason: {reason}".format(reason=reason))
1206
d2e2bf14f2e2 server (websocket): don't crash if self.page doesn't exist while onClose is called
Goffi <goffi@goffi.org>
parents: 1203
diff changeset
160 return
d2e2bf14f2e2 server (websocket): don't crash if self.page doesn't exist while onClose is called
Goffi <goffi@goffi.org>
parents: 1203
diff changeset
161 page.onSocketClose(self.request)
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
162
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
163 log.debug(
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
164 _(
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
165 "Websocket closed for {page} (token: {token}). {reason}".format(
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
166 page=self.page,
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
167 token=self.token,
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
168 reason=""
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
169 if wasClean
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
170 else _("Reason: {reason}").format(reason=reason),
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
171 )
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
172 )
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
173 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
174
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 @classmethod
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 def getBaseURL(cls, host, secure):
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
177 return "ws{sec}://localhost:{port}".format(
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
178 sec="s" if secure else "",
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
179 port=cls.host.options["port_https" if secure else "port"],
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
180 )
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
181
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 @classmethod
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 def getResource(cls, host, secure):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 if cls.host is None:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 cls.host = host
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 factory = websocket.WebSocketServerFactory(cls.getBaseURL(host, secure))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 factory.protocol = cls
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 return resource.WebSocketResource(factory)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
189
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 @classmethod
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 def registerToken(cls, token, page, request):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 if token in cls.tokens_map:
1216
b2d067339de3 python 3 port:
Goffi <goffi@goffi.org>
parents: 1206
diff changeset
193 raise exceptions.ConflictError(_("This token is already registered"))
1113
cdd389ef97bc server: code style reformatting using black
Goffi <goffi@goffi.org>
parents: 1054
diff changeset
194 cls.tokens_map[token] = {"page": page, "request": request}