summaryrefslogtreecommitdiff
path: root/day7/utils.py
diff options
context:
space:
mode:
authorAndrew <saintruler@gmail.com>2019-05-24 16:29:03 +0400
committerAndrew <saintruler@gmail.com>2019-05-24 16:29:03 +0400
commit0f0e815ad1b775ff93699b695f290c562c57962f (patch)
tree2d41e2d3b3ede86b6fb18a176b201920d6681dfa /day7/utils.py
parent402d0d2b9ebd76b8e99eddceeb85c4a66030b51b (diff)
Модули для обработки http-запросов, базовый обработчик url-путей. Обертка для работы с shelve базами данных, html-шаблонизатор.
Diffstat (limited to 'day7/utils.py')
-rw-r--r--day7/utils.py91
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()