You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SimpleHTTPRequestHandler的自定义处理器如何设置协议版本?

问题:自定义HTTP服务器无法正确应用HTTP/1.1协议版本

我基于Python的http.server模块编写了自定义脚本,目标是处理自定义路径“/files”以JSON格式返回文件列表。--protocol参数是Python 3.11为http.server模块新增的,我使用Python 3.11.4,尝试通过以下代码支持该参数:

import json
import os
import sys
from functools import partial
from http.server import SimpleHTTPRequestHandler, test
from pathlib import Path


class HTTPRequestHandler(SimpleHTTPRequestHandler):
    def do_GET(self) -> None:
        if self.path == '/files':
            response = bytes(self._get_response(), 'utf-8')
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.send_header('Content-Length', str(len(response)))
            self.end_headers()
            self.wfile.write(response)

            return

        return super().do_GET()

    def _get_response(self) -> str:
        results = []

        for item in Path(self.directory).rglob('*'):
            if item.is_file():
                if __file__ in str(item):
                    continue

                file_size = str(os.stat(item).st_size)
                relative_file_path = os.path.relpath(item, self.directory)

                if sys.platform == 'win32':
                    relative_file_path = relative_file_path.replace('\\', '/')

                results.append(dict(file=relative_file_path, size=file_size))

        return json.dumps(results)


if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument('-b', '--bind', metavar='ADDRESS',
                        help='bind to this address '
                        '(default: all interfaces)')
    parser.add_argument('-d', '--directory', default=os.getcwd(),
                        help='serve this directory '
                        '(default: current directory)')
    parser.add_argument('-p', '--protocol', metavar='VERSION',
                        default='HTTP/1.1',
                        help='conform to this HTTP version '
                             '(default: %(default)s)')
    parser.add_argument('port', default=8000, type=int, nargs='?',
                        help='bind to this port '
                        '(default: %(default)s)')
    args = parser.parse_args()

    handler_class = partial(HTTPRequestHandler, directory=args.directory)

    test(HandlerClass=handler_class, port=args.port, bind=args.bind, protocol=args.protocol)

执行命令:

python server.py --bind <ip> <port> -p HTTP/1.1

但响应头仍显示“HTTP/1.0”版本,请问哪里操作有误?


解决方案

问题出在http.server.test()函数的protocol参数仅用于配置底层服务器套接字的协议标识,但SimpleHTTPRequestHandler默认使用HTTP/1.0作为响应的协议版本,这个属性不会被test()函数自动覆盖。

要让响应头使用指定的HTTP版本,需要将protocol_version参数传递给自定义的HTTPRequestHandler,具体有两种修改方式:

方式1:通过partial直接传递协议版本

修改handler_class的定义,把args.protocol作为protocol_version参数传入:

handler_class = partial(HTTPRequestHandler, directory=args.directory, protocol_version=args.protocol)

方式2:在Handler类中动态控制协议版本

如果需要更灵活的逻辑,可以在Handler的初始化方法中设置:

class HTTPRequestHandler(SimpleHTTPRequestHandler):
    def __init__(self, *args, protocol_version=None, **kwargs):
        super().__init__(*args, **kwargs)
        if protocol_version:
            self.protocol_version = protocol_version
    
    # 其余方法保持不变

然后同样通过partial传递参数:

handler_class = partial(HTTPRequestHandler, directory=args.directory, protocol_version=args.protocol)

修改后重新执行命令,响应头就会显示正确的HTTP/1.1版本了。

内容的提问来源于stack exchange,提问作者Pavel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:58:09