I would like to replay an arbitrary raw HTTP request in python. As an example, lets use an arbitrary GET request from my chromium browser to Google:
GET / HTTP/1.1
Host: google.de
Cookie: CONSENT=PENDING+071; AEC=ARSKqsKvfEvPS9Vp1bDM6YMPdHpVOoH357W-7q3cqtdDwYeHf3MqPEO1xA; SOCS=CAISHAgBEhJnd3NfMjAyMzAyMjMtMF9SQzEaAmRlIAEaBgiAn-WfBg; NID=511=N6YvXcWd_hnVVnV8w6JK4jscqE2pEt8MuTrw3yZJp-84ZxV6RJLee_yj2DEo2UJuOse0sqLjdnAD7qgPw9al7aEJqsQOCAQPIs21rLy5HQ5IAoObj7icI7ayKJttejI9Va2jDFkk0ZLvUC7P_VPJuxRJyhvLspqU1YVUcYCThrYizbo; 1P_JAR=2023-2-25-20
Sec-Ch-Ua: "Not A(Brand";v="24", "Chromium";v="110"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
X-Client-Data: CO3/ygE=
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
Since I want my request to look exactly like the above, an obvious way would be to use the socket library:
def send(host, port, message):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, port))
s.sendall(message)
print("%s" % message.decode('us-ascii'))
data = s.recv(1024)
print("%s" % data)
However, that way, I obviously can't use TLS or proxies (without writing my own libraries).
So, I thought the request library could be worth a try since it already supports TLS and proxies out of the box. But I can't figure out how to load my HTTP request that I want to replay. I suppose the library was not designed for that.
I could try something like this (from the docs):
from requests import Request, Session
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = req.prepare()
# do something with prepped.body
prepped.body = 'No, I want exactly this as the body.'
# do something with prepped.headers
del prepped.headers['Content-Type']
resp = s.send(prepped,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout
)
print(resp.status_code)
but I still would have to first parse the headers of my request manually. If there a library that takes care of that?
Thanks for your input!