Example #1
0
 def getChild(self, path, request):
     path = path.decode()
     log.debug("%s - %s" % (request.client.host, path))
     resource = path.split('/')[0].encode()
     path = '/'.join(path.split('/')[1:])
     host = '127.0.0.1'
     x_forwarded_for = request.client.host
     x_for_host = request.requestHeaders.getRawHeaders('host')
     x_for_host = x_for_host[0].split(':')[0]
     x_for_port = request.host.port
     if x_for_port == args.SSL_PORT:
         x_for_proto = "https"
     else:
         x_for_proto = "http"
     for header in [
         ('X-Forwarded-For', x_forwarded_for),
         ('X-Forwarded-Host', x_for_host),
         ('X-Forwarded-Port', str(x_for_port)),
         ('X-Forwarded-Proto', x_for_proto),
     ]:
         request.requestHeaders.addRawHeader(*header)
     path = path.encode()
     if resource.startswith(b"webdav"):
         new_path = b'/%s' % (resource, )
         if path:
             new_path += b'/%s' % path
         log.debug("Forwarding request to WebDAV server: %s" %
                   path.decode())
         return ReverseProxyResource(host, args.WEBDAV_PORT, new_path)
     else:
         log.debug("Forwarding request to Flask server")
         new_path = b'/%s' % (resource, )
         if path:
             new_path += b'/%s' % path
         return ReverseProxyResource(host, args.FLASK_PORT, new_path)
Example #2
0
 def test_getChildWithSpecial(self):
     """
     The L{ReverseProxyResource} return by C{getChild} has a path which has
     already been quoted.
     """
     resource = ReverseProxyResource("127.0.0.1", 1234, "/path")
     child = resource.getChild(" /%", None)
     self.assertEqual(child.path, "/path/%20%2F%25")
 def test_getChildWithSpecial(self):
     """
     The L{ReverseProxyResource} return by C{getChild} has a path which has
     already been quoted.
     """
     resource = ReverseProxyResource("127.0.0.1", 1234, b"/path")
     child = resource.getChild(b" /%", None)
     self.assertEqual(child.path, b"/path/%20%2F%25")
Example #4
0
 def __init__(self,
              host,
              port,
              path,
              forwarded_port=None,
              forwarded_proto=None):
     # host:port/path => target server
     self._forwarded_port = forwarded_port
     self._forwarded_proto = forwarded_proto
     ReverseProxyResource.__init__(self, host, port, path)
Example #5
0
 def test_getChild(self):
     """
     The L{ReverseProxyResource.getChild} method should return a resource
     instance with the same class as the originating resource, forward port
     and host values, and update the path value with the value passed.
     """
     resource = ReverseProxyResource("127.0.0.1", 1234, "/path")
     child = resource.getChild('foo', None)
     # The child should keep the same class
     self.assertIsInstance(child, ReverseProxyResource)
     self.assertEquals(child.path, "/path/foo")
     self.assertEquals(child.port, 1234)
     self.assertEquals(child.host, "127.0.0.1")
Example #6
0
 def test_getChild(self):
     """
     The L{ReverseProxyResource.getChild} method should return a resource
     instance with the same class as the originating resource, forward port
     and host values, and update the path value with the value passed.
     """
     resource = ReverseProxyResource("127.0.0.1", 1234, "/path")
     child = resource.getChild("foo", None)
     # The child should keep the same class
     self.assertIsInstance(child, ReverseProxyResource)
     self.assertEquals(child.path, "/path/foo")
     self.assertEquals(child.port, 1234)
     self.assertEquals(child.host, "127.0.0.1")
Example #7
0
 def __init__(self, server_pool, config=None, reactor=reactor):
     ReverseProxyResource.__init__(self,
                                   host="",
                                   port=80,
                                   path="",
                                   reactor=reactor)
     self.isLeaf = True
     self.server_pool = server_pool
     if config is None:
         config = DEFAULT_CONFIG
     else:
         aux = DEFAULT_CONFIG.copy()
         aux.update(config)
         config = aux
     self.config = config
