annotate libervia/web/server/proxy.py @ 1609:f3305832f3f6

server (resources): handle external Libervia apps by adding them to menu without using a Proxy: When an external Libervia app is used, a link is added to the menu, and clicking on it will open the app in an blank page instead of embedding it with a Proxy.
author Goffi <goffi@goffi.org>
date Fri, 31 May 2024 11:10:04 +0200
parents eb00d593801d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1360
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia: a Salut à Toi frontend
1396
822bd0139769 date update
Goffi <goffi@goffi.org>
parents: 1360
diff changeset
4 # Copyright (C) 2011-2021 Jérôme Poisson <goffi@goffi.org>
1360
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 from twisted.web import proxy
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 from twisted.python.compat import urlquote
1435
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
20 from twisted.internet import address
1518
eb00d593801d refactoring: rename `libervia` to `libervia.web` + update imports following backend changes
Goffi <goffi@goffi.org>
parents: 1454
diff changeset
21 from libervia.backend.core.log import getLogger
eb00d593801d refactoring: rename `libervia` to `libervia.web` + update imports following backend changes
Goffi <goffi@goffi.org>
parents: 1454
diff changeset
22 from libervia.web.server.constants import Const as C
1360
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
23
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 log = getLogger(__name__)
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
25
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
26
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
27
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 class SatProxyClient(proxy.ProxyClient):
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
29
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 def handleHeader(self, key, value):
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 if key.lower() == b"x-frame-options":
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 value = b"sameorigin"
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 elif key.lower() == b"content-security-policy":
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 value = value.replace(b"frame-ancestors 'none'", b"frame-ancestors 'self'")
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
35
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 super().handleHeader(key, value)
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 class SatProxyClientFactory(proxy.ProxyClientFactory):
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 protocol = SatProxyClient
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
42
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 class SatReverseProxyResource(proxy.ReverseProxyResource):
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 """Resource Proxy rewritting headers to allow embedding in iframe on same domain"""
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 proxyClientFactoryClass = SatProxyClientFactory
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
46
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 def getChild(self, path, request):
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 return SatReverseProxyResource(
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 self.host, self.port,
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 self.path + b'/' + urlquote(path, safe=b"").encode('utf-8'),
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 self.reactor
389a83eefe62 server: SàT applications integration:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 )
1435
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
53
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
54 def render(self, request):
1454
fc91b78b71db server: handle "proxy" scheme in configuration
Goffi <goffi@goffi.org>
parents: 1435
diff changeset
55 # Forwarded and X-Forwarded-xxx headers can be set
fc91b78b71db server: handle "proxy" scheme in configuration
Goffi <goffi@goffi.org>
parents: 1435
diff changeset
56 # if we have behind an other proxy
1435
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
57 if ((not request.getHeader(C.H_FORWARDED)
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
58 and not request.getHeader(C.H_X_FORWARDED_HOST))):
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
59 forwarded_data = []
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
60 addr = request.getClientAddress()
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
61 if ((isinstance(addr, address.IPv4Address)
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
62 or isinstance(addr, address.IPv6Address))):
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
63 request.requestHeaders.setRawHeaders(C.H_X_FORWARDED_FOR, [addr.host])
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
64 forwarded_data.append(f"for={addr.host}")
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
65 host = request.getHeader("host")
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
66 if host is None:
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
67 port = request.getHost().port
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
68 hostname = request.getRequestHostname()
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
69 host = hostname if port in (80, 443) else f"{hostname}:{port}"
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
70 request.requestHeaders.setRawHeaders(C.H_X_FORWARDED_HOST, [host])
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
71 forwarded_data.append(f"host={host}")
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
72 proto = "https" if request.isSecure() else "http"
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
73 request.requestHeaders.setRawHeaders(C.H_X_FORWARDED_PROTO, [proto])
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
74 forwarded_data.append(f"proto={proto}")
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
75 request.requestHeaders.setRawHeaders(
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
76 C.H_FORWARDED, [";".join(forwarded_data)]
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
77 )
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
78
396d5606477f server (proxy): add "Forwarded" and "X-Forwarded-xxx" headers to reverse proxy
Goffi <goffi@goffi.org>
parents: 1396
diff changeset
79 return super().render(request)