Skip to content

Commit

Permalink
feat(examples): Introduce HTTP Tokio example
Browse files Browse the repository at this point in the history
Introduce a simple HTTP server written in Rust using the Tokio
framework.

Signed-off-by: Mihnea Popeanga <[email protected]>
Signed-off-by: Razvan Deaconescu <[email protected]>
  • Loading branch information
razvand committed Jan 5, 2024
1 parent e856d6f commit 4d01506
Show file tree
Hide file tree
Showing 6 changed files with 382 additions and 0 deletions.
281 changes: 281 additions & 0 deletions examples/http-tokio/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions examples/http-tokio/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "http-tokio"
version = "0.1.0"
edition = "2021"


[dependencies]
tokio = {version = "1", features = ["rt-multi-thread", "net", "time", "macros", "io-util"] }
17 changes: 17 additions & 0 deletions examples/http-tokio/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM --platform=linux/x86_64 rust:1.73.0-bookworm AS build

WORKDIR /src

COPY ./src /src/src
COPY ./Cargo.toml /src/Cargo.toml
COPY ./Cargo.lock /src/Cargo.lock

RUN cargo build

FROM scratch

COPY --from=build src/target/debug/http-tokio /server
COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6
COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6
COPY --from=build /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1
COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
11 changes: 11 additions & 0 deletions examples/http-tokio/Kraftfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
spec: v0.6

runtime: unikraft.org/base:latest

rootfs: ./Dockerfile

cmd: ["/server"]

targets:
- qemu/x86_64
- fc/x86_64
38 changes: 38 additions & 0 deletions examples/http-tokio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Simple HTTP Tokio Server

This is a simple HTTP server written in [Rust](https://www.rust-lang.org/) using the [`Tokio` runtime](https://tokio.rs/).
To run this example, first [install the `kraft` CLI tool](https://unikraft.org/docs/cli).

Then, clone this repository and `cd` into this directory.
Make sure you have the [BuildKit](https://docs.docker.com/build/buildkit/) container started:

```console
docker run -d --name buildkitd --privileged moby/buildkit:latest
export KRAFTKIT_BUILDKIT_HOST=docker-container://buildkitd
```

Then you can run, as `root`:

```console
kraft net create -n 172.44.0.1/24 virbr0
kraft run -M 256M --network bridge:virbr0 --plat qemu --arch x86_64 --kernel-arg "vfs.fstab=[ initrd:/:initrd::: ]" .
```

If you use sudo, make sure you pass the `KRAFTKIT_BUILDKIT_HOST` variable to the `kraft run` command:

```console
sudo KRAFTKIT_BUILDKIT_HOST=docker-container://buildkitd kraft run -M 256M --network bridge:virbr0 --plat qemu --arch x86_64 --kernel-arg "vfs.fstab=[ initrd:/:initrd::: ]" .
```

Query the server using:

```console
curl 172.44.0.2:8080
```

You will get a `Hello, World!` message.

## Learn More

- [Unikraft's Documentation](https://unikraft.org/docs/cli)
- [How to build `Dockerfile` root filesystems with BuildKit](https://unikraft.org/docs/getting-started/integrations/buildkit)
27 changes: 27 additions & 0 deletions examples/http-tokio/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::net::SocketAddr;
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
let listener = TcpListener::bind(&addr).await?;

println!("Listening on: http://{}", addr);

loop {
let (mut stream, _) = listener.accept().await?;

tokio::spawn(async move {
loop {
let mut buffer = [0; 1024];
let _ = stream.read(&mut buffer).await;

let contents = "Hello, world!\r\n";
let content_length = contents.len();
let response = format!("HTTP/1.1 200 OK\r\nContent-Length: {content_length}\r\n\r\n{contents}");
let _ = stream.write_all(response.as_bytes()).await;
}
});
}
}

0 comments on commit 4d01506

Please sign in to comment.