ESP-ADF转Flask服务器:替代SimpleHTTPRequestHandler.rfile.read()的方法
解决Flask中手动解析HTTP分块编码数据流的问题
核心原因是Flask底层的Werkzeug会自动处理HTTP分块编码,把分块的数据流合并成完整的字节流返回给request.stream或request.input_stream,所以你直接读取这些流拿到的是已经解码后的原始音频数据,而非带分块标识的原始HTTP报文内容——这和原BaseHTTPRequestHandler中rfile.read()读取的原始报文流完全不同。
要在Flask中实现和rfile.read()一致的原始报文读取,需要直接获取WSGI的原始输入流,绕过Werkzeug的自动分块解码:
具体实现步骤
- 从
request.environ中获取原始输入流:raw_stream = request.environ['wsgi.input'] - 用这个原始流手动解析分块编码,逻辑和原
server.py中的分块解析代码完全对齐:
示例代码片段
from flask import Flask, request app = Flask(__name__) @app.route('/upload', methods=['POST']) def handle_audio_stream(): raw_stream = request.environ['wsgi.input'] while True: # 读取分块大小行(十六进制+CRLF) chunk_size_line = b'' while True: char = raw_stream.read(1) if char == b'\n': break chunk_size_line += char # 去掉末尾的\r,转成整数 chunk_size = int(chunk_size_line.strip(), 16) if chunk_size == 0: # 结束块,读取末尾的CRLF raw_stream.read(2) break # 读取分块数据 chunk_data = raw_stream.read(chunk_size) # 读取分块后的CRLF raw_stream.read(2) # 处理音频数据(比如写入文件或实时处理) with open('output.wav', 'ab') as f: f.write(chunk_data) return 'Stream processed successfully' if __name__ == '__main__': app.run(host='0.0.0.0', port=8000, debug=False)
关键注意点
- 必须关闭Flask的调试模式(
debug=False),调试模式下Werkzeug会对输入流做额外包装,可能导致读取异常 - 读取分块大小和数据时要严格遵循HTTP分块编码规范:分块大小为十六进制字符串,后跟
\r\n;分块数据后同样跟\r\n;最后一个分块大小为0,后跟\r\n\r\n - 原始流是字节流,所有操作都要基于字节处理,避免转成字符串导致编码问题
内容的提问来源于stack exchange,提问作者Jiewen Guan
相关产品推荐
相关产品推荐

