diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-11-18 00:56:04 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-11-18 01:03:12 +0100 |
| commit | 65031ca3502e0c27780be847fd97c112546741a9 (patch) | |
| tree | 31c8ac5bb815baf5e4b63bde3af9076eb30a30ed /examples | |
| parent | b71a6174e12b4709acaf8bc151938ba12d2a54f6 (diff) | |
Send HTTP headers to payload callback
Even if libweb already parses some common headers, such as
Content-Length, some users might find it interesting to inspect which
headers were received from a request.
Since HTTP/1.1 does not define a limit on the number of maximum headers
a client can send, for security reasons a maximum value must be provided
by the user. Any extra headers shall be then discarded by libweb.
An example application showing this new feature is also provided.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | examples/Makefile | 4 | ||||
| -rw-r--r-- | examples/headers/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | examples/headers/Makefile | 26 | ||||
| -rw-r--r-- | examples/headers/README.md | 16 | ||||
| -rw-r--r-- | examples/headers/main.c | 81 |
6 files changed, 132 insertions, 0 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d9bf4cc..7353458 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,4 @@ cmake_minimum_required(VERSION 3.13) +add_subdirectory(headers) add_subdirectory(hello) add_subdirectory(html) diff --git a/examples/Makefile b/examples/Makefile index b26a13a..672f209 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,6 +1,7 @@ .POSIX: all: \ + headers \ hello \ html @@ -10,6 +11,9 @@ clean: FORCE: +headers: FORCE + +cd headers && $(MAKE) + hello: FORCE +cd hello && $(MAKE) diff --git a/examples/headers/CMakeLists.txt b/examples/headers/CMakeLists.txt new file mode 100644 index 0000000..8c91fd7 --- /dev/null +++ b/examples/headers/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.13) +project(headers C) +add_executable(${PROJECT_NAME} main.c) +target_link_libraries(${PROJECT_NAME} PRIVATE web) diff --git a/examples/headers/Makefile b/examples/headers/Makefile new file mode 100644 index 0000000..4905fbd --- /dev/null +++ b/examples/headers/Makefile @@ -0,0 +1,26 @@ +.POSIX: + +PROJECT = headers +DEPS = \ + main.o +LIBWEB = ../../libweb.a +DYNSTR = ../../dynstr/libdynstr.a +CFLAGS = -I ../../include -I ../../dynstr/include +LIBWEB_FLAGS = -L ../../ -l web +DYNSTR_FLAGS = -L ../../dynstr -l dynstr + +all: $(PROJECT) + +clean: + rm -f $(DEPS) + +FORCE: + +$(PROJECT): $(DEPS) $(LIBWEB) $(DYNSTR) + $(CC) $(LDFLAGS) $(DEPS) $(LIBWEB_FLAGS) $(DYNSTR_FLAGS) -o $@ + +$(LIBWEB): FORCE + +cd ../../ && $(MAKE) + +$(DYNSTR): FORCE + +cd ../../dynstr && $(MAKE) diff --git a/examples/headers/README.md b/examples/headers/README.md new file mode 100644 index 0000000..01c243a --- /dev/null +++ b/examples/headers/README.md @@ -0,0 +1,16 @@ +# HTTP headers example + +This example shows a HTTP/1.1 server that listens to port `8080` and prints +the headers received from the client (up to a maximum of `max_headers`) to +standard output. + +## How to build + +If using `make(1)`, just run `make` from this directory. + +If using CMake, examples are built by default when configuring the project +from [the top-level `CMakeLists.txt`](../../CMakeLists.txt). + +## How to run + +Run the executable without any command line arguments. diff --git a/examples/headers/main.c b/examples/headers/main.c new file mode 100644 index 0000000..b465aa1 --- /dev/null +++ b/examples/headers/main.c @@ -0,0 +1,81 @@ +#include <dynstr.h> +#include <libweb/handler.h> +#include <libweb/html.h> +#include <libweb/http.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> + +static const size_t max_headers = 5; + +static int hello(const struct http_payload *const pl, + struct http_response *const r, void *const user) +{ + printf("Got %zu headers from the client (max %zu).\n", + pl->n_headers, max_headers); + + for (size_t i = 0; i < pl->n_headers; i++) + { + const struct http_header *const h = &pl->headers[i]; + + printf("%s: %s\n", h->header, h->value); + } + + *r = (const struct http_response) + { + .status = HTTP_STATUS_OK + }; + + return 0; +} + +static int on_length(const unsigned long long len, + const struct http_cookie *const c, struct http_response *const r, + void *const user) +{ + *r = (const struct http_response) + { + .status = HTTP_STATUS_FORBIDDEN + }; + + return 1; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + const short port = 8080; + const struct handler_cfg cfg = + { + .length = on_length, + .max_headers = max_headers + }; + + struct handler *const h = handler_alloc(&cfg); + static const char *const urls[] = {"/", "/index.html"}; + + if (!h) + { + fprintf(stderr, "%s: handler_alloc failed\n", __func__); + goto end; + } + + for (size_t i = 0; i < sizeof urls / sizeof *urls; i++) + if (handler_add(h, urls[i], HTTP_OP_GET, hello, NULL)) + { + fprintf(stderr, "%s: handler_add failed\n", __func__); + goto end; + } + + if (handler_listen(h, port)) + { + fprintf(stderr, "%s: handler_listen failed\n", __func__); + goto end; + } + + ret = EXIT_SUCCESS; + +end: + handler_free(h); + return ret; +} |
