Skip to content

Instantly share code, notes, and snippets.

@meyt
Last active April 13, 2023 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meyt/cd4d89a396b5b46960d5f839671678ae to your computer and use it in GitHub Desktop.
Save meyt/cd4d89a396b5b46960d5f839671678ae to your computer and use it in GitHub Desktop.
Measure HTTP request and response time in Python
import socks
from time import time
from dataclasses import dataclass
from http.client import HTTPConnection, HTTPSConnection, HTTPResponse
from urllib.parse import urlparse
USER_AGENT = (
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/112.0.0.0 Safari/537.36"
)
class TimedHTTPResponse(HTTPResponse):
_statusts = None
def _read_status(self, *args, **kwargs):
r = super()._read_status(*args, **kwargs)
if self._statusts is None: # in case of HTTP:100
self._statusts = time()
return r
@dataclass
class HttpResult:
response: HTTPResponse
body: bytes
time_request: float
time_startresponse: float
time_download: float
def httpcall(
url,
method="get",
socks5=None,
headers=None,
body=None,
useragent=None,
debuglevel=0,
):
method = method.upper()
url = urlparse(url)
path = url.path
if not path:
path = "/"
elif url.query:
path = f"{path}?{url.query}"
_headers = {"user-agent": useragent or USER_AGENT}
if headers is not None:
_headers.update(headers)
# create connection
conn_cls = HTTPSConnection if url.scheme == "https" else HTTPConnection
if socks5:
proxy_host, proxy_port = socks5.split(":")
proxy_port = int(proxy_port)
conn = conn_cls(proxy_host, proxy_port)
conn.set_tunnel(url.netloc, url.port)
conn.sock = socks.socksocket()
conn.sock.set_proxy(socks.PROXY_TYPE_SOCKS5, proxy_host, proxy_port)
conn.sock.connect((url.netloc, url.port))
else:
conn = conn_cls(url.netloc)
conn.response_class = TimedHTTPResponse
conn.set_debuglevel(debuglevel)
ts1 = time()
# send request
conn.request(method, path, headers=_headers, body=body)
ts2 = time()
# get response
res = conn.getresponse()
body = res.read()
ts3 = time()
return HttpResult(
time_request=ts2 - ts1,
time_startresponse=res._statusts - ts2,
time_download=ts3 - res._statusts,
response=res,
body=body,
)
"""
Usage:
r = httpcall("http://httpbin.org/get")
print(
r.time_request,
r.time_startresponse,
r.time_download,
r.response.status,
r.response.reason,
r.body,
)
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment