I am implementing the HTTP/1.1 protocol from scratch for academic purpose. I have implemented the RequestBuilder
which builds the request object successively from the buffer passed. This is the code to handle the opened socket.
async fn process_socket(stream: TcpStream) -> Result<Request> {
let mut request_builder = RequestBuilder::new();
let mut buffer: [u8; 1024] = unsafe { MaybeUninit::uninit().assume_init() };
loop {
stream.readable().await?;
match stream.try_read(&mut buffer) {
Ok(0) => {
break;
}
Ok(n) => (),
Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e.into());
}
}
request_builder.parse(&buffer);
}
let request = request_builder.build()?;
Ok(request)
}
request_builder.parse(&buffer);
will take the next part of the buffer and parses the request further. My question is, how to break the loop when the client has sent the whole request. When I make a request to the server using curl localhost:8080
, the whole request is parsed.
The loop would have been broken after reading the whole request stream.
The loop is stuck at stream.readable().await?;
after reading the whole request into buffer. Currently, when I kill curl
command using Ctrl+C
, the loop is broken using Ok(0)
, but I want it to break after reading the who
You need to interpret the HTTP request, as the TCP connection will not get half-closed by a client. A FIN
by the client which would violate the protocol) is the only way readable()
returns (with an Err
) unless the client sends more data (which breaks the HTTP specification).