import http.server,http.client,socketserver,select,socket,urllib.parse,threading,datetime,gzip
LOG=open('proxy.log','a',buffering=1)
class H(http.server.BaseHTTPRequestHandler):
    protocol_version='HTTP/1.1'
    def log_message(self,*a): pass
    def _fwd(self,method):
        url=self.path
        u=urllib.parse.urlparse(url)
        if not u.hostname:
            self.send_error(400); return
        body=None
        if method=='POST':
            n=int(self.headers.get('Content-Length') or 0); body=self.rfile.read(n)
        try:
            c=http.client.HTTPConnection(u.hostname,u.port or 80,timeout=15)
            hdrs={k:v for k,v in self.headers.items() if k.lower() not in ('proxy-connection','host','content-length')}
            if u.hostname=='gcaptcha4.geetest.com':
                for k in list(hdrs):
                    if k.lower() in ('referer','origin'): del hdrs[k]
                hdrs['Referer']='http://ein38eu95792b.4656hd15.cc/'
                hdrs['Origin']='http://ein38eu95792b.4656hd15.cc'
            path=u.path+('?'+u.query if u.query else '')
            c.request(method,path,body=body,headers=hdrs)
            r=c.getresponse(); data=r.read()
            if 'verify' in url or 'load' in url:
                enc=r.getheader('Content-Encoding') or ''
                try:
                    dec=gzip.decompress(data) if 'gzip' in enc else data
                except Exception:
                    dec=data
                if 'verify' in url:
                    LOG.write(f'=== {datetime.datetime.now()} {method} {url}\nSTATUS {r.status}\nRESP {dec[:4000]!r}\n')
                else:
                    LOG.write(f'=== {datetime.datetime.now()} LOAD {url[:160]} STATUS {r.status} LEN {len(data)}\n')
            self.send_response(r.status)
            for k,v in r.getheaders():
                if k.lower() not in ('transfer-encoding','connection','content-length'): self.send_header(k,v)
            self.send_header('Content-Length',str(len(data))); self.end_headers(); self.wfile.write(data)
        except Exception as e:
            LOG.write(f'ERR {url[:120]} {e}\n'); self.send_error(502)
    def do_GET(self): self._fwd('GET')
    def do_POST(self): self._fwd('POST')
    def do_CONNECT(self):
        host,port=self.path.split(':'); port=int(port)
        try:
            s=socket.create_connection((host,port),timeout=10)
            self.send_response(200,'Connection Established'); self.end_headers()
            self.connection.setblocking(False); s.setblocking(False)
            while True:
                r,_,_=select.select([self.connection,s],[],[],30)
                if not r: break
                for src in r:
                    data=src.recv(65536)
                    if not data: return
                    (s if src is self.connection else self.connection).sendall(data)
        except Exception: pass
class S(socketserver.ThreadingMixIn,http.server.HTTPServer): daemon_threads=True
S(('127.0.0.1',8081),H).serve_forever()
