예제 #1
0
    def render_GET(self, request):
        """
        HTTP GET implementation.

        Args:
            request (twisted.web.server.Request): HTTP request object
        Returns:
            HTTP response with headers
        """
        request.setHeader('Access-Control-Allow-Origin',
                          CORS_DEFAULT_ALLOW_ORIGIN)

        data = {
            "_controller": self.__class__.__name__,
            "request_postpath": request.postpath,
            "method": request.method,
            "request_path": request.path,
            "request_header_host": request.getHeader("host"),
            "request_hostname": request.getRequestHostname(),
            "same_same": False,
        }
        fallback_port = "8010"
        try:
            data['whoami_result'] = whoami(request,
                                           fallback_port=fallback_port)
        except Exception as exc:
            data['whoami_result'] = 'FAIL: {!r}'.format(exc)

        try:
            data['mangle_host_header_port'] = mangle_host_header_port(
                request.getHeader("host"), fallback_port=fallback_port)
        except Exception as exc:
            data['mangle_host_header_port'] = 'FAIL: {!r}'.format(exc)

        data['monkey_host'] = new_getRequestHostname(request)

        try:
            a = data['whoami_result']
            b = data['mangle_host_header_port']
            keys = ('port', 'proto')
            data['same_same'] = True
            for key in keys:
                if a[key] != b[key]:
                    data['same_same'] = False
                    break
        except Exception:
            pass
        return json_response(request, data)
    def _reverse_proxy_configuration(self, request):
        """
        Return an example configuration for nginx acting as a reverse proxy
        for the current device.

        Args:
                request (twisted.web.server.Request): HTTP request object
        Returns:
                HTTP response with headers
        """
        mangled = mangle_host_header_port(request.getHeader('host'))
        configuration = {
            "ENIGMA2_HOST": mangled['hostname'],
            "ENIGMA2_PORT": 80,
            "OSCAM_PORT": 83,
            "STREAM_PORT": 8001,
            "STREAM_TRANSCODED_PORT": 8002,
            "PUBLIC_ROOT": '/tmp/public',
            "PICON_ROOT": '/tmp/picon',
        }

        request.setHeader("content-type", "text/plain")
        return gen_reverse_proxy_configuration(configuration)
예제 #3
0
    def render_GET(self, request):
        """
        Request handler for the `file` endpoint.

        Args:
            request (twisted.web.server.Request): HTTP request object
        Returns:
            HTTP response with headers

        .. http:get:: /file

            :query string action: one of `download` [default], `stream`
            :query string name: m3u entry label
            :query string be-lyle: bouquet reference

        """
        action = "download"
        if "action" in request.args:
            action = request.args["action"][0]

        self.log.warning("DEPRECATED file.py access:")
        self.log.warning(pprint.pformat(request.args))

        if "file" in request.args:
            try:
                filename = require_valid_file_parameter(request, "file")
            except ValueError as verr:
                request.setResponseCode(http.BAD_REQUEST)
                self.log.error(verr)
                return ''
            except IOError as ioerr:
                self.log.error(ioerr)
                request.setResponseCode(http.NOT_FOUND)
                return ''

            if not filename.startswith(RECORDINGS_ROOT_PATH):
                if filename not in FILE_ACCESS_WHITELIST:
                    self.log.error("{!r} NOT IN WHITELIST {!r}".format(
                        filename, FILE_ACCESS_WHITELIST))
                    request.setResponseCode(http.FORBIDDEN)
                    return ''

            if action == "stream":
                name = "stream"
                m3u_content = [
                    '#EXTM3U',
                    '#EXTVLCOPT--http-reconnect=true',
                ]

                if "name" in request.args:
                    name = request.args["name"][0]
                    m3u_content.append("#EXTINF:-1,%s" % name)

                mangled = mangle_host_header_port(
                    request.getHeader('host'),
                    fallback_port=comp_config.OpenWebif.port.value)
                args = {"action": "download", "file": filename}
                source_url = build_url(hostname=mangled['hostname'],
                                       path="file",
                                       args=args,
                                       port=mangled["port"])
                m3u_content.append(source_url)
                request.setHeader("Content-Disposition",
                                  'attachment;filename="%s.m3u"' % name)
                request.setHeader("Content-Type", "application/x-mpegurl")
                return "\n".join(m3u_content)
            elif action == "download":
                request.setHeader(
                    "Content-Disposition",
                    "attachment;filename=\"%s\"" % (filename.split('/')[-1]))
                rfile = static.File(filename,
                                    defaultType="application/octet-stream")
                return rfile.render(request)
            else:
                self.log.warning("Unsupported action: {!r}".format(action))
                request.setResponseCode(http.NOT_IMPLEMENTED)
                return ""

        if "dir" in request.args:
            self.log.warning("No 'dir' support.")
            request.setResponseCode(http.NOT_IMPLEMENTED)
            return ""
    def render_GET(self, request):
        """
        HTTP GET implementation.

        Args:
                request (twisted.web.server.Request): HTTP request object
        Returns:
                HTTP response with headers
        """
        rq_path = urlparse.unquote(request.path)

        if not rq_path.startswith(self._resource_prefix):
            raise ValueError("Invalid Request Path {!r}".format(request.path))

        request.setHeader(
            'Access-Control-Allow-Origin', CORS_DEFAULT_ALLOW_ORIGIN)

        # as implemented in BaseController -----------------v
        func_path = rq_path[len(self._resource_prefix) + 1:].replace(".", "")

        if func_path in ("", "index"):
            return self._index(request)

        if func_path == 'reverse_proxy_conf':
            return self._reverse_proxy_configuration(request)

        #: name of OpenWebif method to be called
        owif_func = "{:s}{:s}".format(OWIF_PREFIX, func_path)

        #: callable methods
        funcs = [
            # TODO: add method of *self*
            ('web', getattr(self.web_instance, owif_func, None)),
        ]

        if self.ajax_instance is not None:
            funcs.append(
                ('ajax', getattr(self.ajax_instance, owif_func, None)))

        #: method to be called
        func = None
        #: nickname for controller instance
        source_controller = None

        # query controller instances for given method - first match wins
        for candidate_controller, candidate in funcs:
            if callable(candidate):
                func = candidate
                source_controller = candidate_controller
                break

        if func is None:
            request.setResponseCode(http.NOT_FOUND)
            data = {
                "method": repr(func_path),
                "result": False,
            }

            if self.verbose:
                data["request"] = {
                    "path": request.path,
                    "postpath": request.postpath,
                    "mangled_host_header": mangle_host_header_port(
                        request.getHeader('host')),
                    "host_header": request.getHeader('host')
                }

            return json_response(request, data)

        try:
            request.setResponseCode(http.OK)
            data = func(request)
            data['_controller'] = source_controller
            try:
                if "result" not in data:
                    data["result"] = True
            except Exception:
                # ignoring exceptions is bad.
                pass

            return json_response(data=data, request=request)
        except Exception as exc:
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
            data = {
                "exception": repr(exc),
                "result": False,
                "path": request.path,
            }

            return json_response(request, data)
예제 #5
0
    def render(self, request):
        if self.verbose:
            fmt = "{scheme}://{netloc}{path} " \
                  "accessed by {client}{via} {r_args}"
            args = mangle_host_header_port(request.getHeader('host'))
            args['path'] = request.path
            try:
                args['client'] = request.transport.getPeer()
            except Exception as exc:
                self.log.error(exc)
                args['client'] = request.getClient()
            args['via'] = ''

            header = request.getHeader("X-Forwarded-For")
            if header:
                args['via'] = " ({!r})".format(header.split(",")[-1].strip())

            args['r_args'] = request.args
            self.log.info(fmt.format(**args))
            if self.verbose > 4:
                self.log.debug(request.getAllHeaders())

        # cache data
        path = self.path

        if self.path == "":
            self.path = "index"

        self.path = self.path.replace(".", "")
        owif_callback_name = OWIF_PREFIX + self.path
        func = getattr(self, owif_callback_name, None)

        if self.verbose > 10:
            self.log.info('{!r} {!r}'.format(owif_callback_name, func))

        if callable(func):
            data = func(request)
            if data is None:
                self.log.warning('{!r} {!r} returned None'.format(
                    owif_callback_name, func))
                error404(request)
                return server.NOT_DONE_YET

            if self.content_type:
                request.setHeader("content-type", self.content_type)

            if self.content_type == CONTENT_TYPE_X_MPEGURL:
                request.write(data)
                request.finish()
            elif isinstance(data, str):
                request.setHeader("content-type", CONTENT_TYPE_TEXT)
                request.write(data)
                request.finish()
            else:
                tmpl_trunk = request.path
                template_module_name = self.path

                if tmpl_trunk[-1] == "/":
                    tmpl_trunk += "index"
                elif tmpl_trunk[-5:] != "index" and self.path == "index":
                    tmpl_trunk += "/index"

                tmpl_trunk = tmpl_trunk.strip("/")
                tmpl_trunk = tmpl_trunk.replace(".", "")

                if tmpl_trunk in TEMPLATE_ALIASES:
                    the_alias = TEMPLATE_ALIASES[tmpl_trunk]
                    template_module_name = os.path.basename(the_alias)
                    if self.verbose > 10:
                        self.log.warning("Template alias {!r} -> {!r}".format(
                            tmpl_trunk, the_alias))
                    tmpl_trunk = the_alias

                # out => content
                out = self.loadTemplate(tmpl_trunk, template_module_name, data)
                if out is None:
                    self.log.error(
                        "Template not loadable for {!r} (page {!r})".format(
                            owif_callback_name, request.uri))
                    error404(request)
                else:
                    request.write(out)
                    request.finish()
        else:
            self.log.error("Callback {!r} for page {!r} not found".format(
                owif_callback_name, request.uri))
            error404(request)

        # restore cached data
        self.path = path

        return server.NOT_DONE_YET