Skip to content

Instantly share code, notes, and snippets.

@saward
Created May 15, 2022 15:00
Show Gist options
  • Select an option

  • Save saward/5f65782c799e739c648551b00dc64c86 to your computer and use it in GitHub Desktop.

Select an option

Save saward/5f65782c799e739c648551b00dc64c86 to your computer and use it in GitHub Desktop.

Revisions

  1. saward created this gist May 15, 2022.
    89 changes: 89 additions & 0 deletions main.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    use async_std::io::prelude::*;
    use async_std::io::Error;
    use async_std::net::{TcpListener, TcpStream};
    use async_std::prelude::Future;
    use async_std::task;
    use std::time::Duration;

    struct Server {
    addr: String,
    }

    impl Server {
    fn new(addr: String) -> Self {
    Self { addr }
    }

    async fn run<F, Fut>(self, handler: F) -> Result<(), Error>
    where
    // `handler` now returns a generic type `Fut`...
    F: Fn(String) -> Fut,
    // ...which is a `Future` whose `Output` is an `HttpResponse`
    Fut: Future<Output = String>,
    {
    let listener = TcpListener::bind(self.addr).await?;

    loop {
    let (mut connection, _) = listener.accept().await?;
    let request = read_http_request(&mut connection).await?;

    task::sleep(Duration::from_secs(10)).await;

    // Await the future returned by `handler`
    let response = handler(request).await;

    write_http_response(connection, response).await?;
    }
    }
    }

    async fn read_http_request(stream: &mut TcpStream) -> Result<String, Error> {
    let mut buffer = [0; 1024];

    stream.read(&mut buffer).await?;

    let request = format!("Request: {}", String::from_utf8_lossy(&buffer[..]));

    Ok(request)
    }

    async fn basic_handler(request: String) -> String {
    let contents = format!(
    r#"
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <title>Hello!</title>
    </head>
    <body>
    <h1>Hello!</h1>
    <p>Hi from Rust</p>
    <pre>{}</pre>
    </body>
    </html>
    "#,
    request
    );

    format!(
    "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}",
    contents.len(),
    contents,
    )
    }

    async fn write_http_response(mut stream: TcpStream, response: String) -> Result<(), Error> {
    stream.write(response.as_bytes()).await?;
    stream.flush().await?;

    Ok(())
    }

    fn main() -> std::io::Result<()> {
    let server = Server::new("127.0.0.1:8989".to_string());

    task::block_on(server.run(basic_handler))?;

    Ok(())
    }