Python代理不处理POST请求
我正在创建一个简单的Python代理,它可以记录所有通过它发送的请求。目前,除了POST请求之外,其他的都能正常工作(我无法在StackOverflow上投票)。
我没有专门定义一个处理POST请求的函数,而是用GET函数来代替。
有人能告诉我问题出在哪里吗?
这是我的代码:
#!/usr/local/bin/python2
import BaseHTTPServer, select, socket, SocketServer, urlparse
class ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
self.socket = socket
self.server_version = 'TestProxy 1.0'
self.request_buffer_size = 0
try:
self.handle()
finally:
self.finish()
def connect_to(self, location, destination_socket):
i = location.find(':')
if i >= 0:
host = location[:i]
port = int(location[i + 1:])
else:
host = location
port = 80
print 'Connecting to {0}:{1}'.format(host, port)
try:
self.socket.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):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if self.connect_to(self.path, socket):
self.log_request(200)
self.wfile.write(self.protocol_version + ' 200 Connection established\n')
self.wfile.write('Proxy-agent: {0}\n'.format(self.version_string()))
self.wfile.write('\n')
self.read_write(self.socket, 300)
finally:
print 'Connection closed.'
self.socket.close()
self.connection.close()
def do_GET(self):
scm, location, path, parameters, query, fragment = urlparse.urlparse(self.path, 'http')
if scm != 'http' or fragment or not location:
self.send_error(400, 'bad url {0}'.format(self.path))
return
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if self.connect_to(location, self.socket):
self.log_request()
self.socket.send('{0} {1} {2}\n'.format(self.command, urlparse.urlunparse(('', '', path, parameters, query, '')), self.request_version))
self.headers['Connection'] = 'close'
del self.headers['Proxy-Connection']
for key, value in self.headers.items():
self.socket.send('{0}: {1}\n'.format(key, value))
self.socket.send('\n')
self.read_write(self.socket)
finally:
print 'Closing connection...'
self.socket.close()
self.connection.close()
def read_write(self, socket, max_idling = 100):
iw = [self.connection, socket]
ow = []
count = 0
while count != max_idling:
count += 1
read_list, write_list, exception_list = select.select(iw, ow, iw, 3)
if exception_list:
break
if read_list:
for item in read_list:
out = self.connection if item is socket else socket
data = item.recv(8192)
if data:
out.send(data)
count = 0
else:
pass
#print 'Idle for {0}'.format(count)
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__':
BaseHTTPServer.test(ProxyHandler, ThreadingHTTPServer)
这一部分处理POST和GET请求:
def do_GET(self):
scm, location, path, parameters, query, fragment = urlparse.urlparse(self.path, 'http')
if scm != 'http' or fragment or not location:
self.send_error(400, 'bad url {0}'.format(self.path))
return
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if self.connect_to(location, self.socket):
self.log_request()
self.socket.send('{0} {1} {2}\n'.format(self.command, urlparse.urlunparse(('', '', path, parameters, query, '')), self.request_version))
self.headers['Connection'] = 'close'
del self.headers['Proxy-Connection']
for key, value in self.headers.items():
self.socket.send('{0}: {1}\n'.format(key, value))
self.socket.send('\n')
self.read_write(self.socket)
finally:
print 'Closing connection...'
self.socket.close()
self.connection.close()
1 个回答
1
在self.connection
上进行读取选择时,它总是没有返回。如果你手动从这个对象读取数据,也没有任何数据出来。看起来你需要从self.rfile
读取数据。
需要注意的是,调用select
在self.rfile
上也不会返回,但self.rfile.read()
是可以正常工作的。这可能是因为self.rfile
是一个类似文件的对象,而服务器进程已经从操作系统读取了POST请求主体的开头部分。