http代理的脚本http_proxy.py
生活随笔
收集整理的這篇文章主要介紹了
http代理的脚本http_proxy.py
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
#!/usr/bin/env python# Copyright (C) 2010, Adam Fourney <afourney@cs.uwaterloo.ca> # # This file is part of Adaptable GIMP # # Adaptable GIMP is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # import sys, subprocess, socket, os, errno, random, hashlib, time, reif sys.platform == 'win32':from threading import Threadimport arrayclass Value:def __init__(self, typecode, arg):self.__arr = array.array(typecode, [arg])def getv(self):return self.__arr[0]def setv(self, val):self.__arr[0] = valvalue = property(getv, setv)else:from multiprocessing import Process, Value# CONSTANTS PROXY_TO = 'www.uwaterloo.ca' HOST = '127.0.0.1' PREFERRED_PORT = 8080 HEARTBEAT_PERIOD = 15 APPLICATION = './gimp-2.6.exe' if sys.platform == 'win32' else './gimp-2.6'#####################################################################def main():thread_q = []shutdown = Value('i', 0)is_online = Value('i', 1) # Set up the sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# Try finding a free port to listen on. # Stop after 10 tries.tries = 10port = PREFERRED_PORTwhile (tries > 0):tries = tries - 1try:s.bind((HOST, port))s.listen(5)print "Listening on port {0}".format(port)breakexcept socket.error, (err, msg):if (tries == 0):raiseelif (err == errno.EADDRINUSE):port = random.randint(1024, 49151)continueelse:raise# Set socket timeouts.settimeout(0.5)# Spawn the heartbeatheartbeat_thread = spawn_best_thread(target=start_heartbeat, args=(shutdown,is_online))heartbeat_thread.start()# Spawn our processapp_thread = spawn_best_thread(target=spawn_app, args=(shutdown,port))app_thread.start()# Handle incoming connectionswhile shutdown.value == 0:# Poll the children and reap zombiesnew_q = []for p in thread_q:if p.is_alive():new_q.append(p)thread_q = new_q# Accept a new connection try:conn, addr = s.accept()except socket.timeout:continueexcept socket.error, err:if (err == errno.EINTR):continueelse:raise# Service the request in a new threadconn.settimeout(None)p = spawn_best_thread(target=service_request, args=(conn,is_online))thread_q.append(p)p.start()s.close()#####################################################################def spawn_best_thread(target, args):if sys.platform == 'win32':return Thread(target=target, args=args)else:return Process(target=target, args=args)#####################################################################def start_heartbeat(shutdown, is_online):sleep_for = 0while shutdown.value == 0:# Sleep for half a second at a time to allow for checking of the# shutdown condition.if (sleep_for > 0):time.sleep(0.5)sleep_for = sleep_for - 0.5continue# Do actual workstart_time = time.clock()previous_status = is_online.valuenew_status = previous_statustry:client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.settimeout(HEARTBEAT_PERIOD)client.connect((PROXY_TO, 80))client.sendall("HEAD / HTTP/1.1\r\nHost: {0}\r\nConnection: close\r\n\r\n".format(PROXY_TO))response = ""while 1:data = client.recv(1024)if not data:breakresponse += dataif re.search('^HTTP\/\d\.\d\s+200\s+OK', response):new_status = 1else:new_status = 0except socket.error: new_status = 0except socket.timeout: new_status = 0# Shutdown and close the connection, but report no errorstry: client.shutdown(socket.SHUT_RDWR);except socket.error: passtry: client.close()except socket.error: passif new_status != previous_status:print "Connection status changed. Now {0}".format('Online' if new_status else 'Offline') is_online.value = new_status# Arrange to sleep a littlesleep_for = HEARTBEAT_PERIOD - (time.clock() - start_time)#####################################################################def service_request(conn, is_online):# Read the request, respond and exit.request= ""while 1:data = conn.recv(1024)if not data:breakrequest += data# Requests are terminated by the following sequencepos = request.find("\r\n\r\n")if (pos > -1):data = data[0:pos+4]break response = make_request(request, is_online)conn.sendall(response)try:conn.shutdown(socket.SHUT_RDWR);except socket.error:passconn.close()#####################################################################def make_request(data, is_online):# Split the request into lineslines = data.split("\r\n")if data.endswith("\r\n"):lines.pop()# Hash the first line of the request for use as a keyfirst_line = lines[0];key = hashlib.md5(first_line).hexdigest()# Check for special PROXY messagesif first_line == "PROXY GET STATUS":status_str = "Online" if is_online.value > 0 else "Offline"return "Status: {0}\r\n\r\n".format(status_str)# Exit early if we are offlineif is_online.value == 0:return read_from_cache(key)# Modify the request for proxyingdata = "";for line in lines:if line.startswith('Connection:'):data = data + 'Connection: close' + "\r\n"elif line.startswith('Host:'):data = data + 'Host: {0}'.format(PROXY_TO) + "\r\n"else: data = data + line + "\r\n"# Try to fetch from the server, but fall back on the cache if we're offline try:client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.settimeout(HEARTBEAT_PERIOD)client.connect((PROXY_TO, 80))client.sendall(data)except: return read_from_cache(key)# Read the responseresponse = ""while 1:data = client.recv(1024)if not data:breakresponse += dataclient.close()# Cache the response and returnwrite_to_cache(key, response)return response###################################################################### Read a response from the cache. Return 404 if there is a problem. def read_from_cache(key):try:f = open("web_cache/{0}.tmp".format(key), "r")f_data = f.read()f.close()except IOError as (errnum, strerror):if (errnum == errno.ENOENT):response = """HTTP/1.1 404 Not Found\r Content-Type: text/html\r Connection: close\r Content-Length: 78\r \r \r <HTML><HEAD><TITLE>404</TITLE></HEAD><BODY>Page Not Found: 404</BODY></HTML>"""return responseelse:raisereturn f_data ###################################################################### Write a response to the cache. Create a web_cache directory if required. def write_to_cache(key, response):if not os.path.isdir('web_cache'):os.mkdir('web_cache')f = open('web_cache/{0}.tmp'.format(key), 'w') f.write(response) f.close() ###################################################################### Spawn the main process def spawn_app(shutdown, port):os.environ['AGIMP_PROXY_PORT'] = str(port)subprocess.call([APPLICATION])shutdown.value = 1 ######## CALL MAIN ########if __name__ == '__main__':main()轉載于:https://my.oschina.net/u/1385797/blog/174017
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的http代理的脚本http_proxy.py的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【1489】求二叉树的先序遍历 SD
- 下一篇: speedtest-cli命令行下测试服