def __call__(self, env, start_response): """WSGI entry point.""" self._new_request(env, start_response) method = env['REQUEST_METHOD'] path = env['SCRIPT_NAME'] + env['PATH_INFO'] # Find the handler for our request handler, match = self.find_handler(path, method) if not handler: if method == 'HEAD' and 'GET' in match: # Default action for HEAD is GET without the entity handler, match = self.find_handler(path, method='GET') assert handler is not None elif method == 'OPTIONS' or match: # Show alternative methods headers = [('Allow', ','.join(match + ['OPTIONS']))] status = http.NO_CONTENT if method == 'OPTIONS' else http.METHOD_NOT_ALLOWED return self.create_response(status, headers) else: return self.create_response(http.NOT_FOUND) # Authenticate if not handler.anonymous: try: self.authenticate(env) except Exception as e: return self.create_error(e) # Try to parse an application/json entity ctype = env.get('CONTENT_TYPE') if ctype: ctype, options = http.split_header_options(ctype) if ctype != 'application/json': return self.create_response(http.UNSUPPORTED_MEDIA_TYPE) charset = options.get('charset', 'UTF-8').lower() if charset not in ('utf-8', 'iso-8858-1'): return self.create_response(http.BAD_REQUEST) body = env['wsgi.input'].read() decoded = body.decode(charset) entity = json.try_loads(decoded, dict) if entity is None: return self.create_response(http.BAD_REQUEST) self.remove_links(entity) else: entity = None # Validate the entity validator = handler.entity_validator if validator: try: validator.validate_raise(entity) except ValidationError as e: return self.create_error(e) env['rest.entity'] = entity # Call the handler! try: result = handler(*match.groups()) except Exception as e: return self.create_error(e) return self.create_response(entity=result)
def authenticate(self, env): auth = env.get('HTTP_AUTHORIZATION') headers = [('WWW-Authenticate', 'Token')] if not auth: raise HttpReturn(http.UNAUTHORIZED, headers) method, options = http.split_header_options(auth, sep=' ') if method.lower() != 'token' or 'id' not in options: raise HttpReturn(http.UNAUTHORIZED, headers) if not self.model.validate_token(options['id'], 'client_api'): raise HttpReturn(http.UNAUTHORIZED, headers)