diff options
Diffstat (limited to 'day9/task5_vue/backend/utils.py')
| -rw-r--r-- | day9/task5_vue/backend/utils.py | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/day9/task5_vue/backend/utils.py b/day9/task5_vue/backend/utils.py new file mode 100644 index 0000000..c1b3a04 --- /dev/null +++ b/day9/task5_vue/backend/utils.py @@ -0,0 +1,131 @@ +from io import BytesIO + + +CHUNK_SIZE = 49600 + +HTTP_STATUS_CODES = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi Status", + 226: "IM Used", # see RFC 3229 + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", # unused + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", # see RFC 2324 + 421: "Misdirected Request", # see RFC 7540 + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 426: "Upgrade Required", + 428: "Precondition Required", # see RFC 6585 + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 449: "Retry With", # proprietary MS extension + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 507: "Insufficient Storage", + 510: "Not Extended", +} + +SUCCESS_CODE = 200 +BAD_REQUEST_CODE = 400 +NOT_FOUND_CODE = 404 +METHOD_NOT_ALLOWED_CODE = 405 + + +def render_template(path, **kwargs): + with open(path, encoding='utf-8') as f: + template = f.read() + + for key in kwargs: + template = template.replace(f'%%{key}%%', kwargs[key]) + + return template + + +def parse_multipart_form(data: bytes): + b = BytesIO(data) + separator = b.readline().strip() + + files = [] + + while True: + line = b.readline().strip().strip(b'-') + if not line: + break + + headers_raw = [] + while not line.strip() == b'': + headers_raw.append(line.strip().decode()) + line = b.readline() + + headers = {'Content-Type': headers_raw[1].split(': ')[1]} + for pair in headers_raw[0].split(': ')[1].split('; ')[1:]: + key, value = pair.split('=') + headers[key] = value[1:-1] + + data = b'' + prev_chunk = b.read(CHUNK_SIZE) + chunk = b.read(CHUNK_SIZE) + while separator not in (prev_chunk + chunk): + data += prev_chunk + prev_chunk = chunk + chunk = b.read(CHUNK_SIZE) + + if not chunk: + break + + chunk = (prev_chunk + chunk) + if chunk.startswith(separator) or chunk.endswith(separator): + with_sep = chunk.strip(separator) + else: + if separator in chunk: + with_sep, buffer = chunk.split(separator) + b = BytesIO(buffer + b.read()) + b.readline() + + else: + with_sep = chunk + + data += with_sep + headers['data'] = data + + files.append(headers) + + return files |