def start_server(port, destport):
    revproxy = ReverseProxyResource("127.0.0.1", destport, "/blobs")
    resource = Resource()
    resource.putChild("", DummyResource())
    resource.putChild("blobs", revproxy)
    site = Site(resource)
    reactor.listenTCP(port, site)
Example #9
0
    def _testRender(self, uri, expectedURI):
        """
        Check that a request pointing at C{uri} produce a new proxy connection,
        with the path of this request pointing at C{expectedURI}.
        """
        root = Resource()
        reactor = FakeReactor()
        resource = ReverseProxyResource("127.0.0.1", 1234, "/path", reactor)
        root.putChild('index', resource)
        site = Site(root)

        transport = StringTransportWithDisconnection()
        channel = site.buildProtocol(None)
        channel.makeConnection(transport)
        # Clear the timeout if the tests failed
        self.addCleanup(channel.connectionLost, None)

        channel.dataReceived("GET %s HTTP/1.1\r\nAccept: text/html\r\n\r\n" %
                             (uri, ))

        # Check that one connection has been created, to the good host/port
        self.assertEquals(len(reactor.connect), 1)
        self.assertEquals(reactor.connect[0][0], "127.0.0.1")
        self.assertEquals(reactor.connect[0][1], 1234)

        # Check the factory passed to the connect, and its given path
        factory = reactor.connect[0][2]
        self.assertIsInstance(factory, ProxyClientFactory)
        self.assertEquals(factory.rest, expectedURI)
        self.assertEquals(factory.headers["host"], "127.0.0.1:1234")
    def _testRender(self, uri, expectedURI):
        """
        Check that a request pointing at C{uri} produce a new proxy connection,
        with the path of this request pointing at C{expectedURI}.
        """
        root = Resource()
        reactor = MemoryReactor()
        resource = ReverseProxyResource("127.0.0.1", 1234, b"/path", reactor)
        root.putChild(b"index", resource)
        site = Site(root)

        transport = StringTransportWithDisconnection()
        channel = site.buildProtocol(None)
        channel.makeConnection(transport)
        # Clear the timeout if the tests failed
        self.addCleanup(channel.connectionLost, None)

        channel.dataReceived(b"GET " + uri +
                             b" HTTP/1.1\r\nAccept: text/html\r\n\r\n")

        [(host, port, factory, _timeout, _bind_addr)] = reactor.tcpClients
        # Check that one connection has been created, to the good host/port
        self.assertEqual(host, "127.0.0.1")
        self.assertEqual(port, 1234)

        # Check the factory passed to the connect, and its given path
        self.assertIsInstance(factory, ProxyClientFactory)
        self.assertEqual(factory.rest, expectedURI)
        self.assertEqual(factory.headers[b"host"], b"127.0.0.1:1234")
 def test_getChild(self):
     """
     The L{ReverseProxyResource.getChild} method should return a resource
     instance with the same class as the originating resource, forward
     port, host, and reactor values, and update the path value with the
     value passed.
     """
     reactor = MemoryReactor()
     resource = ReverseProxyResource("127.0.0.1", 1234, b"/path", reactor)
     child = resource.getChild(b"foo", None)
     # The child should keep the same class
     self.assertIsInstance(child, ReverseProxyResource)
     self.assertEqual(child.path, b"/path/foo")
     self.assertEqual(child.port, 1234)
     self.assertEqual(child.host, "127.0.0.1")
     self.assertIdentical(child.reactor, resource.reactor)
Example #12
0
 def test_getChild(self):
     """
     The L{ReverseProxyResource.getChild} method should return a resource
     instance with the same class as the originating resource, forward
     port, host, and reactor values, and update the path value with the
     value passed.
     """
     reactor = MemoryReactor()
     resource = ReverseProxyResource("127.0.0.1", 1234, "/path", reactor)
     child = resource.getChild('foo', None)
     # The child should keep the same class
     self.assertIsInstance(child, ReverseProxyResource)
     self.assertEqual(child.path, "/path/foo")
     self.assertEqual(child.port, 1234)
     self.assertEqual(child.host, "127.0.0.1")
     self.assertIdentical(child.reactor, resource.reactor)
