【发布时间】:2025-12-18 09:50:01
【问题描述】:
我正在尝试从简单的 HTTP 解析器扩展示例;
https://doc.rust-lang.org/book/ch20-01-single-threaded.html
当我解析请求时,服务器总是挂在最后一个标题行之后的行。 我为每一行添加了一些日志记录,并写出 '2' 字符 \d\a 行;
1:20:GET /data HTTP/1.1
2:22:Host: localhost:7878
3:25:User-Agent: curl/7.64.0
4:13:Accept: */*
5:20:Content-Length: 27
6:49:Content-Type: application/x-www-form-urlencoded
7:2:
\u{d}
\u{a}
为什么会这样,你可以通过运行代码然后运行来测试这个 卷曲 http://localhost:7878
你应该会看到它挂起,当你按下 Control C 时,你会看到 rust 日志显示
Natural end of HTTP request reached
We made it out!
这是出错的代码;
use std::fs;
use std::io::BufReader;
use std::io::prelude::*;
use std::net::TcpStream;
use std::net::TcpListener;
enum LogLevel {
DEBUG=0,
NORMAL=1,
PROD=2
}
const LOG_LEVEL : LogLevel = LogLevel::DEBUG;
const GET:i8 = 1;
const OOPS:i8 = -1;
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
log("Server started".to_string(), LogLevel::PROD);
for stream in listener.incoming() {
handle_connection(stream.unwrap());
}
}
fn validate_request_verb(verb: String)->i8 {
if verb.eq("GET") {
return GET;
}
return OOPS;
}
fn handle_connection(mut stream: TcpStream) {
let mut line_count = 0;
let mut reader = BufReader::new(stream.try_clone().unwrap());
let mut request_verb:i8 = OOPS;
loop {
line_count = line_count + 1;
let mut line = String::new();
let line_size = reader.read_line(&mut line).unwrap();
if line_size > 0 {
log(format!("{}:{}:{}", line_count, line_size, line), LogLevel::DEBUG);
if line_count == 1 {
let mut token_counter = 1;
for token in line.split_whitespace(){
if token_counter == 1 {
request_verb = validate_request_verb(token.to_string());
}
token_counter = token_counter + 1;
}
} else { //line_count > 2
if request_verb == GET && !line.contains(": ") {
//spell_out(line);
//TODO: this only works for GET
//break;
}
}
} else { //Count == 0
log("Natural end of HTTP request reached".into(), LogLevel::NORMAL);
break;
}
if line_count > 100 {
log("HTTP request had more than 100 lines".into(), LogLevel::NORMAL);
break;
}
}
println!("We made it out!");
let contents = fs::read_to_string("hello.html").unwrap();
let response = format!(
"HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}",
contents.len(),
contents
);
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}
fn log(message: String , maximum_log_level:LogLevel){
if LOG_LEVEL as i8 <= maximum_log_level as i8 {
if message.ends_with("\n") {
print!("{}", message);
} else {
println!("{}", message);
}
}
}
fn spell_out(s: String){
for c in s.chars(){
println!("{}", c.escape_unicode());
}
}
最后一点,根据
这应该通过使用read_to_string 来解决,但没有运气..
【问题讨论】: