diff --git a/regression/apps/Makefile b/regression/apps/Makefile index 787ce90bd..8a50147e2 100644 --- a/regression/apps/Makefile +++ b/regression/apps/Makefile @@ -8,7 +8,7 @@ CUR_DIR := $(patsubst %/,%,$(dir $(MKFILE_PATH))) INITRAMFS ?= $(CUR_DIR)/../build/initramfs 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" \) ) diff --git a/regression/apps/mongoose/Makefile b/regression/apps/mongoose/Makefile new file mode 100644 index 000000000..bdd709f5f --- /dev/null +++ b/regression/apps/mongoose/Makefile @@ -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 diff --git a/regression/apps/mongoose/http_client.c b/regression/apps/mongoose/http_client.c new file mode 100644 index 000000000..b66e10bbc --- /dev/null +++ b/regression/apps/mongoose/http_client.c @@ -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; +} diff --git a/regression/apps/mongoose/http_server.c b/regression/apps/mongoose/http_server.c new file mode 100644 index 000000000..01d9636e3 --- /dev/null +++ b/regression/apps/mongoose/http_server.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MPL-2.0 + +#include +#include +#include +#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; +} \ No newline at end of file diff --git a/regression/apps/scripts/network.sh b/regression/apps/scripts/network.sh index 5b28f99e6..be90abf3c 100755 --- a/regression/apps/scripts/network.sh +++ b/regression/apps/scripts/network.sh @@ -19,6 +19,7 @@ echo "Start network test......" ./sockoption ./listen_backlog # ./send_buf_full - +./http_server & +./http_client echo "All network test passed"