浙江省高等学校教师教育理论培训

微信搜索“毛凌志岗前心得”小程序

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

更新Sogou代理服务器程序,支持HTTPS « Xiaoxia[PG]

更新Sogou代理服务器程序,支持HTTPS

这个是对之前用Python写的一个Sogou本地代理服务器的更新版本,新版本支持了HTTPS连接,实现了CONNECT请求。
我发现,Sogou上的squid服务器,限制了CONNECT命令只能够连接远程主机的443端口,其他的端口都返回403 Forbidden状态。

教育网的用户,可以使用我在学校建立的HTTP代理,scut.tk:1998。支持IPv4和IPv6的访问。

Windows Binary 下载

sogou.zip (Win32, IPv4)

上代码:

  1. ''''' 
  2.     Author:  Xiaoxia 
  3.     Contact: xiaoxia@xiaoxia.org 
  4.     Website: xiaoxia.org 
  5. '''  
  6.   
  7. from threading import Thread, Lock  
  8. from struct import unpack  
  9. from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer  
  10. from httplib import HTTPResponse  
  11. from SocketServer import ThreadingMixIn  
  12. import socket, os, select  
  13. import time, sys, random  
  14. import threading  
  15.   
  16. # Minimize Memory Usage  
  17. threading.stack_size(128*1024)  
  18.   
  19. x_sogou_auth = "9CD285F1E7ADB0BD403C22AD1D545F40/30/853edc6d49ba4e27"  
  20. proxy_host = "h0.edu.bj.ie.sogou.com"  
  21. proxy_port = 80  
  22. BufferSize = 8192  
  23. RemoteTimeout = 15  
  24.   
  25. def calc_sogou_hash(t, host):  
  26.     s = (t + host + 'SogouExplorerProxy').encode('ascii')  
  27.     code = len(s)  
  28.     dwords = int(len(s)/4)  
  29.     rest = len(s) % 4  
  30.     v = unpack(str(dwords) + 'i'+str(rest)+'s', s)  
  31.     for vv in v:  
  32.         if(type(vv)==type('i')):  
  33.             break  
  34.         a = (vv & 0xFFFF)  
  35.         b = (vv >> 16)  
  36.         code += a  
  37.         code = code ^ (((code<<5)^b) << 0xb)  
  38.         # To avoid overflows  
  39.         code &= 0xffffffff  
  40.         code += code >> 0xb  
  41.     if rest == 3:  
  42.         code += ord(s[len(s)-2]) * 256 + ord(s[len(s)-3])  
  43.         code = code ^ ((code ^ (ord(s[len(s)-1])*4)) << 0x10)  
  44.         code &= 0xffffffff  
  45.         code += code >> 0xb  
  46.     elif rest == 2:  
  47.         code += ord(s[len(s)-1]) * 256 + ord(s[len(s)-2])  
  48.         code ^= code << 0xb  
  49.         code &= 0xffffffff  
  50.         code += code >> 0x11  
  51.     elif rest == 1:  
  52.         code += ord(s[len(s)-1])  
  53.         code ^= code << 0xa  
  54.         code &= 0xffffffff  
  55.         code += code >> 0x1  
  56.     code ^= code * 8  
  57.     code &= 0xffffffff  
  58.     code += code >> 5  
  59.     code ^= code << 4  
  60.     code = code & 0xffffffff  
  61.     code += code >> 0x11  
  62.     code ^= code << 0x19  
  63.     code = code & 0xffffffff  
  64.     code += code >> 6  
  65.     code = code & 0xffffffff  
  66.     return hex(code)[2:].rstrip('L').zfill(8)  
  67.   
  68. class Handler(BaseHTTPRequestHandler):  
  69.     remote = None  
  70.       
  71.     # Ignore Connection Failure  
  72.     def handle(self):  
  73.         try:  
  74.             BaseHTTPRequestHandler.handle(self)  
  75.         except socket.error: pass  
  76.     def finish(self):  
  77.         try:  
  78.             BaseHTTPRequestHandler.finish(self)  
  79.         except socket.error: pass  
  80.       
  81.     # CONNECT Data Transfer  
  82.     def transfer(self, a, b):  
  83.         fdset = [a, b]  
  84.         while True:  
  85.             r,w,e = select.select(fdset, [], [])  
  86.             if a in r:  
  87.                 data = a.recv(BufferSize)  
  88.                 if not data: break  
  89.                 b.sendall(data)  
  90.             if b in r:  
  91.                 data = b.recv(BufferSize)  
  92.                 if not data: break  
  93.                 a.sendall(data)  
  94.       
  95.     def sogouProxy(self):  
  96.         if self.remote is None or self.lastHost != self.headers["Host"]:  
  97.             self.remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
  98.             self.remote.settimeout(RemoteTimeout)  
  99.             self.remote.connect((proxy_host, proxy_port))  
  100.         self.remote.sendall(self.requestline.encode('ascii') + b"\r\n")  
  101.         # Add Sogou Verification Tags  
  102.         self.headers["X-Sogou-Auth"] = x_sogou_auth  
  103.         t = hex(int(time.time()))[2:].rstrip('L').zfill(8)  
  104.         self.headers["X-Sogou-Tag"] = calc_sogou_hash(t, self.headers['Host'])  
  105.         self.headers["X-Sogou-Timestamp"] = t  
  106.         headerstr = str(self.headers).replace("\r\n""\n").replace("\n""\r\n")  
  107.         self.remote.sendall(headerstr.encode('ascii') + b"\r\n")  
  108.         # Send Post data  
  109.         if self.command == 'POST':  
  110.             self.remote.sendall(self.rfile.read(int(self.headers['Content-Length'])))  
  111.         response = HTTPResponse(self.remote, method=self.command)  
  112.         response.begin()  
  113.           
  114.         # Reply to the browser  
  115.         status = "HTTP/1.1 " + str(response.status) + " " + response.reason  
  116.         self.wfile.write(status.encode('ascii') + b'\r\n')  
  117.         hlist = []  
  118.         for line in response.msg.headers: # Fixed multiple values of a same name  
  119.             if 'TRANSFER-ENCODING' not in line.upper():  
  120.                 hlist.append(line)  
  121.         self.wfile.write("".join(hlist) + b'\r\n')  
  122.           
  123.         if self.command == "CONNECT" and response.status == 200:  
  124.             return self.transfer(self.remote, self.connection)  
  125.         else:  
  126.             while True:  
  127.                 response_data = response.read(BufferSize)  
  128.                 if not response_data: break  
  129.                 self.wfile.write(response_data)  
  130.       
  131.     do_POST = do_GET = do_CONNECT = sogouProxy  
  132.   
  133. class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):   
  134.     address_family = socket.AF_INET6  
  135.   
  136. server_address = ("", 1998)  
  137. server = ThreadingHTTPServer(server_address, Handler)  
  138. # Random Target Proxy Server  
  139. proxy_host = 'h' + str(random.randint(0,5)) + '.edu.bj.ie.sogou.com'  
  140.   
  141. print('Proxy over %s.\nPlease set your browser\'s proxy to %s.' % (proxy_host, server_address))  
  142. try:  
  143.     server.serve_forever()  
  144. except:  
  145.     os._exit(1)  
posted on 2012-12-12 14:58  lexus  阅读(574)  评论(0编辑  收藏  举报