Skip to content

Instantly share code, notes, and snippets.

@sethmlarson
Last active February 14, 2022 14:00
Show Gist options
  • Save sethmlarson/034f8e3aa30f3d05f720676db391d5e4 to your computer and use it in GitHub Desktop.
Save sethmlarson/034f8e3aa30f3d05f720676db391d5e4 to your computer and use it in GitHub Desktop.
HTTP client on a business card
import asyncio as A,urllib.parse as U,re;B,C,I,S=b"",b"\r\n",int,lambda*A:re.match(*A,24).groups()
async def request(m,u,h,b):
s,_,a,_,q,_=z=U.urlparse(u);T,E,d,N=s!=b"http",0,B,z.hostname;r,w=await A.open_connection(N,I(z.port or 80+363*T),ssl=T,server_hostname=[None,N][T]);w.write(m+b" "+(a or b"/")+[b"?"+q,B][q==B]+b" HTTP/1.0"+C+C.join([b"%b:%b"%W for W in h]+[B,b]));await w.drain()
while c:=await r.read():
if C*2in(d:=d+c)*(E==0):E,d=d.split(C*2,1);t,o=S(b"HTTP/.+? (\d+).*?%b(.*)"%C,E);o=[S(rb"([^\s]+):\s*(.+?)\s*$",x)for x in o.split(C)]
w.close();return I(t),o,d
@Guerteltier
Copy link

Guerteltier commented Feb 11, 2022

@sethmlarson server_hostname isn't needed and urllib.parse.ParseResultBytes.port is already int.

import asyncio as A,urllib.parse as U,re;B,C,I,S=b"",b"\r\n",int,lambda*A:re.match(*A,24).groups()
async def request(m,u,h,b):
 s,_,a,_,q,_=z=U.urlparse(u);T,E,d=s!=b"http",0,B;r,w=await A.open_connection(z.hostname,z.port or 80+363*T,ssl=T);w.write(m+b" "+(a or b"/")+[b"?"+q,B][q==B]+b" HTTP/1.0"+C+C.join([b"%b:%b"%W for W in h]+[B,b]));await w.drain()
 while c:=await r.read():
  if C*2in(d:=d+c)*(E==0):E,d=d.split(C*2,1);t,o=S(b"HTTP/.+? (\d+).*?%b(.*)"%C,E);o=[S(rb"([^\s]+):\s*(.+?)\s*$",x)for x in o.split(C)]
 w.close();return I(t),o,d

@Guerteltier
Copy link

Additionally s,_,a,q,_=z=U.urlsplit(u) can be used instead of s,_,a,_,q,_=z=U.urlparse(u).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment