我使用这个类在Python:中运行HTTP服务器
class Server:
def __init__(self):
port = 81
httpd = SocketServer.ThreadingTCPServer(('', port), self.Proxy)
httpd.serve_forever()
class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
# just for demonstration:
url = "http://ovh.net/files/10Mio.dat"
opener = urllib2.build_opener()
handle = opener.open(url)
if hasattr(handle.info(), "headers"):
headers = handle.info().headers
for h in headers:
self.send_header(h[0], h[1])
self.end_headers()
self.copyfile(handle, self.wfile)
但不幸的是,这并没有像预期的那样奏效。如果我向服务器发送请求,我会得到一个比我期望的文件大一点的文件。当我查看它时,我发现响应头存储在该文件的开头。响应本身不包含头,所以我认为SimpleHTTPServer在调用do_GET()之前结束了头。
我看到了这个答案,并相应地编辑了我的代码:
class Server:
def __init__(self):
port = 81
httpd = SocketServer.ThreadingTCPServer(('', port), self.Proxy)
httpd.serve_forever()
class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
# get handle again
self.copyfile(handle, self.wfile)
def end_headers(self):
self.send_my_headers()
SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)
def send_my_headers(self):
# Do something smart to get a file-like variable named handle
self.send_header("Access-Control-Allow-Origin", "*")
if hasattr(handle.info(), "headers"):
headers = handle.info().headers
for h in headers:
self.send_header(h[0], h[1])
但这并没有什么区别。响应标头仍然填充在文件中。这是怎么回事?
编辑:我更新了我的第一个例子来澄清我的意思。我想要的有点像HTTP代理:我的服务器应该从另一台服务器下载一个文件,然后将数据发送回客户端。由于某些原因(无法解释),我无法使用常规代理。
现在,第一个代码示例非常有效地做到了这一点。我的问题是在这个过程中所有的头都会丢失。这意味着客户端不知道下载大小(因此显示了不确定的进度条)或文件名(内容处置)。
在我的第二个代码示例中,我试图发送从上游服务器获得的头,但头似乎在调用do_GET之前就完成了。
好吧,使用Wireshark我发现了这里的实际错误:
我忘了做
self.send_response(200)
在发送标题之前,它发送一行类似于:
HTTP/1.1 200 OK
我想这一行的缺失会导致HTTP客户端认为服务器使用的是HTTP/0.9,实际上是错误的头。