class BaseHandler(tornado.web.RequestHandler): ''' General request handler. ''' def initialize(self, registry): self.registry = registry if self.registry.get_hostname() == '': self.registry.set_hostname(self.request.protocol + '://' + self.request.host) def __init__(self, application, request, **kwargs): super(BaseHandler, self).__init__(application, request, **kwargs) # This ensures that at least one registry is loaded in case initialize # is not called for some reason... self.registry = NonePersistentRegistry() if self.registry.get_hostname() == '': self.registry.set_hostname(self.request.protocol + '://' + self.request.host) def extract_http_data(self): ''' Extracts all necessary information from the HTTP envelop. Minimize the data which is carried around inside of the service. Also ensures that the names are always equal - When deployed in Apache the names of the Headers change. ''' heads = {} headers = self.request.headers if 'Category' in headers: heads['Category'] = headers['Category'] if 'X-Occi-Attribute' in headers: heads['X-OCCI-Attribute'] = headers['X-Occi-Attribute'] if 'X-Occi-Location' in headers: heads['X-OCCI-Location'] = headers['X-Occi-Location'] if 'Link' in headers: heads['Link'] = headers['Link'] if self.request.body is not '': body = self.request.body.strip() else: body = '' return heads, body def get_renderer(self, content_type): ''' Returns the proper rendering parser. content_type -- String with either either Content-Type or Accept. ''' try: return self.registry.get_renderer( self.request.headers[content_type]) except KeyError: return self.registry.get_renderer(self.registry.get_default_type()) def response(self, status, mime_type, headers, body='OK'): ''' Will create a response and send it to the client. status -- The status code. mime_type -- Sets the Content-Type of the response. headers -- The HTTP headers. body -- The text for the body (default: ok). ''' self.set_header('Server', VERSION) self.set_header('Content-Type', mime_type) self.set_status(status) if headers is not None: for item in headers.keys(): self._headers[item] = headers[item] self.write(body) self.finish('\n') def get_error_html(self, status_code, **kwargs): self.set_header('Server', VERSION) self.set_header('Content-Type', self.registry.get_default_type()) exception = sys.exc_info()[1] msg = str(exception) self.set_status(status_code) return msg def parse_action(self): ''' Retrieves the Action which was given in the request. ''' headers, body = self.extract_http_data() rendering = self.get_renderer(CONTENT_TYPE) action = rendering.to_action(headers, body) return action def parse_filter(self): ''' Retrieve any attributes or categories which where provided in the request for filtering. ''' headers, body = self.extract_http_data() attr = 'X-OCCI-Attribute' if attr not in headers and 'Category' not in headers and body == '': return [], {} rendering = self.get_renderer(CONTENT_TYPE) categories, attributes = rendering.get_filters(headers, body) return categories, attributes def parse_entity(self, def_kind=None): ''' Retrieves the entity which was rendered within the request. def_kind -- Indicates if the request can be incomplete (False). ''' headers, body = self.extract_http_data() rendering = self.get_renderer(CONTENT_TYPE) entity = rendering.to_entity(headers, body, def_kind) return entity def parse_entities(self): ''' Retrieves a set of entities which was rendered within the request. ''' headers, body = self.extract_http_data() rendering = self.get_renderer(CONTENT_TYPE) entities = rendering.to_entities(headers, body) return entities def parse_mixins(self): ''' Retrieves a mixin from a request. ''' headers, body = self.extract_http_data() rendering = self.get_renderer(CONTENT_TYPE) mixin = rendering.to_mixins(headers, body) return mixin def render_entity(self, entity): ''' Renders a single entity to the client. entity -- The entity which should be rendered. ''' rendering = self.get_renderer(ACCEPT) headers, body = rendering.from_entity(entity) self.response(200, rendering.mime_type, headers, body) def render_entities(self, entities, key): ''' Renders a list of entities to the client. entities -- The entities which should be rendered. ''' rendering = self.get_renderer(ACCEPT) headers, body = rendering.from_entities(entities, key) self.response(200, rendering.mime_type, headers, body) def render_categories(self, categories): ''' Renders a list of categories to the client. categories -- The categories which should be rendered. ''' rendering = self.get_renderer(ACCEPT) headers, body = rendering.from_categories(categories) self.response(200, rendering.mime_type, headers, body)