Skip to content

Instantly share code, notes, and snippets.

@bendem
Created May 4, 2026 12:45
Show Gist options
  • Select an option

  • Save bendem/e6949e2c42b035c8218a8394562b635c to your computer and use it in GitHub Desktop.

Select an option

Save bendem/e6949e2c42b035c8218a8394562b635c to your computer and use it in GitHub Desktop.
import ctypes
import ctypes.wintypes
class WinhttpAutoproxyOptions(ctypes.Structure):
_fields_ = [
("dwFlags", ctypes.wintypes.DWORD),
("dwAutoDetectFlags", ctypes.wintypes.DWORD),
("u", ctypes.wintypes.LPCWSTR),
("r", ctypes.c_void_p),
("d", ctypes.wintypes.DWORD),
("fAutoLogonIfChallenged", ctypes.wintypes.BOOL),
]
class WinhttpProxyInfo(ctypes.Structure):
_fields_ = [
("dwAccessType", ctypes.wintypes.DWORD),
("lpszProxy", ctypes.wintypes.LPWSTR),
("lpszProxyBypass", ctypes.wintypes.LPWSTR),
]
def proxy_for(url: str) -> str:
h = w.WinHttpOpen("py", 1, None, None, 0)
winhttp_autoproxy_options = WinhttpAutoproxyOptions(
1, 3, None, None, 0, True
) # AUTO_DETECT | DHCP+DNS
winhttp_proxy_info = WinhttpProxyInfo()
ok = w.WinHttpGetProxyForUrl(
h,
url,
ctypes.byref(winhttp_autoproxy_options),
ctypes.byref(winhttp_proxy_info),
)
w.WinHttpCloseHandle(h)
if ok and winhttp_proxy_info.lpszProxy:
return winhttp_proxy_info.lpszProxy
return "DIRECT"
if __name__ == "__main__":
import sys
w = ctypes.WinDLL("winhttp", use_last_error=True)
w.WinHttpOpen.restype = ctypes.wintypes.HANDLE
w.WinHttpGetProxyForUrl.argtypes = (
ctypes.wintypes.HANDLE, # hSession
ctypes.wintypes.LPCWSTR, # lpcwszUrl
ctypes.POINTER(WinhttpAutoproxyOptions), # pAutoProxyOptions
ctypes.POINTER(WinhttpProxyInfo), # pProxyInfo
)
w.WinHttpGetProxyForUrl.restype = ctypes.wintypes.BOOL
w.WinHttpCloseHandle.argtypes = (ctypes.wintypes.HANDLE,)
w.WinHttpCloseHandle.restype = ctypes.wintypes.BOOL
print(proxy_for(sys.argv[1]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment