Esempio n. 1
0
 def post(self, api_request):
     if self.verbose:
         logging.info('post: api_request={}', api_request)
     context = api_request['context']
     if len(context) > 0:
         query_params = api_request['query_params']
         operator = context[0]
         if operator == 'mode':
             self.controller.set_mode(query_params['mode'])
         elif operator == 'np':
             pin = None
             num_pixels = None
             if 'pin' in query_params:
                 pin = query_params['pin']
             if 'num_pixels' in query_params:
                 num_pixels = query_params['num_pixels']
             self.controller.set_np(pin=pin, num_pixels=num_pixels)
         elif operator == 'lamp':
             if 'color_name' not in query_params:
                 raise uhttpd.BadRequestException(
                     "Expected name in query_params")
             self.controller.set_color_name(query_params['color_name'])
         elif operator == 'schedule':
             if 'name' not in query_params:
                 raise uhttpd.BadRequestException(
                     "Expected name in query_params")
             self.controller.update_schedule(query_params['name'],
                                             api_request['body'])
         elif operator == 'colorspec':
             if 'name' not in query_params:
                 raise uhttpd.BadRequestException(
                     "Expected name in query_params")
             self.controller.set_colorspec(query_params['name'],
                                           api_request['body'])
         elif operator == 'color':
             self.controller.set_color(
                 (int(query_params['r']), int(query_params['g']),
                  int(query_params['b'])))
         elif operator == 'reboot':
             self.controller.reboot()
         elif operator == 'reset':
             self.controller.reset()
         else:
             raise uhttpd.BadRequestException(
                 "Bad post request: Unknown operator: {}".format(operator))
     else:
         raise uhttpd.BadRequestException(
             "Bad post request: Missing operator in context")
 def save(self, api_request):
     context = api_request['context']
     logging.info("context: {}".format(context))
     if context == ['ap', 'config']:
         return self.save_ap_config(api_request)
     else:
         raise uhttpd.BadRequestException("Unsupported context on save: {}",
                                          context)
 def extract_query(path):
     components = path.split("?")
     query_params = {}
     if len(components) == 1:
         return path, query_params
     elif len(components) > 2:
         raise uhttpd.BadRequestException("Malformed path: {}".format(path))
     path_part = components[0]
     query_part = components[1]
     qparam_components = query_part.split("&")
     for qparam_component in qparam_components:
         if qparam_component.strip() == '':
             continue
         qparam = qparam_component.split("=")
         if len(qparam) != 2 or not qparam[0]:
             raise uhttpd.BadRequestException(
                 "Invalid query parameter: {}".format(qparam_component))
         query_params[qparam[0]] = qparam[1]
     return path_part, query_params
Esempio n. 4
0
 def delete(self, api_request):
     context = api_request['context']
     if len(context) > 0:
         query_params = api_request['query_params']
         operator = context[0]
         if operator == 'schedule':
             if 'name' not in query_params:
                 raise uhttpd.BadRequestException(
                     "Expected name in query_params")
             self.controller.delete_schedule(query_params['name'])
         elif operator == 'colorspec':
             if 'name' not in query_params:
                 raise uhttpd.BadRequestException(
                     "Expected name in query_params")
             self.controller.delete_colorspec(query_params['name'])
         else:
             raise uhttpd.BadRequestException(
                 "Bad delete request: Unknown operator: {}".format(
                     operator))
     else:
         raise uhttpd.BadRequestException(
             "Bad delete request: Missing operator in context")
