mmhttp 0.5.1

A minimal HTTP 0.9 client for Rust, using std networking.
Documentation
use std::{io::{Read, Write}, net::{TcpStream, ToSocketAddrs}};


/// Makes a single new connection to the specified `addr`, and sends an HTTP 0.9 "Simple Request" with the
/// specified `method`. Returns the response.
/// 
/// # Examples
/// 
/// ```
/// let response = mmhttp::get("example.com:80", "/").unwrap();
/// println!("Response: {}", String::from_utf8_lossy(&response));
/// ```
pub fn get<A: ToSocketAddrs>(addr: A, path: &str) -> std::io::Result<Vec<u8>> {
    let mut socket = TcpStream::connect(addr)?;
    // > Simple-Request = "GET" SP Request-URI CRLF
    // Followed by CRLF for the end of the request.
    let req = format!("GET {}\r\n\r\n", path);
    // > If an HTTP/1.0 server receives a Simple-Request, it must respond with
    // an HTTP/0.9 Simple-Response. An HTTP/1.0 client capable of receiving
    // a Full-Response should never generate a Simple-Request.
    socket.write_all(req.as_bytes())?;

    // > Simple-Response = [ Entity-Body ]
    // > Note that the Simple-Response consists only of the entity body and is 
    // terminated by the server closing the connection.
    let mut response = Vec::with_capacity(1024);
    socket.read_to_end(&mut response)?;
    Ok(response)
}

#[cfg(test)]
mod tests {
    use crate::get;

    #[test]
    fn test_request_to_server() {
        get("rust-lang.com:80", "/").unwrap();
    }

    #[test]
    fn test_invalid_req() {
        get("%", "/")
            .expect_err("Expected an error for invalid address");
    }

    #[test]
    fn test_invalid_port() {
        get("rust-lang.com:99999", "/")
            .expect_err("Expected an error for invalid port");
    }

    #[test]
    fn test_missing_port() {
        get("example.com", "/")
            .expect_err("Expected an error for missing port");
    }
}