如何在Rust Tokio Tungstenite中返回HTTP错误响应?
解决Tokio Tungstenite返回HTTP 400拒绝WebSocket连接的问题
要实现缺失roomID查询参数时返回HTTP 400响应,你需要利用tungstenite::Error::Http类型,在回调中构造自定义的HTTP 400响应并通过错误返回,这样accept_hdr_async会发送该响应而非直接关闭连接。
修改后的完整代码
use std::collections::HashMap; use url::Url; use tokio_tungstenite::tungstenite::{Error, http::Response}; // ... 你的其他业务代码 ... let websocket_stream_result = tokio_tungstenite::accept_hdr_async( stream, |req, mut res| { // 补全协议头以满足Url解析要求,避免无协议导致的解析失败 let url = match Url::parse(&format!("http://localhost{}", req.uri())) { Ok(url) => url, Err(_) => { let bad_req = Response::builder() .status(400) .header("Content-Type", "text/plain") .body("Invalid request URI".into()) .unwrap(); return Err(Error::Http(bad_req)); } }; let params: HashMap<String, String> = url .query_pairs() .map(|(key, value)| (key.to_string(), value.to_string())) .collect(); if params.get("roomID").is_none() { // 构造HTTP 400响应,明确提示缺失参数 let bad_req = Response::builder() .status(400) .header("Content-Type", "text/plain") .body("Missing required query parameter: roomID".into()) .unwrap(); // 返回Http类型错误,触发框架发送该响应 Err(Error::Http(bad_req)) } else { println!("Room ID is: {}", params.get("roomID").unwrap()); Ok(res) } }, ).await;
关键改动说明
- URI解析修正:
Url::parse要求完整URL(含协议),因此用http://localhost补全请求URI,避免无协议导致的解析失败。 - 自定义400响应:当
roomID缺失时,通过Response::builder构建状态码400的响应,设置合适的内容类型和提示文本,让客户端明确知道拒绝原因。 - Http错误触发响应:将构造好的响应包装成
Error::Http返回,accept_hdr_async会自动将该HTTP响应发送给客户端,完成握手拒绝流程,而非直接关闭连接。
内容的提问来源于stack exchange,提问作者Ethan Crabb
相关产品推荐
相关产品推荐

