Skip to content

Instantly share code, notes, and snippets.

@akhil-reni
Last active March 4, 2022 08:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save akhil-reni/5c20f40729179858570ad1ffdf4502f3 to your computer and use it in GitHub Desktop.
Save akhil-reni/5c20f40729179858570ad1ffdf4502f3 to your computer and use it in GitHub Desktop.
Raw HTTP Request parser
from __future__ import absolute_import, unicode_literals
from http.server import BaseHTTPRequestHandler
from io import BytesIO
from urllib import parse
class Request:
def __init__(self):
self.headers = None
self.params = None
self.data = None
self.path = None
def replace(self, string, payload):
for k, v in self.headers.items():
k.replace(string, payload)
v.replace(string, payload)
for k, v in self.params.items():
self.params[k] = self.params[k].replace(string, payload)
for k, v in self.data.items():
self.data[k] = self.data[k].replace(string, payload)
print(self.data)
class RequestParser(object):
def __init__(self, request_text):
self.request = Request()
try:
self.raw_request = HTTPRequest(request_text)
if self.raw_request.error_code:
raise Exception("failed parsing request")
self.request.method = self.raw_request.command
self.request.path = self.construct_path()
self.request.headers = self.raw_request.headers
self.request.data = self.convert(self.construct_data())
self.request.params = self.convert(self.construct_params())
except Exception as e:
raise e
def convert(self, data):
if isinstance(data, bytes):
return data.decode()
if isinstance(data, (str, int)):
return str(data)
if isinstance(data, dict):
return dict(map(self.convert, data.items()))
if isinstance(data, tuple):
return tuple(map(self.convert, data))
if isinstance(data, list):
return list(map(self.convert, data))
if isinstance(data, set):
return set(map(self.convert, data))
def construct_path(self):
return parse.urlsplit(self.raw_request.path).path
def construct_data(self):
return dict(parse.parse_qsl(self.raw_request.rfile.read(int(self.raw_request.headers.get('content-length')))))
def construct_params(self):
return dict(parse.parse_qsl(parse.urlsplit(self.raw_request.path).query))
with open("requests.txt", "rb") as f:
parser = RequestParser(f.read())
print(parser.request.method) # prints method
print(parser.request.path) # prints request.path
print(parser.request.headers) # prints requests headers
print(parser.request.data) # prints requests body
print(parser.request.params) # prints requests params
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment