view libervia/server/proxy.py @ 1360:389a83eefe62

server: SàT applications integration: - a SàT Application can be added to the menu (if necessary values are exposed), by using the `sat-app:[application_name]` in `menu_json` or `menu_extra_json`. The application will then be started with Libervia, and embedded, i.e. Libervia menu will appear and application will be integrated under it. - the same `sat-app:[application_name]` thing can be used in redirection, in this case the redirection will reverse proxy directly the application, without embedding it (no Libervia menu will appear) - the ReverseProxy will replace headers if necessary to allow embedding in a iframe from the same domain - new `embed_app` page to embed a SàT Application
author Goffi <goffi@goffi.org>
date Mon, 28 Sep 2020 21:12:21 +0200
parents
children 822bd0139769
line wrap: on
line source

#!/usr/bin/env python3

# Libervia: a Salut à Toi frontend
# Copyright (C) 2011-2020 Jérôme Poisson <goffi@goffi.org>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
from twisted.web import proxy
from twisted.python.compat import urlquote
from sat.core.log import getLogger

log = getLogger(__name__)



class SatProxyClient(proxy.ProxyClient):

    def handleHeader(self, key, value):
        if key.lower() == b"x-frame-options":
            value = b"sameorigin"
        elif key.lower() == b"content-security-policy":
            value = value.replace(b"frame-ancestors 'none'", b"frame-ancestors 'self'")

        super().handleHeader(key, value)


class SatProxyClientFactory(proxy.ProxyClientFactory):
    protocol = SatProxyClient


class SatReverseProxyResource(proxy.ReverseProxyResource):
    """Resource Proxy rewritting headers to allow embedding in iframe on same domain"""
    proxyClientFactoryClass = SatProxyClientFactory

    def getChild(self, path, request):
        return SatReverseProxyResource(
            self.host, self.port,
            self.path + b'/' + urlquote(path, safe=b"").encode('utf-8'),
            self.reactor
        )