-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(examples): Introduce HTTP C application (#3)
Approved-by: Alexander Jung <[email protected]>
- Loading branch information
Showing
4 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
spec: v0.6 | ||
|
||
name: http-c | ||
|
||
unikraft: | ||
version: stable | ||
kconfig: | ||
CONFIG_LIBUKBUS: 'y' | ||
|
||
targets: | ||
- qemu/x86_64 | ||
- qemu/arm64 | ||
- fc/x86_64 | ||
- xen/x86_64 | ||
- linuxu/x86_64 | ||
- linuxu/arm64 | ||
|
||
libraries: | ||
lwip: | ||
version: stable | ||
kconfig: | ||
CONFIG_LWIP_UKNETDEV: 'y' | ||
CONFIG_LWIP_TCP: 'y' | ||
CONFIG_LWIP_THREADS: 'y' | ||
CONFIG_LWIP_SOCKET: 'y' | ||
CONFIG_LWIP_AUTOIFACE: 'y' | ||
CONFIG_LWIP_IPV4: 'y' | ||
CONFIG_LWIP_DHCP: 'y' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
$(eval $(call addlib,apphttpreply)) | ||
|
||
APPHTTPREPLY_SRCS-y += $(APPHTTPREPLY_BASE)/main.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Simple HTTP C Server on Unikraft | ||
|
||
This directory contains a simple HTTP server written in C running with Unikraft. | ||
The image opens up a simple HTTP server and provides a simple HTML response for each request. | ||
|
||
To run this example, [install Unikraft's companion command-line toolchain `kraft`](https://unikraft.org/docs/cli). | ||
|
||
Then, clone this repository and `cd` into this directory. | ||
You can then build the project with: | ||
|
||
```console | ||
kraft build | ||
``` | ||
|
||
In the above command, `kraft build` will prompt you with the target you wish to compile for. | ||
If you are unsure, select `qemu/` and your host's architecture, e.g. `qemu/x86_64`. | ||
|
||
Once built, you can execute the unikernel via: | ||
|
||
```console | ||
kraft run -p 8080:8080 | ||
``` | ||
|
||
Once executed, query the simple HTTP server: | ||
|
||
```console | ||
curl localhost:8080 | ||
``` | ||
|
||
## Learn more | ||
|
||
- [How to build unikernels](https://unikraft.org/docs/cli/building) | ||
- [How to run unikernels locally](https://unikraft.org/docs/cli/running) | ||
- [The `Kraftfile` specification](https://unikraft.org/docs/cli/reference/kraftfile/latest) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* SPDX-License-Identifier: BSD-3-Clause */ | ||
/* | ||
* Authors: Simon Kuenzer <[email protected]> | ||
* | ||
* Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation. | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
* POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <sys/socket.h> | ||
#include <arpa/inet.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
|
||
#define LISTEN_PORT 8080 | ||
static const char reply[] = "HTTP/1.1 200 OK\r\n" \ | ||
"Content-type: text/html\r\n" \ | ||
"Connection: close\r\n" \ | ||
"\r\n" \ | ||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" \ | ||
"<html>" \ | ||
"<head><title>It works!</title></head>" \ | ||
"<body><h1>It works!</h1><p>This is only a test.</p></body>" \ | ||
"</html>\n"; | ||
|
||
#define BUFLEN 2048 | ||
static char recvbuf[BUFLEN]; | ||
|
||
int main(int argc __attribute__((unused)), | ||
char *argv[] __attribute__((unused))) | ||
{ | ||
int rc = 0; | ||
int srv, client; | ||
ssize_t n; | ||
struct sockaddr_in srv_addr; | ||
|
||
srv = socket(AF_INET, SOCK_STREAM, 0); | ||
if (srv < 0) { | ||
fprintf(stderr, "Failed to create socket: %d\n", errno); | ||
goto out; | ||
} | ||
|
||
srv_addr.sin_family = AF_INET; | ||
srv_addr.sin_addr.s_addr = INADDR_ANY; | ||
srv_addr.sin_port = htons(LISTEN_PORT); | ||
|
||
rc = bind(srv, (struct sockaddr *) &srv_addr, sizeof(srv_addr)); | ||
if (rc < 0) { | ||
fprintf(stderr, "Failed to bind socket: %d\n", errno); | ||
goto out; | ||
} | ||
|
||
/* Accept one simultaneous connection */ | ||
rc = listen(srv, 1); | ||
if (rc < 0) { | ||
fprintf(stderr, "Failed to listen on socket: %d\n", errno); | ||
goto out; | ||
} | ||
|
||
printf("Listening on port %d...\n", LISTEN_PORT); | ||
while (1) { | ||
client = accept(srv, NULL, 0); | ||
if (client < 0) { | ||
fprintf(stderr, | ||
"Failed to accept incoming connection: %d\n", | ||
errno); | ||
goto out; | ||
} | ||
|
||
/* Receive some bytes (ignore errors) */ | ||
read(client, recvbuf, BUFLEN); | ||
|
||
/* Send reply */ | ||
n = write(client, reply, sizeof(reply) - 1); | ||
if (n < 0) | ||
fprintf(stderr, "Failed to send a reply\n"); | ||
else | ||
printf("Sent a reply\n"); | ||
|
||
/* Close connection */ | ||
close(client); | ||
} | ||
|
||
out: | ||
return rc; | ||
} |