コード例 #1
0
ファイル: route.py プロジェクト: mmasata/miniweb
    def __compile_regex(self, url):
        try:
            log.debug("Compile url to regex.")

            self.num_slashes = []
            slash = 0
            params = []
            current_param = ""
            param_reading = False
            self.regex_str = "^"

            for char in url:
                if char is "{":
                    self.num_slashes.append(slash)
                    param_reading = True
                elif char is "}":
                    param_reading = False
                    params.append(current_param)
                    self.regex_str += "\w+"
                    current_param = ""
                elif param_reading:
                    current_param += char
                else:
                    self.regex_str += char
                    slash = slash + 1 if char is "/" else slash

            self.regex_str += "$"
            return ure.compile(self.regex_str), params
        except:
            raise CompileRegexException(
                "Error with compiling regex in route class!")
コード例 #2
0
    def __parse_data(self, data):
        log.info("Parsing FormData.")
        rows = data.split("\r\n")
        read_values = False
        current_value = ""
        current_is_file = False
        filename = None
        current_key = None
        for row in rows:
            if not (row[0:2] == "--"):
                if not read_values:
                    if row != "":
                        param_header = row.split(";")
                        current_is_file = len(param_header) == 3
                        filename = param_header[2] if current_is_file else None
                        current_key = param_header[1].split('"')[1]
                        read_values = True
                else:
                    current_value += row
            elif current_key is not None:
                if current_is_file:
                    current_value = self.__create_file(filename, current_value)

                log.debug("Set form data attribute with key: {k}.".format(
                    k=current_key))
                setattr(self, current_key, current_value)
                read_values = False
                current_key = None
                current_value = ""
                filename = None
コード例 #3
0
ファイル: request.py プロジェクト: mmasata/miniweb
    async def parse_header(self, data):
        """
        Accept HTTP request header in raw and parse them and store to attribute.
        :param data: Incoming header row.
        :return: Boolean if we can continue read headers.
        """

        try:
            if not self.has_path:
                self.method, full_path, proto = data.split()
                log.info("Incoming HTTP request {m} {p}.".format(m=self.method, p=full_path))

                await self.__find_query_params(full_path)
                self.has_path = True
            else:
                header, value = data.split(": ")
                self.headers[header] = value.replace("\r\n", "")
                log.debug("Header\n {k}: {v}".format(k=header, v=self.headers[header]))

                if "Content-Length" == header:
                    self.headers["Content-Type"] = self.headers["Content-Type"].split(";")[0]
                    self.content_len = int(value)
                    self.content_read = self.content_len > 0
                    return False

            return True
        except HeaderException:
            log.error("Error during read of request headers!")
コード例 #4
0
ファイル: server.py プロジェクト: mmasata/miniweb
    async def __handle(self, reader, writer):
        req = Request()
        h_read = True

        while h_read:
            h_line = await reader.readline()

            if h_line == b"\r\n":
                log.debug("All headers was accepted.")
                break

            if len(h_line) > 0:
                h_read = await req.parse_header(h_line.decode())

        if req.content_read:
            content = await reader.read(-1)
            await req.parse_content(content.decode())

        res = await self.miniweb.handle_response(req, Response())
        log.debug("Response arrived back to server.py")

        if res is not None and res.can_send:
            await self.__send_headers(res, writer)
            await self.__send_data(res, writer)
            await self.__close_connection(writer)
        else:
            log.warning(
                "End communication with client - will drop on timeout!")

        if not self.keep_run:
            await self.__stop()
コード例 #5
0
ファイル: response.py プロジェクト: mmasata/miniweb
    def build(self):
        """
        Send response to client and mark it as finished.
        :return: self
        """

        log.debug("Response was marked as builded.")
        self.can_send = True
        return self
コード例 #6
0
ファイル: route.py プロジェクト: mmasata/miniweb
 def is_match(self, path):
     """
     Accept current path from HTTP request and looking for match with current route.
     :param path: Incoming path from HTTP request.
     :return: Boolean of match
     """
     log.debug("Looking for route match.\n Path: {p}\n Regex: {r}".format(
         p=path, r=self.regex_str))
     return ure.match(self.regex, path) is not None
コード例 #7
0
    def __init__(self, path, params=None):
        if path is None:
            path = "/default/"

        log.debug("Creating new controller with path: {p}.".format(p=path))

        self.path = path
        self.params = params
        self.filters = []
コード例 #8
0
 def _filter(fc):
     if controller is None:
         log.debug("Adding new global middleware function.")
         global_filter.append(fc)
     else:
         log.debug(
             "Adding new controller middleware function for controller with path: {p}"
             .format(p=controller.path))
         controller.add_filter(fc)
     return fc
コード例 #9
0
def get_mime_by_suffix(destination_file):
    """
    Find mime type by incoming file suffix.
    :param suff: File suffix.
    :return: mime type
    """

    suff = destination_file.split('.')[1]
    log.debug("Incoming suffix to recognize Mime: {s}.".format(s=suff))
    return suffix_file[suff]
コード例 #10
0
ファイル: response.py プロジェクト: mmasata/miniweb
    def type(self, mime):
        """
        Set MIME type to Response.
        :param mime: Response data type.
        :return: self
        """

        log.debug("Response type was set to {m}.".format(m=mime))
        self.mime = mime
        return self