Example #13
0
 def __init__(self, *arg, **kwarg):
    log.debug("WebProxy called")
    try:
       if 'remove' in kwarg.keys():
          self.remove=int(kwarg['remove'])
          del kwarg['remove']
    except:
       log.debug("error in remove")
    return ReverseProxyResource.__init__(self, *arg, **kwarg)
Example #14
0
    def create(transport, path, config):
        personality = transport.worker.personality
        personality.WEB_SERVICE_CHECKERS['reverseproxy'](personality, config)

        host = config['host']
        port = int(config.get('port', 80))

        resource = ReverseProxyResource(host, port, path)

        return RouterWebServiceReverseWeb(transport, path, config, resource)
Example #15
0
 def as_resource(self):
     # TODO there's a delay before gunicorn actually finishes starting; Do
     # Something in the meantime?
     if self.runner is not None and self.runner.failure_count > 0:
         return _app_failing
     elif self.runner_port is None:
         return _app_down
     else:
         self.log_request()
         return ReverseProxyResource('localhost', self.runner_port,
                                     self.mount_url)
Example #16
0
    def __init__(self,
                 host,
                 path,
                 port=80,
                 cache=None,
                 pool_maxsize=4,
                 downloader=None,
                 filter_fun=None,
                 reactor=reactor):
        path = path[:-1] if path.endswith('/') else path
        paths = path.split('/')

        root_path = paths[0]
        ReverseProxyResource.__init__(self, host, port, root_path, reactor)
        self._sub_paths = paths[1:]

        self._downloader = downloader \
            or IllustrationDownloader(host=host, pool_maxsize=pool_maxsize)

        self._cache = cache
        self._filter = filter_fun
Example #17
0
    def getChild(self, path, request):
        token = request.getCookie('token')

        if token is None:
            self._setToken(request)

        if path == 'api':
            return APIResource()
        elif path == 'ws':
            return self._ws.getResource(request)
        else:
            return ReverseProxyResource('127.0.0.1', 8080,
                                        os.path.join('/', path))

        if not path:
            return File(os.path.join(self._static_path, 'index.html'))

        return self
Example #18
0
 def __init__(self, port):
     ReverseProxyResource.__init__(self, 'localhost', port, b'')
Example #19
0
 def __init__(self, host, port, path, module_registry, reactor=reactor):
     self.module_registry = module_registry
     ReverseProxyResource.__init__(self, host, port, path, reactor)
Example #20
0
        file = open(settings['logfile'], "wa")
        log.startLogging(file, setStdout=False)
    else:
        log.startLogging(sys.stdout, setStdout=False)

    if settings.has_key('starturl'):
        log.msg('Open', settings['starturl'])
    if settings.has_key('jsonconfigfile'):
        file = open(settings['jsonconfigfile'], 'w')
        import json
        json.dump(settings, file)
    log.msg(os.getcwd())
    log.msg(settings['rootdir'])
    root = CacheFile(settings['rootdir'])
    from twisted.web.proxy import ReverseProxyResource
    proxy = ReverseProxyResource('windpowerhub.com', 80, '/~albatros/php')
    root.putChild("php", proxy)

    #phproot = static.File('src/com/kk_electronic/public/clsrv/')
    #phproot.processors = {
    #                      '.php':PHP5Script
    #                      }
    #root.putChild("messagebox", MessageBoxRoot())
    root.putChild("websocket", WebSocketRoot())
    #root.putChild("clsrv", phproot)
    site = server.Site(root)
    reactor.listenTCP(settings.as_int('port'), site)  #@UndefinedVariable
    reactor.run()  #@UndefinedVariable


