def default(self, *args, **query): """ This method returns the content of existing files on the file system. Query string might be used for cache busting and are otherwise ignored. """ # Append special header to all responses cherrypy.response.headers["X-Jasy-Version"] = jasy.__version__ # Enable cross domain access to this server enableCrossDomain() # When it's a file name in the local folder... load it if args: path = os.path.join(*args) else: path = "index.html" path = os.path.join(self.root, path) # Check for existance first if os.path.isfile(path): if self.enableDebug: info("Serving file: %s", path) return serveFile(os.path.abspath(path)) # Otherwise return a classic 404 else: if self.enableDebug: info("File not found: %s", path) raise cherrypy.NotFound(path)
def __init__(self, id, config): self.id = id self.config = config self.root = getKey(config, "root", ".") self.enableDebug = getKey(config, "debug", False) info('Static "%s" => "%s" [debug:%s]', self.id, self.root, self.enableDebug)
def __init__(self, id, config): self.id = id self.config = config self.host = getKey(config, "host") self.auth = getKey(config, "auth") self.enableDebug = getKey(config, "debug", False) self.enableMirror = getKey(config, "mirror", False) self.enableOffline = getKey(config, "offline", False) if self.enableMirror: self.mirror = Cache(os.getcwd(), "jasymirror-%s" % self.id, hashkeys=True) info('Proxy "%s" => "%s" [debug:%s|mirror:%s|offline:%s]', self.id, self.host, self.enableDebug, self.enableMirror, self.enableOffline)
def watch(path, callback): header("Build Daemon") if Observer is None: error("You need to install Watchdog for supporting file system watchers") # We need to pause the session to make room for other jasy executions session.pause() # Initialize file system observer observer = Observer() observer.schedule(JasyEventHandler(), ".", recursive=True) observer.start() info("Started file system watcher for %s... [PID=%s]", path, os.getpid()) info("Use 'ulimit -n 1024' to increase number of possible open files") try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() info("Stopped file system watcher for %s...", path) observer.join()
def default(self, *args, **query): """ This method returns the content of existing files on the file system. Query string might be used for cache busting and are otherwise ignored. """ url = self.config["host"] + "/".join(args) result = None # Try using offline mirror if feasible if self.enableMirror and cherrypy.request.method == "GET": mirrorId = "%s[%s]" % (url, json.dumps(query, separators=(',',':'), sort_keys=True)) result = self.mirror.read(mirrorId) if result is not None and self.enableDebug: info("Mirrored: %s" % url) # Check if we're in forced offline mode if self.enableOffline and result is None: info("Offline: %s" % url) raise cherrypy.NotFound(url) # Load URL from remote server if result is None: # Prepare headers headers = CaseInsensitiveDict() for name in cherrypy.request.headers: if not name in self.__blockHeaders: headers[name] = cherrypy.request.headers[name] # Load URL from remote host try: if self.enableDebug: info("Requesting: %s", url) # Apply headers for basic HTTP authentification if "X-Proxy-Authorization" in headers: headers["Authorization"] = headers["X-Proxy-Authorization"] del headers["X-Proxy-Authorization"] # Add headers for different authentification approaches if self.auth: # Basic Auth if self.auth["method"] == "basic": headers["Authorization"] = b"Basic " + base64.b64encode(("%s:%s" % (self.auth["user"], self.auth["password"])).encode("ascii")) # We disable verifícation of SSL certificates to be more tolerant on test servers result = requests.get(url, params=query, headers=headers, verify=False) except Exception as err: if self.enableDebug: info("Request failed: %s", err) raise cherrypy.HTTPError(403) # Storing result into mirror if self.enableMirror and cherrypy.request.method == "GET": # Wrap result into mirrorable entry resultCopy = Result(result.headers, result.content) self.mirror.store(mirrorId, resultCopy) # Copy response headers to our reponse for name in result.headers: if not name.lower() in self.__blockHeaders: cherrypy.response.headers[name] = result.headers[name] # Append special header to all responses cherrypy.response.headers["X-Jasy-Version"] = jasy.__version__ # Enable cross domain access to this server enableCrossDomain() return result.content
def serve(routes=None, port=8080, host="127.0.0.1"): header("HTTP Server") # We need to pause the session to make room for other jasy executions session.pause() # Shared configuration (global/app) config = { "global" : { "environment" : "production", "log.screen" : False, "server.socket_port": port, "server.socket_host": host, "engine.autoreload_on" : False }, "/" : { "log.screen" : False } } # Update global config cherrypy.config.update(config) # Somehow this screen disabling does not work # This hack to disable all access/error logging works def empty(*param, **args): pass def inspect(*param, **args): if args["severity"] > 20: error("Critical error occoured:") error(param[0]) cherrypy.log.access = empty cherrypy.log.error = inspect cherrypy.log.screen = False # Initialize routing info("Initialize routing...") indent() root = Static("/", {}) if routes: for key in routes: entry = routes[key] if "host" in entry: node = Proxy(key, entry) else: node = Static(key, entry) setattr(root, key, node) outdent() # Finally start the server app = cherrypy.tree.mount(root, "", config) cherrypy.process.plugins.PIDFile(cherrypy.engine, "jasylock-http-%s" % port).subscribe() cherrypy.engine.start() info("Started HTTP server at port %s... [PID=%s]", port, os.getpid()) indent() cherrypy.engine.block() outdent() info("Stopped HTTP server at port %s.", port) # Resume session to continue work on next task (if given) session.resume()
def on_modified(self, event): super(JasyEventHandler, self).on_modified(event) what = 'directory' if event.is_directory else 'file' info("Modified %s: %s", what, event.src_path)
def on_moved(self, event): super(JasyEventHandler, self).on_moved(event) what = 'directory' if event.is_directory else 'file' info("Moved %s: from %s to %s", what, event.src_path, event.dest_path)