def handle(self, url, method): if not self.serve: return HTTPError(503, "Server stopped") try: handler, args = self.match_url(url, method) return handler(**args) except HTTPResponse, e: return e
def match_url(self, path, method='GET'): path, method = path.strip().lstrip('/'), method.upper() callbacks, args = self.routes.match(path) if not callbacks: raise HTTPError(404, "Not found: " + path) if method in callbacks: return callbacks[method], args if method == 'HEAD' and 'GET' in callbacks: return callbacks['GET'], args if 'ANY' in callbacks: return callbacks['ANY'], args allow = [m for m in callbacks if m != 'ANY'] if 'GET' in allow and 'HEAD' not in allow: allow.append('HEAD') raise HTTPError(405, "Method not allowed.", header=[('Allow', ",".join(allow))])
def get(self, path, params): url = self._user + self._ipAddr + ':' + str(self._port) + path try: response = requests.get(url=url, params=params) response.raise_for_status() return json.loads(response.text) except requests.exceptions.HTTPError: raise HTTPError('HTTP error') except requests.exceptions.RequestException: raise ConnError('Wrong IP')
def post(self, path, data): url = self._user + self._ipAddr + ':' + str(self._port) + path dat = 'json=' + json.dumps(data) try: response = requests.post(url=url, headers=self._head, data=dat) response.raise_for_status() return json.loads(response.text) except requests.exceptions.HTTPError: raise HTTPError('HTTP error') except requests.exceptions.RequestException: raise ConnError('Wrong IP')
def static_file(filename, root, guessmime=True, mimetype=None, download=False): root = os.path.abspath(root) + os.sep filename = os.path.abspath(os.path.join(root, filename.strip('/\\'))) header = dict() if not filename.startswith(root): return HTTPError(403, "Access denied.") if not os.path.exists(filename) or not os.path.isfile(filename): return HTTPError(404, "File does not exist.") if not os.access(filename, os.R_OK): return HTTPError(403, "You do not have permission to access this file.") if not mimetype and guessmime: header['Content-Type'] = mimetypes.guess_type(filename)[0] else: header['Content-Type'] = mimetype if mimetype else 'text/plain' if download == True: download = os.path.basename(filename) if download: header['Content-Disposition'] = 'attachment; filename="%s"' % download stats = os.stat(filename) lm = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(stats.st_mtime)) header['Last-Modified'] = lm ims = request.environ.get('HTTP_IF_MODIFIED_SINCE') if ims: ims = ims.split(";")[0].strip() ims = parse_date(ims) if ims is not None and ims >= int(stats.st_mtime): header['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime()) return HTTPResponse(status=304, header=header) header['Content-Length'] = stats.st_size if request.method == 'HEAD': return HTTPResponse('', header=header) else: return HTTPResponse(open(filename, 'rb'), header=header)
def patch(self): raise HTTPError(405)
class Brick(object): def __init__(self, catchall=True, autojson=True, config=None): self.routes = Router() self._logger = None self.mounts = {} self.error_handler = {} self.catchall = catchall self.config = config or {} self.serve = True self.castfilter = [] if autojson and dumps: self.add_filter(dict, dumps) def optimize(self, *a, **ka): depr("Brick.optimize() is obsolete.") def mount(self, app, script_path): if not isinstance(app, Brick): raise TypeError('Only Brick instances are supported for now.') script_path = '/'.join(filter(None, script_path.split('/'))) path_depth = script_path.count('/') + 1 if not script_path: raise TypeError('Empty script_path. Perhaps you want a merge()?') for other in self.mounts: if other.startswith(script_path): raise TypeError('Conflict with existing mount: %s' % other) @self.route('/%s/:#.*#' % script_path, method="ANY") def mountpoint(): request.path_shift(path_depth) return app.handle(request.path, request.method) self.mounts[script_path] = app def add_filter(self, ftype, func): if not isinstance(ftype, type): raise TypeError("Expected type object, got %s" % type(ftype)) self.castfilter = [(t, f) for (t, f) in self.castfilter if t != ftype] self.castfilter.append((ftype, func)) self.castfilter.sort() def match_url(self, path, method='GET'): path, method = path.strip().lstrip('/'), method.upper() callbacks, args = self.routes.match(path) if not callbacks: raise HTTPError(404, "Not found: " + path) if method in callbacks: return callbacks[method], args if method == 'HEAD' and 'GET' in callbacks: return callbacks['GET'], args if 'ANY' in callbacks: return callbacks['ANY'], args allow = [m for m in callbacks if m != 'ANY'] if 'GET' in allow and 'HEAD' not in allow: allow.append('HEAD') raise HTTPError(405, "Method not allowed.", header=[('Allow', ",".join(allow))]) def get_url(self, routename, **kargs): scriptname = request.environ.get('SCRIPT_NAME', '').strip('/') + '/' location = self.routes.build(routename, **kargs).lstrip('/') return urljoin(urljoin('/', scriptname), location) def route(self, path=None, method='GET', **kargs): def wrapper(callback): routes = [path] if path else yieldroutes(callback) methods = method.split(';') if isinstance(method, str) else method for r in routes: for m in methods: r, m = r.strip().lstrip('/'), m.strip().upper() old = self.routes.get_route(r, **kargs) if old: old.target[m] = callback else: self.routes.add(r, {m: callback}, **kargs) self.routes.compile() return callback return wrapper def get(self, path=None, method='GET', **kargs): return self.route(path, method, **kargs) def post(self, path=None, method='POST', **kargs): return self.route(path, method, **kargs) def put(self, path=None, method='PUT', **kargs): return self.route(path, method, **kargs) def delete(self, path=None, method='DELETE', **kargs): return self.route(path, method, **kargs) def error(self, code=500): def wrapper(handler): self.error_handler[int(code)] = handler return handler return wrapper def handle(self, url, method): if not self.serve: return HTTPError(503, "Server stopped") try: handler, args = self.match_url(url, method) return handler(**args) except HTTPResponse, e: return e except Exception, e: if isinstance(e, (KeyboardInterrupt, SystemExit, MemoryError))\ or not self.catchall: raise print e return HTTPError(500, 'Unhandled exception', e, format_exc(10))
def abort(code=500, text='Unknown Error: Appliction stopped.'): raise HTTPError(code, text)
if 'wsgi.file_wrapper' in request.environ: return request.environ['wsgi.file_wrapper'](out) elif hasattr(out, 'close') or not hasattr(out, '__iter__'): return WSGIFileWrapper(out) try: out = iter(out) first = out.next() while not first: first = out.next() except StopIteration: return self._cast('', request, response) except HTTPResponse, e: first = e except Exception, e: first = HTTPError(500, 'Unhandled exception', e, format_exc(10)) if isinstance(e, (KeyboardInterrupt, SystemExit, MemoryError))\ or not self.catchall: raise if isinstance(first, HTTPResponse): return self._cast(first, request, response) if isinstance(first, StringType): return itertools.chain([first], out) if isinstance(first, unicode): return itertools.imap(lambda x: x.encode(response.charset), itertools.chain([first], out)) return self._cast(HTTPError(500, 'Unsupported response type: %s'\ % type(first)), request, response) def __call__(self, environ, start_response): try:
def trace(self): raise HTTPError(405)
def connect(self): raise HTTPError(405)
def options(self): raise HTTPError(405)
def delete(self): raise HTTPError(405)
def put(self): raise HTTPError(405)
def head(self): raise HTTPError(405)
def post(self): raise HTTPError(405)
def get(self): raise HTTPError(405)