if __name__ == "__main__":
Example #21
0
    def _create_resource(self, path_config, nested=True):
        """
        Creates child resource to be added to the parent.

        :param path_config: Configuration for the new child resource.
        :type path_config: dict

        :returns: Resource -- the new child resource
        """
        # WAMP-WebSocket resource
        #
        if path_config['type'] == 'websocket':

            ws_factory = WampWebSocketServerFactory(self._router_session_factory, self.config.extra.cbdir, path_config, self._templates)

            # FIXME: Site.start/stopFactory should start/stop factories wrapped as Resources
            ws_factory.startFactory()

            return WebSocketResource(ws_factory)

        # Static file hierarchy resource
        #
        elif path_config['type'] == 'static':

            static_options = path_config.get('options', {})

            if 'directory' in path_config:

                static_dir = os.path.abspath(os.path.join(self.config.extra.cbdir, path_config['directory']))

            elif 'package' in path_config:

                if 'resource' not in path_config:
                    raise ApplicationError(u"crossbar.error.invalid_configuration", "missing resource")

                try:
                    mod = importlib.import_module(path_config['package'])
                except ImportError as e:
                    emsg = "Could not import resource {} from package {}: {}".format(path_config['resource'], path_config['package'], e)
                    self.log.error(emsg)
                    raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)
                else:
                    try:
                        static_dir = os.path.abspath(pkg_resources.resource_filename(path_config['package'], path_config['resource']))
                    except Exception as e:
                        emsg = "Could not import resource {} from package {}: {}".format(path_config['resource'], path_config['package'], e)
                        self.log.error(emsg)
                        raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)

            else:

                raise ApplicationError(u"crossbar.error.invalid_configuration", "missing web spec")

            static_dir = static_dir.encode('ascii', 'ignore')  # http://stackoverflow.com/a/20433918/884770

            # create resource for file system hierarchy
            #
            if static_options.get('enable_directory_listing', False):
                static_resource_class = StaticResource
            else:
                static_resource_class = StaticResourceNoListing

            cache_timeout = static_options.get('cache_timeout', DEFAULT_CACHE_TIMEOUT)
            allow_cross_origin = static_options.get('allow_cross_origin', True)

            static_resource = static_resource_class(static_dir, cache_timeout=cache_timeout, allow_cross_origin=allow_cross_origin)

            # set extra MIME types
            #
            static_resource.contentTypes.update(EXTRA_MIME_TYPES)
            if 'mime_types' in static_options:
                static_resource.contentTypes.update(static_options['mime_types'])
            patchFileContentTypes(static_resource)

            # render 404 page on any concrete path not found
            #
            static_resource.childNotFound = Resource404(self._templates, static_dir)

            return static_resource

        # WSGI resource
        #
        elif path_config['type'] == 'wsgi':

            if not _HAS_WSGI:
                raise ApplicationError(u"crossbar.error.invalid_configuration", "WSGI unsupported")

            if 'module' not in path_config:
                raise ApplicationError(u"crossbar.error.invalid_configuration", "missing WSGI app module")

            if 'object' not in path_config:
                raise ApplicationError(u"crossbar.error.invalid_configuration", "missing WSGI app object")

            # import WSGI app module and object
            mod_name = path_config['module']
            try:
                mod = importlib.import_module(mod_name)
            except ImportError as e:
                raise ApplicationError(u"crossbar.error.invalid_configuration", "WSGI app module '{}' import failed: {} - Python search path was {}".format(mod_name, e, sys.path))
            else:
                obj_name = path_config['object']
                if obj_name not in mod.__dict__:
                    raise ApplicationError(u"crossbar.error.invalid_configuration", "WSGI app object '{}' not in module '{}'".format(obj_name, mod_name))
                else:
                    app = getattr(mod, obj_name)

            # Create a threadpool for running the WSGI requests in
            pool = ThreadPool(maxthreads=path_config.get("maxthreads", 20),
                              minthreads=path_config.get("minthreads", 0),
                              name="crossbar_wsgi_threadpool")
            self._reactor.addSystemEventTrigger('before', 'shutdown', pool.stop)
            pool.start()

            # Create a Twisted Web WSGI resource from the user's WSGI application object
            try:
                wsgi_resource = WSGIResource(self._reactor, pool, app)

                if not nested:
                    wsgi_resource = WSGIRootResource(wsgi_resource, {})
            except Exception as e:
                raise ApplicationError(u"crossbar.error.invalid_configuration", "could not instantiate WSGI resource: {}".format(e))
            else:
                return wsgi_resource

        # Redirecting resource
        #
        elif path_config['type'] == 'redirect':
            redirect_url = path_config['url'].encode('ascii', 'ignore')
            return RedirectResource(redirect_url)

        # Node info resource
        #
        elif path_config['type'] == 'nodeinfo':
            return NodeInfoResource(self._templates, self)

        # Reverse proxy resource
        #
        elif path_config['type'] == 'reverseproxy':

            # Import late because t.w.proxy imports the reactor
            from twisted.web.proxy import ReverseProxyResource

            host = path_config['host']
            port = int(path_config.get('port', 80))
            path = path_config.get('path', '').encode('ascii', 'ignore')
            return ReverseProxyResource(host, port, path)

        # JSON value resource
        #
        elif path_config['type'] == 'json':
            value = path_config['value']

            return JsonResource(value)

        # CGI script resource
        #
        elif path_config['type'] == 'cgi':

            cgi_processor = path_config['processor']
            cgi_directory = os.path.abspath(os.path.join(self.config.extra.cbdir, path_config['directory']))
            cgi_directory = cgi_directory.encode('ascii', 'ignore')  # http://stackoverflow.com/a/20433918/884770

            return CgiDirectory(cgi_directory, cgi_processor, Resource404(self._templates, cgi_directory))

        # WAMP-Longpoll transport resource
        #
        elif path_config['type'] == 'longpoll':

            path_options = path_config.get('options', {})

            lp_resource = WampLongPollResource(self._router_session_factory,
                                               timeout=path_options.get('request_timeout', 10),
                                               killAfter=path_options.get('session_timeout', 30),
                                               queueLimitBytes=path_options.get('queue_limit_bytes', 128 * 1024),
                                               queueLimitMessages=path_options.get('queue_limit_messages', 100),
                                               debug_transport_id=path_options.get('debug_transport_id', None)
                                               )
            lp_resource._templates = self._templates

            return lp_resource

        # Publisher resource (part of REST-bridge)
        #
        elif path_config['type'] == 'publisher':

            # create a vanilla session: the publisher will use this to inject events
            #
            publisher_session_config = ComponentConfig(realm=path_config['realm'], extra=None)
            publisher_session = ApplicationSession(publisher_session_config)

            # add the publisher session to the router
            #
            self._router_session_factory.add(publisher_session, authrole=path_config.get('role', 'anonymous'))

            # now create the publisher Twisted Web resource
            #
            return PublisherResource(path_config.get('options', {}), publisher_session)

        # Webhook resource (part of REST-bridge)
        #
        elif path_config['type'] == 'webhook':

            # create a vanilla session: the webhook will use this to inject events
            #
            webhook_session_config = ComponentConfig(realm=path_config['realm'], extra=None)
            webhook_session = ApplicationSession(webhook_session_config)

            # add the webhook session to the router
            #
            self._router_session_factory.add(webhook_session, authrole=path_config.get('role', 'anonymous'))

            # now create the webhook Twisted Web resource
            #
            return WebhookResource(path_config.get('options', {}), webhook_session)

        # Caller resource (part of REST-bridge)
        #
        elif path_config['type'] == 'caller':

            # create a vanilla session: the caller will use this to inject calls
            #
            caller_session_config = ComponentConfig(realm=path_config['realm'], extra=None)
            caller_session = ApplicationSession(caller_session_config)

            # add the calling session to the router
            #
            self._router_session_factory.add(caller_session, authrole=path_config.get('role', 'anonymous'))

            # now create the caller Twisted Web resource
            #
            return CallerResource(path_config.get('options', {}), caller_session)

        # File Upload resource
        #
        elif path_config['type'] == 'upload':

            upload_directory = os.path.abspath(os.path.join(self.config.extra.cbdir, path_config['directory']))
            upload_directory = upload_directory.encode('ascii', 'ignore')  # http://stackoverflow.com/a/20433918/884770
            if not os.path.isdir(upload_directory):
                emsg = "configured upload directory '{}' in file upload resource isn't a directory".format(upload_directory)
                self.log.error(emsg)
                raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)

            if 'temp_directory' in path_config:
                temp_directory = os.path.abspath(os.path.join(self.config.extra.cbdir, path_config['temp_directory']))
                temp_directory = temp_directory.encode('ascii', 'ignore')  # http://stackoverflow.com/a/20433918/884770
            else:
                temp_directory = os.path.abspath(tempfile.gettempdir())
                temp_directory = os.path.join(temp_directory, 'crossbar-uploads')
                if not os.path.exists(temp_directory):
                    os.makedirs(temp_directory)

            if not os.path.isdir(temp_directory):
                emsg = "configured temp directory '{}' in file upload resource isn't a directory".format(temp_directory)
                self.log.error(emsg)
                raise ApplicationError(u"crossbar.error.invalid_configuration", emsg)

            # file upload progress and finish events are published via this session
            #
            upload_session_config = ComponentConfig(realm=path_config['realm'], extra=None)
            upload_session = ApplicationSession(upload_session_config)

            self._router_session_factory.add(upload_session, authrole=path_config.get('role', 'anonymous'))

            self.log.info("File upload resource started. Uploads to {upl} using temp folder {tmp}.", upl=upload_directory, tmp=temp_directory)

            return FileUploadResource(upload_directory, temp_directory, path_config['form_fields'], upload_session, path_config.get('options', {}))

        # Generic Twisted Web resource
        #
        elif path_config['type'] == 'resource':

            try:
                klassname = path_config['classname']

                self.log.debug("Starting class '{name}'", name=klassname)

                c = klassname.split('.')
                module_name, klass_name = '.'.join(c[:-1]), c[-1]
                module = importlib.import_module(module_name)
                make = getattr(module, klass_name)

                return make(path_config.get('extra', {}))

            except Exception as e:
                emsg = "Failed to import class '{}' - {}".format(klassname, e)
                self.log.error(emsg)
                self.log.error("PYTHONPATH: {pythonpath}", pythonpath=sys.path)
                raise ApplicationError(u"crossbar.error.class_import_failed", emsg)

        # Schema Docs resource
        #
        elif path_config['type'] == 'schemadoc':

            realm = path_config['realm']

            if realm not in self.realm_to_id:
                raise ApplicationError(u"crossbar.error.no_such_object", "No realm with URI '{}' configured".format(realm))

            realm_id = self.realm_to_id[realm]

            realm_schemas = self.realms[realm_id].session._schemas

            return SchemaDocResource(self._templates, realm, realm_schemas)

        # Nested subpath resource
        #
        elif path_config['type'] == 'path':

            nested_paths = path_config.get('paths', {})

            if '/' in nested_paths:
                nested_resource = self._create_resource(nested_paths['/'])
            else:
                nested_resource = Resource404(self._templates, b'')

            # nest subpaths under the current entry
            #
            self._add_paths(nested_resource, nested_paths)

            return nested_resource

        else:
            raise ApplicationError(u"crossbar.error.invalid_configuration",
                                   "invalid Web path type '{}' in {} config".format(path_config['type'],
                                                                                    'nested' if nested else 'root'))
Example #22
0
 def __init__(self, host, port, path, module_registry, reactor=reactor):
     self.module_registry = module_registry
     ReverseProxyResource.__init__(self, host, port, path, reactor)
Example #23
0
 def __init__(self,*args,**kwargs):
     ReverseProxyResource.__init__(self,*args,**kwargs)