コード例 #11
0
ファイル: response.py プロジェクト: mmasata/miniweb
    def status(self, status):
        """
        Set HTTP status to Response.
        :param status: HTTP status code.
        :return: self
        """

        log.debug("Response status was set to {s}.".format(s=status))
        self.stat = status
        return self
コード例 #12
0
ファイル: request.py プロジェクト: mmasata/miniweb
    async def parse_content(self, data):
        """
        Accept Content-Data and parse them to object. Object is stored to Request class.
        :param data: Incoming Content-Data
        :return: None
        """

        log.debug("Content data: \r\n"+data)
        try:
            self.content = get_content(data, self.headers["Content-Type"])
        except ContentTypeException:
            log.error("Error in parsing Content-Type!")
コード例 #13
0
ファイル: route.py プロジェクト: mmasata/miniweb
    def is_match(self, path):
        try:
            destination_file = path.replace(self.file_path, self.root, 1)

            log.info("Looking for static file.")
            log.debug("File destination path should be {df}.".format(
                df=destination_file))

            self.file = open(destination_file)
            self.mime = get_mime_by_suffix(destination_file)
            return True
        except:
            log.debug("Match with static route was not found.")
            return False
コード例 #14
0
ファイル: request.py プロジェクト: mmasata/miniweb
    async def __find_query_params(self, full_path):
        if "?" in full_path:
            log.debug("Parsing query params.")

            self.params = {}
            self.path, q_par_str = full_path.split("?", 1)

            q_par_arr = q_par_str.split("&")
            for par in q_par_arr:
                key, value = par.split("=")
                self.params[key] = value

                log.debug("Query param\n {k}: {v}".format(k=key, v=value))
        else:
            self.path = full_path
コード例 #15
0
def validate_consumes(mime, req, res):
    """
    Validate incoming Content-Type.
    :param mime: Mime type which route can accept.
    :param req: HTTP request wrapped inside of Request class.
    :param res:  Response class which will define HTTP response.
    :return: Boolean of success/fail.
    """

    log.info("Validate consumes.")
    if (mime is None) or (req.headers["Content-Type"] in mime):
        log.debug("Consumes middleware was suceed.")
        return True
    else:
        log.warning("Consumes middleware failed!")
        res.type("text/html").entity(consume_error(
            req.headers["Content-Type"])).status(400).build()
        return False
コード例 #16
0
def validate(controller, req, res):
    """
    Validate incoming HTTP request - run middleware function.
    :param controller: Group router to group and define path. (optional parameter)
    :param req: HTTP request wrapped inside of Request class.
    :param res: Response class which will define HTTP response.
    :return: Boolean of success/fail.
    """

    log.info("Validate middlewares.")
    if not check_filters_group(global_filter, req, res):
        return False

    if controller is not None:
        if not check_filters_group(controller.filters, req, res):
            return False

    log.debug("Middleware function was suceed.")
    return True
コード例 #17
0
ファイル: route.py プロジェクト: mmasata/miniweb
    def get_path_params(self, path):
        """
        Accept current path from HTTP request and try found path parameters.
        :param path: Incoming path from HTTP request.
        :return: path parameters in dictionary
        """

        params = None
        if len(self.param_keys) > 0:
            log.debug("Getting path variables from path.")

            params = {}
            split_path = path.split("/")
            slash_arr_size = len(self.num_slashes)

            for i in range(0, slash_arr_size):
                params[self.param_keys[i]] = split_path[self.num_slashes[i]]

        return params
コード例 #18
0
ファイル: server.py プロジェクト: mmasata/miniweb
    async def __send_data(self, res, writer):
        log.debug("Sending response data")

        d_type = res.ent.__class__.__name__
        if d_type == "TextIOWrapper":
            log.debug("Sending file/s.")

            b_arr = bytearray(self.config.buffer)
            while True:
                data = res.ent.readinto(b_arr)

                if not data:
                    break
                await writer.awrite(b_arr, 0, data)

        elif d_type == "dict":
            log.debug("Dumps dictionary to JSON string and sending to client.")

            json_str = ujson.dumps(res.ent)
            await writer.awrite(json_str)

        else:
            await writer.awrite(res.ent)
コード例 #19
0
ファイル: server.py プロジェクト: mmasata/miniweb
 async def __close_connection(self, writer):
     log.debug("Closing communication with client.")
     await writer.aclose()
コード例 #20
0
ファイル: server.py プロジェクト: mmasata/miniweb
    async def __send_headers(self, res, writer):
        log.debug("Sending response headers.")

        await writer.awrite("HTTP/1.1 " + str(res.stat) + "\r\n")
        await writer.awrite("Content-Type: " + res.mime + "\r\n\r\n")
コード例 #21
0
ファイル: server.py プロジェクト: mmasata/miniweb
 async def __stop(self):
     log.debug(
         "Miniweb server will be stopped in {t}ms.".format(t=self.delay))
     await asyncio.sleep_ms(self.delay)
     self.e_loop.stop()
     log.info("Miniweb has been stopped.")