mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 12:36:46 +00:00
Add mongoose-based http example
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
30a2553a70
commit
c8ec4bb8ba
@ -8,7 +8,7 @@ CUR_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
|
|||||||
INITRAMFS ?= $(CUR_DIR)/../build/initramfs
|
INITRAMFS ?= $(CUR_DIR)/../build/initramfs
|
||||||
REGRESSION_BUILD_DIR ?= $(INITRAMFS)/regression
|
REGRESSION_BUILD_DIR ?= $(INITRAMFS)/regression
|
||||||
|
|
||||||
TEST_APPS := signal_c pthread network hello_world hello_pie hello_c fork_c fork execve pty
|
TEST_APPS := signal_c pthread network hello_world hello_pie hello_c fork_c fork execve pty mongoose
|
||||||
|
|
||||||
C_SOURCES := $(shell find . -type f \( -name "*.c" -or -name "*.h" \) )
|
C_SOURCES := $(shell find . -type f \( -name "*.c" -or -name "*.h" \) )
|
||||||
|
|
||||||
|
47
regression/apps/mongoose/Makefile
Normal file
47
regression/apps/mongoose/Makefile
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
MAIN_MAKEFILE := $(firstword $(MAKEFILE_LIST))
|
||||||
|
INCLUDE_MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||||
|
CUR_DIR := $(shell dirname $(realpath $(MAIN_MAKEFILE)))
|
||||||
|
BUILD_DIR := $(CUR_DIR)/../../build/initramfs/regression/network
|
||||||
|
TARGET_SERVER := $(BUILD_DIR)/http_server
|
||||||
|
TARGET_CLIENT := $(BUILD_DIR)/http_client
|
||||||
|
CC := cc
|
||||||
|
CFLAGS := -W -Wall -Wextra -g -I. -DMG_HTTP_DIRLIST_TIME_FMT="%Y/%m/%d %H:%M:%S" -DMG_ENABLE_LINES=1 -DMG_ENABLE_IPV6=1 -DMG_ENABLE_SSI=1
|
||||||
|
SRC_SERVER := http_server.c mongoose.c
|
||||||
|
SRC_CLIENT := http_client.c mongoose.c
|
||||||
|
DEP := mongoose.h
|
||||||
|
|
||||||
|
.PHONY: all clean mongoose server client
|
||||||
|
|
||||||
|
all: server client
|
||||||
|
|
||||||
|
server: $(TARGET_SERVER)
|
||||||
|
|
||||||
|
client: $(TARGET_CLIENT)
|
||||||
|
|
||||||
|
# Rule to build the http server
|
||||||
|
$(TARGET_SERVER): $(SRC_SERVER) | $(BUILD_DIR)
|
||||||
|
$(CC) $(SRC_SERVER) $(CFLAGS) -o $@
|
||||||
|
|
||||||
|
# Rule to build the http client
|
||||||
|
$(TARGET_CLIENT): $(SRC_CLIENT) | $(BUILD_DIR)
|
||||||
|
$(CC) $(SRC_CLIENT) $(CFLAGS) -o $@
|
||||||
|
|
||||||
|
# Rule to ensure the mongoose dependency is present
|
||||||
|
mongoose:
|
||||||
|
@if [ ! -d "mongoose" ]; then \
|
||||||
|
git clone https://github.com/cesanta/mongoose.git; \
|
||||||
|
fi
|
||||||
|
@cd mongoose && git fetch && git checkout 98782e44c2c095f18b839b09a231328824c23d46
|
||||||
|
@cp mongoose/mongoose.c mongoose/mongoose.h .
|
||||||
|
|
||||||
|
# Rule to create the build directory
|
||||||
|
$(BUILD_DIR):
|
||||||
|
@mkdir -p $@
|
||||||
|
|
||||||
|
# Rule to clean all generated files
|
||||||
|
clean:
|
||||||
|
$(RM) -r $(TARGET_SERVER) $(TARGET_CLIENT) mongoose mongoose.c mongoose.h *.o build
|
||||||
|
|
||||||
|
$(SRC_SERVER) $(SRC_CLIENT): mongoose
|
51
regression/apps/mongoose/http_client.c
Normal file
51
regression/apps/mongoose/http_client.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static const char *s_url = "http://127.0.0.1:8080/";
|
||||||
|
static const char *s_post_data = NULL; // POST data
|
||||||
|
|
||||||
|
// Print HTTP response and signal that we're done
|
||||||
|
static void fn(struct mg_connection *c, int ev, void *ev_data)
|
||||||
|
{
|
||||||
|
if (ev == MG_EV_CONNECT) {
|
||||||
|
// Connected to server. Send request
|
||||||
|
struct mg_str host = mg_url_host(s_url);
|
||||||
|
int content_length = s_post_data ? (int)strlen(s_post_data) : 0;
|
||||||
|
|
||||||
|
mg_printf(c,
|
||||||
|
"%s %s HTTP/1.1\r\n"
|
||||||
|
"Host: %.*s\r\n"
|
||||||
|
"Content-Length: %d\r\n"
|
||||||
|
"\r\n",
|
||||||
|
s_post_data ? "POST" : "GET", mg_url_uri(s_url),
|
||||||
|
(int)host.len, host.ptr, content_length);
|
||||||
|
|
||||||
|
mg_send(c, s_post_data, content_length);
|
||||||
|
} else if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
// Response is received. Print it
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
|
||||||
|
printf("%.*s", (int)hm->message.len, hm->message.ptr);
|
||||||
|
c->is_draining = 1; // Tell mongoose to close this connection
|
||||||
|
*(bool *)c->fn_data = true; // Tell event loop to stop
|
||||||
|
} else if (ev == MG_EV_ERROR) {
|
||||||
|
*(bool *)c->fn_data = true; // Error, tell event loop to stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct mg_mgr mgr;
|
||||||
|
if (argc > 1)
|
||||||
|
s_url = argv[1]; // Use URL provided on the command line
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr); // Initialize event manager
|
||||||
|
|
||||||
|
mg_http_connect(&mgr, s_url, fn, &done); // Create client connection
|
||||||
|
while (!done)
|
||||||
|
mg_mgr_poll(&mgr, 50);
|
||||||
|
|
||||||
|
mg_mgr_free(&mgr); // Free resources
|
||||||
|
return 0;
|
||||||
|
}
|
72
regression/apps/mongoose/http_server.c
Normal file
72
regression/apps/mongoose/http_server.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
static int s_debug_level = MG_LL_INFO;
|
||||||
|
static const char *s_listening_address = "http://127.0.0.1:8080/";
|
||||||
|
|
||||||
|
static int s_signo;
|
||||||
|
static void signal_handler(int signo)
|
||||||
|
{
|
||||||
|
s_signo = signo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event handler for the listening connection.
|
||||||
|
static void cb(struct mg_connection *c, int ev, void *ev_data)
|
||||||
|
{
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
struct mg_http_message *hm = ev_data;
|
||||||
|
if (mg_match(hm->uri, mg_str("/"), NULL)) {
|
||||||
|
// Generate a random number
|
||||||
|
srand(time(NULL));
|
||||||
|
int random_number = rand();
|
||||||
|
char response[100];
|
||||||
|
sprintf(response, "Random number: %d\n", random_number);
|
||||||
|
MG_INFO(("Send a random number : %d", random_number));
|
||||||
|
mg_http_reply(c, 200, "", "%s", response);
|
||||||
|
} else {
|
||||||
|
// Serve 404 for other routes
|
||||||
|
mg_http_reply(c, 404, "", "Not found");
|
||||||
|
}
|
||||||
|
// Remove this line if you need a long running server
|
||||||
|
// signal_handler(SIGTERM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct mg_mgr mgr;
|
||||||
|
struct mg_connection *c;
|
||||||
|
|
||||||
|
// Parse command-line flags
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "-l") == 0) {
|
||||||
|
s_listening_address = argv[++i];
|
||||||
|
} else if (strcmp(argv[i], "-v") == 0) {
|
||||||
|
s_debug_level = atoi(argv[++i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialise stuff
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
signal(SIGTERM, signal_handler);
|
||||||
|
mg_log_set(s_debug_level);
|
||||||
|
mg_mgr_init(&mgr);
|
||||||
|
if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) {
|
||||||
|
MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT",
|
||||||
|
s_listening_address));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start infinite event loop
|
||||||
|
MG_INFO(("Mongoose version : v%s", MG_VERSION));
|
||||||
|
MG_INFO(("Listening on : %s", s_listening_address));
|
||||||
|
while (s_signo == 0)
|
||||||
|
mg_mgr_poll(&mgr, 1000);
|
||||||
|
mg_mgr_free(&mgr);
|
||||||
|
MG_INFO(("Exiting on signal %d", s_signo));
|
||||||
|
return 0;
|
||||||
|
}
|
@ -19,6 +19,7 @@ echo "Start network test......"
|
|||||||
./sockoption
|
./sockoption
|
||||||
./listen_backlog
|
./listen_backlog
|
||||||
# ./send_buf_full
|
# ./send_buf_full
|
||||||
|
./http_server &
|
||||||
|
./http_client
|
||||||
|
|
||||||
echo "All network test passed"
|
echo "All network test passed"
|
||||||
|
Reference in New Issue
Block a user