Get rest of a string after using `lines()`

I'm trying to parse an HTTP request and am using lines() to easily parse the headers, however I'd like to get access to the "rest" of the string without it being split by Lines.

Example #1:

let raw_req: String = /* ... */;
let req_lines = raw_req.lines();

for line in lines {
    if line.is_empty() {
        // End of headers
        break;
    }

    let (header, value) = /* parse(...) */;
    /* ... */
}

let body = /* ??? */;

Lets say I have the following HTTP request:

GET /index.html HTTP/1.1\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)\r\n
Host: www.example.com\r\n
\r\n

Since the request body is empty, body would just be an empty string, which is fine.

However if the request had a body that happens to contain newlines:

GET /index.html HTTP/1.1\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)\r\n
Host: www.example.com\r\n
\r\n
Hello,\n
World!

Using lines() would also split the body, which is not what I want.
Is there a way to achieve something like this?

You could very naively collect the remaining lines like this:

fn main() {
    let raw_req = "GET /index.html HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.example.com

Hello,
World!";
        
    let mut req_lines = raw_req.lines();
    
    while let Some(line) = req_lines.next() {
        if line.is_empty() {
            break;
        }
    }
    
    let body: String = req_lines.collect::<Vec<&str>>().join("\n");
    
    assert_eq!(&body, "Hello,\nWorld!");
}

Playground.

Note that we need to convert the for loop into a while loop to make it work, as the while loop won't consume the whole lines iterator by implicitly calling .into_iter() on it.

You could split the original string on "\r\n\r\n" into two parts, then use lines on the 1st part to get a line for each header. This ensures that the newlines in the 2nd part are unchanged.

Incidentally, I wonder why the Lines iterator has no .as_str() method like, for example, Chars does.

3 Likes