Esempio n. 5
0
 def get(self, api_request):
     context = api_request['context']
     if len(context) > 0:
         if context[0] == 'config':
             query_params = api_request['query_params']
             return Handler.get_path(
                 self.controller.config, context[1:], 'all' in query_params
                 and query_params['all'] == 'true')
         if context[0] == 'stats':
             return self.controller.get_stats()
         if context[0] == 'color':
             return self.controller.get_color()
     else:
         raise uhttpd.BadRequestException(
             "Bad get request: Missing operator in context")
 def handle_request(self, http_request):
     #
     # We only support GET
     #
     verb = http_request['verb']
     if verb != 'get':
         raise uhttpd.BadRequestException(
             "Unsupported HTTP verb: {}".format(verb))
     # the relative path is the path on the HTTP request stripped of the
     # prefix used to register the file handler
     relative_path = uhttpd.get_relative_path(http_request)
     # the effective path is the relative path with the root path
     # prefixed, and normalized to remove '.' and '..'
     absolute_path = self.effective_path(relative_path)
     #
     # If the path is forbidden, 403 out
     #
     remote_addr = http_request['tcp']['remote_addr']
     if not self.is_prefix(self._root_path, absolute_path):
         logging.info("FORBIDDEN {} {}".format(remote_addr, absolute_path))
         raise uhttpd.ForbiddenException(absolute_path)
     #
     # If the path doesn't exist, 404 out
     #
     if not exists(absolute_path):
         logging.info("NOT_FOUND {} {}".format(remote_addr, absolute_path))
         raise uhttpd.NotFoundException(absolute_path)
     #
     # Otherwise, generate a file listing or a file
     #
     if is_dir(absolute_path):
         index_path = absolute_path + "/index.html"
         if exists(index_path):
             response = self.create_file_response(index_path)
             logging.info("ACCESS {} {}".format(remote_addr, index_path))
             return response
         else:
             logging.info("ACCESS {} {}".format(remote_addr, absolute_path))
             prefix = http_request['prefix']
             return self.create_dir_listing_response(absolute_path)
     else:
         logging.info("ACCESS {} {}".format(remote_addr, absolute_path))
         return self.create_file_response(absolute_path)
Esempio n. 7
0
 def get(self, api_request):
     #print(api_request)
     context = api_request['context']
     if len(context) > 0:
         what_to_return = context[0]
         if what_to_return == 'query_params':
             query_params = api_request['query_params']
             return query_params
         elif what_to_return == "nothing":
             return None
         elif what_to_return == "empty":
             return b''
         elif what_to_return == "something":
             return b'something'
         elif what_to_return == "bad_request_excetion":
             raise uhttpd.BadRequestException("derp")
         elif what_to_return == "not_found_excetion":
             raise uhttpd.NotFoundException("what you were looking for")
         elif what_to_return == "forbidden_excetion":
             raise uhttpd.ForbiddenException("tsktsk")
     return {'action': 'get'}
 def get(self, api_request):
     #print(api_request)
     context = api_request['context']
     if len(context) > 0:
         what_to_return = context[0]
         if what_to_return == 'query_params':
             query_params = api_request['query_params']
             return query_params
         elif what_to_return == "nothing":
             return None
         elif what_to_return == "empty":
             return b''
         elif what_to_return == "something":
             return b'something'
         elif what_to_return == "html":
             return "<html><body><h1>HTML</h1></body></html>"
         elif what_to_return == "json":
             return {
                 'some': [{
                     'j': 1,
                     's': [],
                     'o': "str",
                     'n': {
                         "дружище": "バディ"
                     }
                 }]
             }
         elif what_to_return == "int":
             return 1342
         elif what_to_return == "float":
             return 3.14159
         elif what_to_return == "bad_request_excetion":
             raise uhttpd.BadRequestException("derp")
         elif what_to_return == "not_found_excetion":
             raise uhttpd.NotFoundException("what you were looking for")
         elif what_to_return == "forbidden_excetion":
             raise uhttpd.ForbiddenException("tsktsk")
     else:
         return {'action': 'get'}
 def handle_request(self, http_request):
     relative_path = uhttpd.get_relative_path(http_request)
     path_part, query_params = self.extract_query(relative_path)
     components = path_part.strip('/').split('/')
     prefix, handler, context = self.find_handler(components)
     if handler:
         json_body = None
         headers = http_request['headers']
         if 'body' in http_request and 'content-type' in headers and headers[
                 'content-type'] == "application/json":
             try:
                 json_body = ujson.loads(http_request['body'])
             except Exception as e:
                 raise uhttpd.BadRequestException(
                     "Failed to load JSON: {}".format(e))
         verb = http_request['verb']
         api_request = {
             'prefix': prefix,
             'context': context,
             'query_params': query_params,
             'body': json_body,
             'http': http_request
         }
         if verb == 'get':
             response = handler.get(api_request)
         elif verb == 'put':
             response = handler.put(api_request)
         elif verb == 'post':
             response = handler.post(api_request)
         elif verb == 'delete':
             response = handler.delete(api_request)
         else:
             # TODO add support for more verbs!
             error_message = "Unsupported verb: {}".format(verb)
             raise uhttpd.BadRequestException(error_message)
     else:
         error_message = "No handler found for components {}".format(
             components)
         raise uhttpd.NotFoundException(error_message)
     ##
     ## prepare response
     ##
     if response is not None:
         response_type = type(response)
         if response_type is dict or response_type is list:
             data = ujson.dumps(response).encode('UTF-8')
             body = lambda stream: stream.awrite(data)
             content_type = "application/json"
             content_length = len(data)
         elif response_type is bytes:
             data = response
             body = lambda stream: stream.awrite(data)
             content_type = "application/binary"
             content_length = len(data)
         elif response_type is str:
             data = response.encode("UTF-8")
             body = lambda stream: stream.awrite(data)
             content_type = "text/html; charset=utf-8"
             content_length = len(data)
         elif response_type is int or response_type is float:
             data = str(response)
             body = lambda stream: stream.awrite(data)
             content_type = "text/plain"
             content_length = len(data)
         else:
             data = str(response)
             body = lambda stream: stream.awrite(data)
             content_type = "text/plain"
             content_length = len(data)
     else:
         body = None
         content_type = None
         content_length = None
     headers = {}
     if content_length:
         headers.update({'content-length': content_length})
     if content_type:
         headers.update({'content-type': content_type})
     return {'code': 200, 'headers': headers, 'body': body}
