简单的proxy之TinyHTTPProxy.py
简单的proxy之TinyHTTPProxy.py
如果是在外企工作的话,可以访问美国的机器,这样就可以在美国的机器上为自己装个proxy,然后本地就可以很容易的使用proxy来上网了。
TinyHTTPProxy.py :
主页:http://www.voidtrance.net/2010/01/simple-python-http-proxy/
下载:http://www.voidtrance.net/downloads/tiny-proxy-0.3.1.tar.gz
使用方法:
1)很好用,下载然后在后台运行。只依赖于基本的python modules,运行的时候不需要root权限。
- proxy [-p port] [-l logfile] [-dh] [allowed_client_name ...]]
- -p - Port to bind to
- -l - Path to logfile. If not specified, STDOUT is used
- -d - Run in the background
2) Chrome中的switchsharper插件的配置:
TinyHTTPProxy.py的源代码:
- #!/usr/bin/python
- __doc__ = """Tiny HTTP Proxy.
- This module implements GET, HEAD, POST, PUT and DELETE methods
- on BaseHTTPServer, and behaves as an HTTP proxy. The CONNECT
- method is also implemented experimentally, but has not been
- tested yet.
- Any help will be greatly appreciated. SUZUKI Hisao
- 2009/11/23 - Modified by Mitko Haralanov
- * Added very simple FTP file retrieval
- * Added custom logging methods
- * Added code to make this a standalone application
- """
- __version__ = "0.3.1"
- import BaseHTTPServer, select, socket, SocketServer, urlparse
- import logging
- import logging.handlers
- import getopt
- import sys
- import os
- import signal
- import threading
- from types import FrameType, CodeType
- from time import sleep
- import ftplib
- DEFAULT_LOG_FILENAME = "proxy.log"
- class ProxyHandler (BaseHTTPServer.BaseHTTPRequestHandler):
- __base = BaseHTTPServer.BaseHTTPRequestHandler
- __base_handle = __base.handle
- server_version = "TinyHTTPProxy/" + __version__
- rbufsize = 0 # self.rfile Be unbuffered
- def handle(self):
- (ip, port) = self.client_address
- self.server.logger.log (logging.INFO, "Request from '%s'", ip)
- if hasattr(self, 'allowed_clients') and ip not in self.allowed_clients:
- self.raw_requestline = self.rfile.readline()
- if self.parse_request(): self.send_error(403)
- else:
- self.__base_handle()
- def _connect_to(self, netloc, soc):
- i = netloc.find(':')
- if i >= 0:
- host_port = netloc[:i], int(netloc[i+1:])
- else:
- host_port = netloc, 80
- self.server.logger.log (logging.INFO, "connect to %s:%d", host_port[0], host_port[1])
- try: soc.connect(host_port)
- except socket.error, arg:
- try: msg = arg[1]
- except: msg = arg
- self.send_error(404, msg)
- return 0
- return 1
- def do_CONNECT(self):
- soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- if self._connect_to(self.path, soc):
- self.log_request(200)
- self.wfile.write(self.protocol_version +
- " 200 Connection established\r\n")
- self.wfile.write("Proxy-agent: %s\r\n" % self.version_string())
- self.wfile.write("\r\n")
- self._read_write(soc, 300)
- finally:
- soc.close()
- self.connection.close()
- def do_GET(self):
- (scm, netloc, path, params, query, fragment) = urlparse.urlparse(
- self.path, 'http')
- if scm not in ('http', 'ftp') or fragment or not netloc:
- self.send_error(400, "bad url %s" % self.path)
- return
- soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- if scm == 'http':
- if self._connect_to(netloc, soc):
- self.log_request()
- soc.send("%s %s %s\r\n" % (self.command,
- urlparse.urlunparse(('', '', path,
- params, query,
- '')),
- self.request_version))
- self.headers['Connection'] = 'close'
- del self.headers['Proxy-Connection']
- for key_val in self.headers.items():
- soc.send("%s: %s\r\n" % key_val)
- soc.send("\r\n")
- self._read_write(soc)
- elif scm == 'ftp':
- # fish out user and password information
- i = netloc.find ('@')
- if i >= 0:
- login_info, netloc = netloc[:i], netloc[i+1:]
- try: user, passwd = login_info.split (':', 1)
- except ValueError: user, passwd = "anonymous", None
- else: user, passwd ="anonymous", None
- self.log_request ()
- try:
- ftp = ftplib.FTP (netloc)
- ftp.login (user, passwd)
- if self.command == "GET":
- ftp.retrbinary ("RETR %s"%path, self.connection.send)
- ftp.quit ()
- except Exception, e:
- self.server.logger.log (logging.WARNING, "FTP Exception: %s",
- e)
- finally:
- soc.close()
- self.connection.close()
- def _read_write(self, soc, max_idling=20, local=False):
- iw = [self.connection, soc]
- local_data = ""
- ow = []
- count = 0
- while 1:
- count += 1
- (ins, _, exs) = select.select(iw, ow, iw, 1)
- if exs: break
- if ins:
- for i in ins:
- if i is soc: out = self.connection
- else: out = soc
- data = i.recv(8192)
- if data:
- if local: local_data += data
- else: out.send(data)
- count = 0
- if count == max_idling: break
- if local: return local_data
- return None
- do_HEAD = do_GET
- do_POST = do_GET
- do_PUT = do_GET
- do_DELETE=do_GET
- def log_message (self, format, *args):
- self.server.logger.log (logging.INFO, "%s %s", self.address_string (),
- format % args)
- def log_error (self, format, *args):
- self.server.logger.log (logging.ERROR, "%s %s", self.address_string (),
- format % args)
- class ThreadingHTTPServer (SocketServer.ThreadingMixIn,
- BaseHTTPServer.HTTPServer):
- def __init__ (self, server_address, RequestHandlerClass, logger=None):
- BaseHTTPServer.HTTPServer.__init__ (self, server_address,
- RequestHandlerClass)
- self.logger = logger
- def logSetup (filename, log_size, daemon):
- logger = logging.getLogger ("TinyHTTPProxy")
- logger.setLevel (logging.INFO)
- if not filename:
- if not daemon:
- # display to the screen
- handler = logging.StreamHandler ()
- else:
- handler = logging.handlers.RotatingFileHandler (DEFAULT_LOG_FILENAME,
- maxBytes=(log_size*(1<<20)),
- backupCount=5)
- else:
- handler = logging.handlers.RotatingFileHandler (filename,
- maxBytes=(log_size*(1<<20)),
- backupCount=5)
- fmt = logging.Formatter ("[%(asctime)-12s.%(msecs)03d] "
- "%(levelname)-8s {%(name)s %(threadName)s}"
- " %(message)s",
- "%Y-%m-%d %H:%M:%S")
- handler.setFormatter (fmt)
- logger.addHandler (handler)
- return logger
- def usage (msg=None):
- if msg: print msg
- print sys.argv[0], "[-p port] [-l logfile] [-dh] [allowed_client_name ...]]"
- print " -p - Port to bind to"
- print " -l - Path to logfile. If not specified, STDOUT is used"
- print " -d - Run in the background"
- def handler (signo, frame):
- while frame and isinstance (frame, FrameType):
- if frame.f_code and isinstance (frame.f_code, CodeType):
- if "run_event" in frame.f_code.co_varnames:
- frame.f_locals["run_event"].set ()
- return
- frame = frame.f_back
- def daemonize (logger):
- class DevNull (object):
- def __init__ (self): self.fd = os.open ("/dev/null", os.O_WRONLY)
- def write (self, *args, **kwargs): return 0
- def read (self, *args, **kwargs): return 0
- def fileno (self): return self.fd
- def close (self): os.close (self.fd)
- class ErrorLog:
- def __init__ (self, obj): self.obj = obj
- def write (self, string): self.obj.log (logging.ERROR, string)
- def read (self, *args, **kwargs): return 0
- def close (self): pass
- if os.fork () != 0:
- ## allow the child pid to instanciate the server
- ## class
- sleep (1)
- sys.exit (0)
- os.setsid ()
- fd = os.open ('/dev/null', os.O_RDONLY)
- if fd != 0:
- os.dup2 (fd, 0)
- os.close (fd)
- null = DevNull ()
- log = ErrorLog (logger)
- sys.stdout = null
- sys.stderr = log
- sys.stdin = null
- fd = os.open ('/dev/null', os.O_WRONLY)
- #if fd != 1: os.dup2 (fd, 1)
- os.dup2 (sys.stdout.fileno (), 1)
- if fd != 2: os.dup2 (fd, 2)
- if fd not in (1, 2): os.close (fd)
- def main ():
- logfile = None
- daemon = False
- max_log_size = 20
- port = 8000
- allowed = []
- run_event = threading.Event ()
- local_hostname = socket.gethostname ()
- try: opts, args = getopt.getopt (sys.argv[1:], "l:dhp:", [])
- except getopt.GetoptError, e:
- usage (str (e))
- return 1
- for opt, value in opts:
- if opt == "-p": port = int (value)
- if opt == "-l": logfile = value
- if opt == "-d": daemon = not daemon
- if opt == "-h":
- usage ()
- return 0
- # setup the log file
- logger = logSetup (logfile, max_log_size, daemon)
- if daemon:
- daemonize (logger)
- signal.signal (signal.SIGINT, handler)
- if args:
- allowed = []
- for name in args:
- client = socket.gethostbyname(name)
- allowed.append(client)
- logger.log (logging.INFO, "Accept: %s (%s)" % (client, name))
- ProxyHandler.allowed_clients = allowed
- else:
- logger.log (logging.INFO, "Any clients will be served...")
- server_address = (socket.gethostbyname (local_hostname), port)
- ProxyHandler.protocol = "HTTP/1.0"
- httpd = ThreadingHTTPServer (server_address, ProxyHandler, logger)
- sa = httpd.socket.getsockname ()
- print "Servering HTTP on", sa[0], "port", sa[1]
- req_count = 0
- while not run_event.isSet ():
- try:
- httpd.handle_request ()
- req_count += 1
- if req_count == 1000:
- logger.log (logging.INFO, "Number of active threads: %s",
- threading.activeCount ())
- req_count = 0
- except select.error, e:
- if e[0] == 4 and run_event.isSet (): pass
- else:
- logger.log (logging.CRITICAL, "Errno: %d - %s", e[0], e[1])
- logger.log (logging.INFO, "Server shutdown")
- return 0
- if __name__ == '__main__':
- sys.exit (main ())
其他的python proxy:
https://github.com/senko/tornado-proxy
完!
简单的proxy之TinyHTTPProxy.py的更多相关文章
- ExtJS笔记 Proxy
Proxies are used by Stores to handle the loading and saving of Model data. Usually developers will n ...
- 如何制作python安装模块(setup.py)
Python模块的安装方法: 1. 单文件模块:直接把文件拷贝到$python_dir/lib 2. 多文件模块,带setup.py:python setup.py install 3. egg文件, ...
- Nginx uWSGI web.py 站点搭建
一.安装nginx 在安装nginx前,需要先装nginx的依赖包. 1.如果没有yum则先安装yum 删除原有的yum rpm -aq|grep yum|xargs rpm -e --node ...
- python-web.py 入门介绍
内容来源:webpy.org 介绍: 1.python中web.py 是一个轻量级Python web框架,它简单而且功能强大.web.py是一个开源项目. 2.安装很简单:pip install w ...
- DCGAN 代码简单解读
之前在DCGAN文章简单解读里说明了DCGAN的原理.本次来实现一个DCGAN,并在数据集上实际测试它的效果.本次的代码来自github开源代码DCGAN-tensorflow,感谢carpedm20 ...
- python 中的__init__.py的用法与个人理解
使用Python模块常见的情况是,事先写好A.py文件,需要import B.py文件时,先拷贝到当前目录,然后再import 这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就很费 ...
- Linux 下面 Sqlserver 2017 的简单安装
1. 公司网络太烂 yum 在线安装失败 2. 解决方法 找微软的官网 百度网盘 离线下载rpm包. https://packages.microsoft.com/rhel/7/mssql-serve ...
- 生产者&消费者.py
1.最简单的 --生产者消费者 send.py# !/usr/bin/env python3.5# -*- coding:utf-8 -*-# __author__ == 'LuoTianShuai' ...
- Django框架----路由系统、视图和模板(简单介绍)
一.路由配置系统(urls) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表: 你就是以这种方式告诉Django,对于这个URL ...
随机推荐
- Node.js ECONNREFUSED错误
1 现象 node服务器 遇见此错误,如下:events.js:71throw arguments[1]; // Unhandled 'error' event^Error: connect ECON ...
- STM32应用实例六:与MS5837压力传感器的I2C通讯
MS5837压力传感器是一种可用于电路板上,适用于检测10-1200mbar压力范围的传感器,灵敏度非常高,理论上能够检测到0.01mbar的压力变化,实际使用过程中测试并无明显的变化. MS5837 ...
- Dubbo入门---搭建一个最简单的Demo框架
参考文档: https://blog.csdn.net/noaman_wgs/article/details/70214612/
- C++ code:剩余串排列
方法一: 一种直观的解是,先对第一个字串排序,然后逐个字符在第二个字串中搜索,把搜索不到的字符输出,就是所要的结果. 然而,算法库中有一个集合差运算set_difference,而且要求两个集合容器是 ...
- 【ES】代码例子
#!/usr/bin/env python #coding=utf-8 from elasticsearch import Elasticsearch from elasticsearch_dsl i ...
- ROS----TUT-RIM协作机器人和Actin-ROS接口
TUT-RIM: Collaborative Intelligent Heavy Machinery and Robotics http://www.ros.org/news/2017/02/tutr ...
- 使用k8s operator安装和维护etcd集群
关于Kubernetes Operator这个新生事物,可以参考下文来了解这一技术的来龙去脉: https://yq.aliyun.com/articles/685522?utm_content=g_ ...
- Spring之对象依赖关系(依赖注入Dependency Injection)
承接上篇: Spring中,如何给对象的属性赋值: 1:通过构造函数,如下所示: <!-- 1:构造函数赋初始值 --><bean id="user1" clas ...
- python全栈开发day24-__new__、__del__、item系列、异常处理
一.昨日内容回顾 1.反射 用字符串类型的名字,操作命名空间的变量. 反射使用场景:明显的简化代码,能拿到的变量名本来就是一个字符串类型的时候, 用户输入的,文件读入的,网上传输的 2.__call_ ...
- Linux 关闭网络管理服务
1 将NetworkManager 服务设置开机不启动 chkconfig NetworkManager off 2将NetwokManager服务关闭 service NetworkManager ...