zoukankan      html  css  js  c++  java
  • 使tinyHttpPoxy支持二級代理

    使tinyHttpPoxy支持二級代理 - liukeforever的专栏 - 博客频道 - CSDN.NET

    使tinyHttpPoxy支持二級代理

    分类: Python 211人阅读 评论(1) 收藏 举报

    tinyHttpPoxy是一個簡單的Http代理程式,但是有一個不足的地方是
    不支持二級代理,改寫了一下,最主要是增加
    self.headers['Proxy-Authorization'] = 'Basic bGs6MjAwMg=='


    #!/bin/sh -
    "exec" "python" "-O" "$0" "$@"

    __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
    """

    __version__ = "0.2.1"

    import BaseHTTPServer, select, socket, SocketServer, urlparse
    import base64

    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
    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
    print "/t" "connect to %s:%d" % host_port
    soc.settimeout(5)
    try: soc.connect(host_port)
    except socket.error, arg:
    #try: msg = arg[1]
    #except: msg = arg
    #self.send_error(404, msg)
    self.send_error(404, 'url timeout')
    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:
    print "/t" "bye"
    soc.close()
    self.connection.close()

    def do_GET(self):
    (scm, netloc, path, params, query, fragment) = urlparse.urlparse(
    self.path, 'http')
    print "cmd:", self.raw_requestline
    #print 'self.path = ', self.path
    #print 'Values: ', (scm, netloc, path, params, query, fragment)
    if scm != 'http' or fragment or not netloc:
    self.send_error(400, "bad url %s" % self.path)
    return
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    fid = None
    try:
    #if self._connect_to(netloc, soc):
    if self._connect_to('172.17.5.53:80', soc):
    self.log_request()
    getStr = "%s %s %s/r/n" % (
    self.command,
    urlparse.urlunparse((scm, netloc, path, params, query, '')),
    self.request_version)
    print "A:", scm, netloc, path,params,query
    soc.send(getStr)
    print "getStr: ", getStr
    ###
    self.headers['Proxy-Authorization'] = 'Basic bGs6MjAwMg=='
    self.headers['Connection'] = 'close'
    del self.headers['Proxy-Connection']
    for key_val in self.headers.items():
    s = "%s: %s/r/n" % key_val
    print "s:", s
    soc.send(s)
    soc.send("/r/n")
    if path == '/mt':
    f = '.'+path+'/'+query
    if f != '/mt/':
    print "f:", f
    fid = open(f,'wb+')
    self._read_write(soc,cache=fid)
    finally:
    #print "/t" "bye"
    soc.close()
    if fid: fid.close()
    self.connection.close()

    def _read_write(self, soc, max_idling=20,cache=None):
    ''' todo: need more checking to make sure not garbage downloaded
    more checking to avoid download duplicate
    '''
    iw = [self.connection, soc]
    ow = []
    header_pos = -1; # data pos for end of http header
    header_buffer = ''
    count = 0
    #print "count = ", count
    while 1:
    count += 1
    #print "count = ", count
    (ins, _, exs) = select.select(iw, ow, iw, 3)
    if exs:
    #print "break"
    break
    if ins:
    for i in ins:
    if i is soc:
    out = self.connection
    data = i.recv(81920)
    #print "OK: ", data
    else:
    out = soc
    data = i.recv(81920)
    print "OK: ", data
    #print "OK: ", data
    #data = data.decode('big5').encode('utf-8')
    #print data
    if data:
    out.send(data)
    if cache:
    if header_pos == -1:
    header_buffer += data
    header_pos = header_buffer.find('/r/n/r/n')
    if header_pos == -1:
    header_buffer = header_buffer[-3:]
    else:
    data = header_buffer[header_pos+4:]
    if header_pos != -1:
    cache.write(data)

    count = 0
    else:
    print "/t" "idle", count
    if count == max_idling:
    print "max_idling", max_idling
    break

    do_HEAD = do_GET
    do_POST = do_GET
    do_PUT = do_GET
    do_DELETE=do_GET

    class ThreadingHTTPServer (SocketServer.ThreadingMixIn,
    BaseHTTPServer.HTTPServer): pass

    if __name__ == '__main__':
    from sys import argv
    if argv[1:] and argv[1] in ('-h', '--help'):
    print argv[0], "[port [allowed_client_name ...]]"
    else:
    if argv[2:]:
    allowed = []
    for name in argv[2:]:
    client = socket.gethostbyname(name)
    allowed.append(client)
    print "Accept: %s (%s)" % (client, name)
    ProxyHandler.allowed_clients = allowed
    del argv[2:]
    else:
    print "Any clients will be served..."
    BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer)

  • 相关阅读:
    LR学习笔记6-常用术语
    LR学习笔记5-LR界面分析3
    LR学习笔记4-LR界面分析2
    LR学习笔记3-LR界面分析1
    Maven快速导出maven工程的依赖包
    Python3 将txt数据转换成列表,进行排序,筛选
    iOS OC环信实时语音切换听筒免提听不到声音报错:AVAudioSessionErrorCodeBadParam
    iOS voip电话和sip软电话 --网络电话
    远程(离线)推送自定义推送声音,友盟、极光
    Swift3.0 自定义tableView复用cell 的写法,与CollectionViewCell的不同,数据model
  • 原文地址:https://www.cnblogs.com/lexus/p/2851565.html
Copyright © 2011-2022 走看看