zoukankan      html  css  js  c++  java
  • 更新Sogou代理服务器程序,支持HTTPS

    更新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)  
  • 相关阅读:
    漫谈递归转非递归
    (转)程序猿面试需要的知识点总结
    LeetCode:4_Median of Two Sorted Arrays | 求两个排序数组的中位数 | Hard
    LeetCode: 3_Longest Substring Without Repeating Characters | 求没有重复字符的最长子串的长度 | Medium
    LeetCode: 221_Maximal Square | 二维0-1矩阵中计算包含1的最大正方形的面积 | Medium
    LeetCode: 2_Add Two Numbers | 两个链表中的元素相加 | Medium
    算法导论第十五章 动态规划
    AVL树探秘
    算法导论第十四章 数据结构的扩张
    算法导论第十三章 红黑树
  • 原文地址:https://www.cnblogs.com/lexus/p/2814652.html
Copyright © 2011-2022 走看看