Esempio n. 10
0
 def handle_request(self, http_request):
     relative_path = uhttpd.get_relative_path(http_request)
     path_part, query_params = self.extract_query(relative_path)
     components = path_part.strip('/').split('/')
     prefix, handler, context = self.find_handler(components)
     if handler:
         json_body = None
         headers = http_request['headers']
         if 'body' in http_request and 'content-type' in headers and headers[
                 'content-type'] == "application/json":
             try:
                 json_body = ujson.loads(http_request['body'])
             except Exception as e:
                 raise uhttpd.BadRequestException(
                     "Failed to load JSON: {}".format(e))
         verb = http_request['verb']
         api_request = {
             'prefix': prefix,
             'context': context,
             'query_params': query_params,
             'body': json_body,
             'http': http_request
         }
         if verb == 'get':
             response = handler.get(api_request)
         elif verb == 'put':
             response = handler.put(api_request)
         elif verb == 'post':
             response = handler.post(api_request)
         elif verb == 'delete':
             response = handler.delete(api_request)
         else:
             # TODO add support for more verbs!
             error_message = "Unsupported verb: {}".format(verb)
             raise uhttpd.BadRequestException(error_message)
     else:
         error_message = "No handler found for components {}".format(
             components)
         raise uhttpd.NotFoundException(error_message)
     if response is not None:
         if type(response) is dict:
             data = ujson.dumps(response).encode('UTF-8')
             content_type = "application/json"
         elif type(response) is bytes:
             data = response
             content_type = "application/binary"
         else:
             raise Exception(
                 "Response from API Handler is neither dict nor bytearray nor None"
             )
         body = lambda stream: stream.awrite(data)
     else:
         data = body = None
     ret = {
         'code': 200,
         'headers': {
             'content-length': len(data) if data else 0
         },
         'body': body
     }
     if data is not None:
         ret['headers']['content-type'] = content_type
     return ret