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

开发小型HTTP服务器遇IndexError: list index out of range问题求助

解决HTTP服务器数组索引越界错误

问题说明

开发HTTP服务器时触发IndexError: list index out of range,报错指向请求解析环节的split()[1]操作。

报错信息

Traceback (most recent call last):
  File "/data/data/com.termux/files/home/SimpleHTTP/Generic/main.py", line 12, in <module>
    client.send(str(f"HTTP/1.1 200 OK \n\n{open(f'.{client.recv(1024).decode().splitlines()[0].split()[1]}', 'rb').read()}").encode('utf-8'))
                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

原始代码

import socket

#Make a socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("0.0.0.0", 8080))
sock.listen(1)

#Handling requests
while True:
  #listening for client
  client, address = sock.accept()

  try:
    #reads file from response and makes a response
    client.send(str(f"HTTP/1.1 200 OK \n\n{open(f'.{client.recv(1024).decode().splitlines()[0].split()[1]}', 'rb').read()}").encode('utf-8'))
  #HTTP Response 404
  except FileNotFoundError:
    client.send("HTTP/1.1 404 Not Found".encode("utf-8"))

问题根源

  1. 无请求校验:所有逻辑压缩在一行,未处理空请求、格式错误的请求。比如客户端断开连接时recv()返回空字节,解码后无法拆分出有效请求行;非标准HTTP请求的请求行拆分后元素不足2个,访问[1]就会越界。
  2. 安全风险:直接拼接用户输入的路径,存在路径遍历攻击(如../)风险。
  3. 数据损坏:二进制文件转字符串再编码,会破坏非文本文件的内容。

修复方案

优化后的代码

import socket
import os
from urllib.parse import unquote

# 创建socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("0.0.0.0", 8080))
sock.listen(1)
print("服务器运行在 http://0.0.0.0:8080")

# 处理请求循环
while True:
    # 接受客户端连接
    client, address = sock.accept()
    print(f"来自 {address} 的连接")

    try:
        # 接收请求数据
        request_data = client.recv(1024)
        if not request_data:
            client.close()
            continue

        # 解码并解析请求行
        request_str = request_data.decode('utf-8', errors='replace')
        lines = request_str.splitlines()
        if not lines:
            raise ValueError("空请求")

        request_line = lines[0].strip()
        parts = request_line.split()
        if len(parts) < 2:
            raise ValueError("无效请求行格式")

        # 提取并安全处理路径
        path = unquote(parts[1])
        # 规范化路径,防止路径遍历
        safe_path = os.path.normpath(os.path.join('.', path))
        if not safe_path.startswith('./'):
            raise PermissionError("非法访问路径")

        # 读取文件内容
        with open(safe_path, 'rb') as f:
            content = f.read()

        # 发送200响应及正确头信息
        response_headers = b"HTTP/1.1 200 OK\r\n"
        response_headers += b"Content-Length: %d\r\n" % len(content)
        response_headers += b"\r\n"
        client.send(response_headers + content)

    except FileNotFoundError:
        client.send(b"HTTP/1.1 404 Not Found\r\n\r\n文件不存在")
    except (ValueError, PermissionError) as e:
        client.send(b"HTTP/1.1 400 Bad Request\r\n\r\n请求无效: " + str(e).encode('utf-8'))
    except Exception as e:
        client.send(b"HTTP/1.1 500 Internal Server Error\r\n\r\n服务器错误: " + str(e).encode('utf-8'))
    finally:
        client.close()

修复要点

  • 拆分逻辑,逐步骤校验请求有效性,避免索引越界。
  • 对路径解码、规范化,拦截路径遍历攻击。
  • 使用with语句安全操作文件,避免资源泄漏。
  • 直接发送二进制文件内容,避免数据损坏。
  • 扩展异常捕获范围,返回对应HTTP错误码。
  • 确保客户端连接最终关闭,避免资源占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:43:07