Rust Book第20章单线程服务器示例代码在Chrome中运行时因无效UTF-8触发panic求助
Rust Book第20章单线程服务器示例代码在Chrome中运行时因无效UTF-8触发panic求助
嘿,我之前也踩过这个坑!Chrome发送的HTTP请求里偶尔会包含一些不符合UTF-8标准的字节,而教程里用的BufReader::lines()方法会默认尝试把所有输入解析成UTF-8字符串,一旦碰到无效字节就会返回错误,你直接用unwrap()就触发panic了。
问题根源
lines()方法在读取每一行时,会严格按照UTF-8编码解析字节流,但浏览器(比如Chrome)发送的请求可能包含一些扩展ASCII字符或者其他非标准编码的内容,导致解析失败。教程里的示例是简化版,只考虑了理想情况,没处理这类异常。
修复方案
我们可以先读取整个请求的字节流,再手动处理UTF-8解析的错误,而不是依赖lines()的自动解析。这里有两种常用的处理方式:
方式1:优雅处理无效UTF-8,返回错误响应
修改handle_connection函数,先读取所有字节,再尝试转换为字符串,遇到错误时返回400请求错误:
use std::{ io::{prelude::*, BufReader}, net::{TcpListener, TcpStream}, }; fn main() { let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); for stream in listener.incoming() { let stream = stream.unwrap(); handle_connection(stream); } } fn handle_connection(mut stream: TcpStream) { let buf_reader = BufReader::new(&mut stream); // 先读取全部请求字节 let mut request_bytes = Vec::new(); if buf_reader.read_to_end(&mut request_bytes).is_err() { eprintln!("Failed to read request"); return; } // 尝试转换为UTF-8字符串,处理错误 let http_request = match String::from_utf8(request_bytes) { Ok(req) => req, Err(e) => { eprintln!("Invalid UTF-8 in request: {}", e); // 返回400错误响应 let response = "HTTP/1.1 400 Bad Request\r\n\r\nInvalid request encoding"; stream.write_all(response.as_bytes()).unwrap_or_default(); stream.flush().unwrap_or_default(); return; } }; // 按行分割请求,继续后续处理 let request_lines: Vec<&str> = http_request.lines().collect(); println!("Received request lines: {:?}", request_lines); // 返回正常响应(保留原教程的逻辑) let response = "HTTP/1.1 200 OK\r\n\r\nHello, World!"; stream.write_all(response.as_bytes()).unwrap_or_default(); stream.flush().unwrap_or_default(); }
方式2:忽略无效UTF-8,替换为占位符
如果不需要严格拒绝非UTF-8请求,可以用String::from_utf8_lossy(),它会把无效字节替换成�符号,确保程序不会panic:
// 替换上述代码中的match部分 let http_request = String::from_utf8_lossy(&request_bytes); let request_lines: Vec<&str> = http_request.lines().collect();
额外提示
教程里的示例主要是演示TCP服务器和HTTP的基本原理,实际生产环境中还需要处理更多异常情况,比如连接中途断开、超大请求、非法请求格式等。如果后续要扩展这个服务器,建议逐步加入错误处理逻辑,避免直接使用unwrap()。
备注:内容来源于stack exchange,提问作者Luke Puplett
相关产品推荐
相关产品推荐

