diff options
| author | Andrew <saintruler@gmail.com> | 2019-05-24 16:29:03 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2019-05-24 16:29:03 +0400 |
| commit | 0f0e815ad1b775ff93699b695f290c562c57962f (patch) | |
| tree | 2d41e2d3b3ede86b6fb18a176b201920d6681dfa /day7/utils.py | |
| parent | 402d0d2b9ebd76b8e99eddceeb85c4a66030b51b (diff) | |
Модули для обработки http-запросов, базовый обработчик url-путей. Обертка для работы с shelve базами данных, html-шаблонизатор.
Diffstat (limited to 'day7/utils.py')
| -rw-r--r-- | day7/utils.py | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/day7/utils.py b/day7/utils.py new file mode 100644 index 0000000..0aa0709 --- /dev/null +++ b/day7/utils.py @@ -0,0 +1,91 @@ +import re +from time import strftime, gmtime + +_URI_RESERVED = { + '21': '!', '23': '#', '24': '$', '26': '&', + '27': '\'', '28': '(', '29': ')', '2A': '*', + '2B': '+', '2C': ',', '2F': '/', '3A': ':', + '3B': ';', '3D': '=', '3F': '?', '40': '@', + '5B': '[', '5D': ']' +} + +BAD_REQUEST = 'HTTP/1.1 400 Bad Request' +NOT_FOUND = 'HTTP/1.1 404 Not Found' +SUCCESS = 'HTTP/1.1 200 OK' +METHOD_NOT_ALLOWED = 'HTTP/1.1 405 Method Not Allowed' + + +def add_headers(status, html: str): + return '\r\n'.join([ + status, + f'Date: {strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime())}', + 'Server: BrandNewServer', + 'Content-Type: text/html; charset=utf-8', + 'Connection: keep-alive', + '', html + ]) + + +def validate_url(url): + url_pattern = re.compile(r'/((.*?/?)+)?') + return bool(url_pattern.fullmatch(url)) + + +def parse_cookies(cookies_line: str): + cookies_line = cookies_line.strip().strip(';') + pairs = cookies_line.split(';') + d = {} + for pair in pairs: + try: + key, value = pair.split('=', maxsplit=1) + d[key] = value + except ValueError: + raise ValueError('Wrong format of cookies') + + return d + + +def parse_headers(request_line: str): + request = request_line.split('\r\n') + method, url, http_ver = request.pop(0).split() + headers = {} + for line in request: + field, value = line.split(': ', maxsplit=1) + headers[field] = value + + return method, url, http_ver, headers + + +def parse_query(query_line: str): + pairs = query_line.strip().split('&') + d = {} + for pair in pairs: + try: + key, value = pair.split('=', maxsplit=1) + d[url_decoder(key)] = url_decoder(value) + except ValueError: + raise ValueError('Wrong format of query') + + return d + + +def url_decoder(url_line: str): + url_line = url_line.replace('+', ' ') + encoded = b'' + i = 0 + while i < len(url_line): + if url_line[i] == '%': + hex_value = url_line[i + 1: i + 3] + if hex_value in _URI_RESERVED: + integer = ord(_URI_RESERVED[hex_value]) + else: + integer = int(hex_value, 16) + + encoded += bytes([integer]) + i += 3 + continue + else: + encoded += bytes([ord(url_line[i])]) + i += 1 + + return encoded.decode() |