Пример #1
0
def read_config(config_path):
    default_config = {
        "address": '0.0.0.0',
        "queue": 8,
        "port": 80,
        "datasize": 1024,
        "cpu_limit": psutil.cpu_count(),
        "document_root": "/server/"
    }
    file_existed = os.path.exists(config_path)
    if not file_existed:
        raise ValueError(f"Missed config on {config_path}")
    config_raw, error = open_io(config_path)
    if error:
        raise ValueError(f"Read file error:  {config_path}")
    config_values = config_raw.decode("utf-8").split('\n')
    for values in config_values:
        if values:
            key, value = re.search(r'\S* \S*', values).group(0).split(' ')
            default_config.update({key: value})
    default_config["binding"] = (default_config["address"],
                                 default_config["port"])
    default_config["cpu_limit"] = int(default_config["cpu_limit"])
    logger.info(f"Config: {default_config}")
    return default_config
Пример #2
0
 def server_init(self):
     self.socket_initialize()
     for worker in range(self.cpu_number):
         pid = os.fork()
         if pid > 0:
             self.forking_workers.append(pid)
         elif pid == 0:
             logger.info(f'Create new worker with pid: {os.getpid()}')
             while True:
                 client_socket, client_address = self.socket.accept()
                 raw_request = client_socket.recv(self.size)
                 if raw_request.strip() == 0:
                     client_socket.close()
                     continue
                 request = http_handlers.request_handler(raw_request)
                 if not request.validated:
                    response = self.answers["FORBIDDEN"]
                 else:
                     response = self.handle_request(request)
                 client_socket.send(response)
                 client_socket.close()
         else:
             logger.info("Cant fork anymore")
     self.socket.close()
     for worker_pid in self.forking_workers:
         os.waitpid(worker_pid, 0)
Пример #3
0
 def socket_initialize(self):
     server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     server_socket.bind(self.binding)
     server_socket.listen(self.queue)
     self.socket = server_socket
     logger.info(f"""Binding on {self.binding} with process count {self.cpu_number} with filepath {self.root}""")
Пример #4
0
    def file_handler(self, filepath):
        content_type = None
        content_length = 0

        data, error = open_io(filepath)
        if error:
            logger.info(f"Error in reading file with filename:{filepath}")  # Raise some exception?
        else:
            content_length = len(data)
            content_type = self.content_type(filepath)
        return data, content_length, content_type
def request_handler(input_request):
    method, path = None, None
    logger.info(f"Input raw request {input_request} \n")
    request_body = input_request.decode('utf-8')
    request_by_string = request_body.split(" ")
    validate = True if len(request_by_string) >= 3 else False  # Minimum length ( head example )
    if validate:
        method = request_by_string[0]
        path = unquote(request_by_string[1].split('?')[0])

    processing_request = Request(input_request.decode('utf-8'),
                                 method,
                                 validate,
                                 path)
    return processing_request
Пример #6
0
    def handle_request(self, request):
        filepath = os.path.normpath(self.root + request.path)
        logger.info(f"Filepath {filepath}")
        # Prefix check
        if os.path.commonprefix([self.root, filepath]) != self.root:
            logger.info("Status: 403")
            return self.answers["FORBIDDEN"]
        if request.method not in ("GET", "HEAD"):
            logger.info("Status: 405")
            return self.answers["NOT_ALLOWED"]
        elif not os.path.exists(filepath):
            logger.info("Status: 404")
            return self.answers["NOT_FOUND"]

        # Check dir path
        if os.path.isdir(filepath):
            filepath += '/index.html'
        if not os.path.exists(filepath):
            logger.info("Status: 403")
            return self.answers["FORBIDDEN"]
        if not os.path.isfile(filepath):
            logger.info("Status: 403")
            return self.answers["FORBIDDEN"]

        data, content_length, content_type = self.file_handler(filepath)

        if content_type is None:
            logger.info("Status: 404")
            return self.answers["NOT_FOUND"]

        if request.method == 'HEAD':
            logger.info("Status: 200")
            return http_handlers.response_handler(http_version=HTTP_VERSION,
                                                  status_code=HTTPStatus.OK,
                                                  content_len=content_length,
                                                  content_type=content_type)
        logger.info("Status: 200")
        return http_handlers.response_handler(http_version=HTTP_VERSION,
                                              status_code=HTTPStatus.OK,
                                              content_len=content_length,
                                              content_type=content_type,
                                              data=data)