diff --git a/warden3/warden_server/warden_server.py b/warden3/warden_server/warden_server.py index 9df6bf8f227ae7fd3b66fa91dafd75142f23b6fb..be4a43594d673c9785c258ee174ee4c94c178f18 100755 --- a/warden3/warden_server/warden_server.py +++ b/warden3/warden_server/warden_server.py @@ -845,11 +845,6 @@ class Server(ObjectReq): exception = None try: - try: - injson = environ['wsgi.input'].read() - except: - raise self.req.error(message="Data read error.", error=408, exc=sys.exc_info()) - try: method = getattr(self.handler, path) method.exposed # dummy access to trigger AttributeError @@ -862,14 +857,6 @@ class Server(ObjectReq): if not client: raise self.req.error(message="I'm watching. Authenticate.", error=403) - try: - events = json.loads(injson) if injson else None - except Exception as e: - raise self.req.error(message="Deserialization error.", error=400, - exc=sys.exc_info(), args=injson, parser=str(e)) - if events: - args["events"] = events - auth = self.auth.authorize(self.req.env, self.req.client, self.req.path, method) if not auth: raise self.req.error(message="I'm watching. Not authorized.", error=403, client=client.name) @@ -880,15 +867,13 @@ class Server(ObjectReq): args.pop("hostnames", None) args = self.sanitize_args(path, method, args) - result = method(**args) # call requested method try: - # 'default': takes care of non JSON serializable objects, - # which could (although shouldn't) appear in handler code - output = json.dumps(result, default=lambda v: str(v)) - except Exception as e: - raise self.req.error(message="Serialization error", error=500, - exc=sys.exc_info(), args=str(result)) + post_data = environ['wsgi.input'].read() + except: + raise self.req.error(message="Data read error.", error=408, exc=sys.exc_info()) + + headers, output = method(post_data, **args) except Error as e: exception = e @@ -919,6 +904,33 @@ class Server(ObjectReq): +def json_wrapper(method): + + def meth_deco(self, post, **args): + if "events" in method.func_code.co_varnames[0:method.func_code.co_argcount]: + try: + events = json.loads(post) if post else None + except Exception as e: + raise self.req.error(message="Deserialization error.", error=400, + exc=sys.exc_info(), args=post, parser=str(e)) + if events: + args["events"] = events + + result = method(self, **args) # call requested method + + try: + # 'default': takes care of non JSON serializable objects, + # which could (although shouldn't) appear in handler code + output = json.dumps(result, default=lambda v: str(v)) + except Exception as e: + raise self.req.error(message="Serialization error", error=500, + exc=sys.exc_info(), args=str(result)) + + return [('Content-type', 'application/json')], output + + return meth_deco + + class WardenHandler(ObjectReq): def __init__(self, req, validator, db, auth, @@ -941,6 +953,7 @@ class WardenHandler(ObjectReq): @expose(read=1, debug=1) + @json_wrapper def getDebug(self): return { "environment": self.req.env, @@ -964,6 +977,7 @@ class WardenHandler(ObjectReq): @expose(read=1) + @json_wrapper def getInfo(self): info = { "version": VERSION, @@ -976,6 +990,7 @@ class WardenHandler(ObjectReq): @expose(read=1) + @json_wrapper def getEvents(self, id=None, count=None, cat=None, nocat=None, tag=None, notag=None, @@ -1041,12 +1056,16 @@ class WardenHandler(ObjectReq): ev_ids = err.setdefault("events_id", []) for i in ilist: event = events[i] - id = event.get("ID", None) + try: + id = event["ID"] + except (AttributeError, TypeError, ValueError): + id = None ev_ids.append(id) return errlist @expose(write=1) + @json_wrapper def sendEvents(self, events=[]): if not isinstance(events, list): raise self.req.error(message="List of events expected.", error=400)