def serve_directory(directory_meta, request_path, server): """ called when asked to serce a directory check for the presence of an index file and serve it (without redirect of course) or present an index if there isn't one lets lok through meta_info[contents], anything with index is of interest precedence is .dbpy, .html, .txt, and thats it for now, just auto generate an index, fun! """ #redirect like apache if we don't end the path with '/' if not request_path.endswith('/'): redirect_location = request_path + '/' if server.request.query_string: redirect_location += '?' + server.request.query_string return Response(301, 'redirect', headers={'Location': redirect_location}) #ok, lets build our index thing extensions_precedence = ('dbpy', 'html', 'txt') #build the re re_string = "^index\.(%s)$" % ('|'.join(extensions_precedence)) index_re = re.compile(re_string) index_paths = {} for file_meta in directory_meta['contents']: file_path = file_meta['path'] base_name = os.path.basename(file_path) index_re_match = index_re.match(base_name) if index_re_match: match_type = index_re_match.group(1) index_paths[match_type] = file_meta for extension in extensions_precedence: if extension in index_paths: new_file_meta = index_paths[extension] new_request_path = request_path + os.path.basename( new_file_meta['path']) #we know request path ends with a '/' return server._serve_file(new_file_meta, new_request_path) #there are no index files, so lets return a default one index_file = util.index_generator.get_index_file( directory_meta['contents'], request_path, server.client) return Response(200, index_file)
def _serve_file(self, meta_info, path): for handler in self.handlers: checkfunc = handler['check'] if checkfunc(meta_info): return handler['handler'](meta_info, path, self) #if we get to here we have to return an error #415 is unsupported media type, by the way return Response(415, 'No Handler installed for given path', error=True)
def serve_dbpy(file_meta, request_path, server): path = file_meta['path'] f = server.client.get_file(path).read() if f.startswith("#NOEXECUTE"): #allows these files to be shared without getting executed headers = {'Content-type': 'text/plain'} return Response(200, f, headers) param_dict = dict(client=server.client, request=server.request) return dbpy.execute.execute(f, **param_dict)
def serve_static(file_meta, request_path, server): """ downloads and serves the file in path """ path = file_meta['path'] f = server.client.get_file(path).read() if f.startswith('#DBPYEXECUTE'): #allows arbitrary text files to be run as dbpy code. security risk? #any way, it is like a bypass... back to dbpy param_dict = dict(client=server.client, request=server.request) return dbpy.execute.execute(f, **param_dict) headers = {'Content-type': server._get_content_type(file_meta)} return Response(200, f, headers)
def serve(self): """ serves the given path, returning a Response Object some special rules - if it is a directory, returns an indexed list of the files - if it is a directory without a trailing slash, returns a redirect request (these will also be able to come fro) """ request = self.request client = self.client path = request.path #anything prefixed with '_' is not accessable path_components = path.split('/') for component in path_components: if component.startswith('_'): return Response(403, 'Forbidden', error=True) try: #f**k this extra request... is there a way to avoid it? probably meta_info = self.client.metadata(path) #### checking for the is_Deleted flag try: if meta_info['is_deleted']: return Response(410, "File is deleted", error=True) except KeyError: pass #its not deleted #ok. here is were i need to call the file thing return self._serve_file(meta_info, path) except dropbox.rest.ErrorResponse as e: return Response(e.status, e.reason, headers=e.headers, error=True)
def serve_markdown(file_meta, request_path, server): page_template = """ <html> <head> <title> %s </title> </head> <body> %s </body> </html> """ path = file_meta['path'] page_title = "%s | Markdown" % path page_body = markdown.markdown(server.client.get_file(path).read()) page = page_template % (page_title, page_body) headers = {'Content-Type': 'text/html'} return Response(200, page, headers)
def execute(filestring, **kwargs): PRINT_EXCEPTIONS = True DEBUG = True response = Response(None, "") sandbox = get_sandbox() #setting up the parameters for the builtin construction locker = dbapi.io.DropboxFileLocker(kwargs['client']) request = kwargs['request'] cookie = request.headers.get('Cookie', None) session = util.sessions.DrapacheSession(cookie) builtin_params = dict(response=response, locker=locker, sandbox=sandbox, session=session, **kwargs) env = environment.DBPYEnvironment(**builtin_params) #replaceing stdout old_stdout = sys.stdout new_stdout = StringIO.StringIO() sys.stdout = new_stdout try: sandbox_thread = DBPYExecThread(env, filestring) sandbox_thread.start() sandbox_thread.join(env.DBPY_TIMEOUT) if sandbox_thread.isAlive(): #time to kill it sandbox_thread.kill() sandbox_thread.join() if sandbox_thread.error is not None: #this is where processing of the traceback should take place #so that we can show a meaningful error message if DEBUG: print "<h1>Debug Traceback</h1>" print "<pre>" sys.stdout.write(sandbox_thread.error_traceback) print "</pre>" raise sandbox_thread.error except: if PRINT_EXCEPTIONS: print "<pre>" traceback.print_exc(file=new_stdout) print "</pre>" sys.stdout = old_stdout response.body = new_stdout.getvalue() if response.status is None: response.status = 200 if not 'Content-Type' in response.headers: response.set_header('Content-Type', 'text/html') return response
def execute(filestring,**kwargs): PRINT_EXCEPTIONS = True DEBUG = True response = Response(None,"") sandbox = get_sandbox() #setting up the parameters for the builtin construction locker = dbapi.io.DropboxFileLocker(kwargs['client']) request = kwargs['request'] cookie = request.headers.get('Cookie',None) session = util.sessions.DrapacheSession(cookie) builtin_params = dict( response=response, locker=locker, sandbox=sandbox, session=session, **kwargs ) env = environment.DBPYEnvironment(**builtin_params) #replaceing stdout old_stdout = sys.stdout new_stdout = StringIO.StringIO() sys.stdout = new_stdout try: sandbox_thread = DBPYExecThread(env,filestring) sandbox_thread.start() sandbox_thread.join(env.DBPY_TIMEOUT) if sandbox_thread.isAlive(): #time to kill it sandbox_thread.kill() sandbox_thread.join() if sandbox_thread.error is not None: #this is where processing of the traceback should take place #so that we can show a meaningful error message if DEBUG: print "<h1>Debug Traceback</h1>" print "<pre>" sys.stdout.write(sandbox_thread.error_traceback) print "</pre>" raise sandbox_thread.error except: if PRINT_EXCEPTIONS: print "<pre>" traceback.print_exc(file=new_stdout) print "</pre>" sys.stdout = old_stdout response.body = new_stdout.getvalue() if response.status is None: response.status = 200 if not 'Content-Type' in response.headers: response.set_header('Content-Type','text/html') return response