Python中使用BaseHTTPServer编写简易HTTP服务器,Response有时缺少头部,求大佬指点!

就是一个很简单的 HTTP 服务器,响应任意 GET 请求,返回一个文件
服务端用 clumsy 模拟乱序环境,乱序 10%
然后在客户端抓包发现有时候服务端的 Response 没有 HTTP 头,不知道为什么……
是 python 有 bug 还是我写的代码有问题?求大佬指点

有头部的流

GET /122879/122879.bat HTTP/1.1
Host: 200.200.89.77:8832
User-Agent: python-requests/2.18.4
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

HTTP/1.0 200 OK Server: BaseHTTP/0.6 Python/3.7.0 Date: Fri, 03 Aug 2018 15:10:09 GMT Content-Length: 252416 Last-Modified: Thu, 14 Sep 2017 05:05:10 GMT

MZ…@… .!..L.!This program cannot be run in DOS mode.

$…PE…L…:1…x…^…

没有头部的流

GET /122877/122877.bat HTTP/1.1
Host: 200.200.89.77:8832
User-Agent: python-requests/2.18.4
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

MZ…@… .!..L.!This program cannot be run in DOS mode.

$…PE…L…:1…x…^…

源代码

from http.server import BaseHTTPRequestHandler
from http.server import HTTPServer
import datetime
import os
import shutil

Listen Address

ADDR = ‘’

Listen Port

PORT = 8832

class WebRequestHandler(BaseHTTPRequestHandler): def do_GET(self): path = “./testb” try: f = open(path, ‘rb’) except IOError: self.send_error(404, “File not found”) return None self.send_response(200) #self.send_header(“Content-type”, ‘image/png’) #self.send_header(‘Content-Disposition’,‘attachment; filename=test.exe’) fs = os.fstat(f.fileno()) self.send_header(“Content-Length”, str(fs[6])) self.send_header(“Last-Modified”, self.date_time_string(fs.st_mtime)) self.end_headers()
shutil.copyfileobj(f, self.wfile) f.close()

server = HTTPServer((ADDR, PORT), WebRequestHandler) print(“Server start!”) server.serve_forever()


Python中使用BaseHTTPServer编写简易HTTP服务器,Response有时缺少头部,求大佬指点!

6 回复

说明没走到 set header 逻辑里,需要打日志了


这个问题我遇到过。BaseHTTPServer的send_response方法默认只发送状态行和ServerDate头,其他头部需要手动添加。你肯定是漏了调用send_headerend_headers

看个完整例子,关键在do_GET方法里那三行:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import time

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # 1. 先发送响应状态码
        self.send_response(200)
        
        # 2. 发送自定义头部(这步不能少!)
        self.send_header('Content-type', 'text/html; charset=utf-8')
        self.send_header('X-Custom-Header', 'MyValue')
        
        # 3. 结束头部发送(这步必须调用!)
        self.end_headers()
        
        # 4. 发送响应体
        self.wfile.write('<html><body>Hello World</body></html>')

if __name__ == '__main__':
    server = HTTPServer(('localhost', 8080), MyHandler)
    server.serve_forever()

常见坑点:

  • 忘了调end_headers(),导致头部没真正发送出去
  • send_header之前调send_response
  • end_headers()之后还想加头部(已经发不出去了)

用curl验证一下:

curl -I http://localhost:8080/

应该能看到完整的头部信息。

总结:按顺序调用那三个方法就行。

散了散了,Wireshark 有 bug,导致乱序包重组失败,实际是有 HTTP 头的

首先别怀疑编程语言有 bug

我太相信 wireshark 了

我总以为这么历史悠久的软件怎么会有 BUG 呢?
他还真有
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=13517

回到顶部