1
0
Fork 0

Add PUT server example

This commit is contained in:
Xavier Del Campo 2023-11-17 16:34:45 +01:00
parent 551220b60d
commit 3fb730bc33
Signed by: midokura-xavi
GPG Key ID: A9D49AA996C6753A
7 changed files with 142 additions and 1 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
*.so.*
examples/hello/hello
examples/html/html
examples/put/put

View File

@ -2,3 +2,4 @@ cmake_minimum_required(VERSION 3.13)
add_subdirectory(headers)
add_subdirectory(hello)
add_subdirectory(html)
add_subdirectory(put)

View File

@ -3,7 +3,8 @@
all: \
headers \
hello \
html
html \
put
clean:
+cd hello && $(MAKE) clean

View File

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.13)
project(put C)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} PRIVATE web dynstr)

26
examples/put/Makefile Normal file
View File

@ -0,0 +1,26 @@
.POSIX:
PROJECT = put
DEPS = \
main.o
LIBWEB = ../../libweb.a
DYNSTR = ../../dynstr/libdynstr.a
CFLAGS = -I ../../include -I ../../dynstr/include -g
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)

18
examples/put/README.md Normal file
View File

@ -0,0 +1,18 @@
# HTTP `PUT` example
This example shows a minimal setup for an application using `libweb` that only
accepts `PUT` requests. When executed, it starts a HTTP/1.1 server on a random
port that shall be printed to standard output. When a `PUT` request is received,
`libweb` shall store the body into a file in the `/tmp` directory, and print the
path of the temporary file to the 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.

90
examples/put/main.c Normal file
View File

@ -0,0 +1,90 @@
#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 int on_put(const struct http_payload *const pl,
struct http_response *const r, void *const user)
{
if (pl->expect_continue)
{
*r = (const struct http_response)
{
.status = HTTP_STATUS_CONTINUE
};
return 0;
}
printf("File uploaded to %s\n", pl->u.put.tmpname);
*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_OK
};
return 0;
}
int main(int argc, char *argv[])
{
int ret = EXIT_FAILURE;
const struct handler_cfg cfg =
{
.tmpdir = "/tmp",
.length = on_length
};
struct handler *const h = handler_alloc(&cfg);
static const char *const urls[] = {"/*"};
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_PUT, on_put, NULL))
{
fprintf(stderr, "%s: handler_add failed\n", __func__);
goto end;
}
unsigned short outport;
if (handler_listen(h, 0, &outport))
{
fprintf(stderr, "%s: handler_listen failed\n", __func__);
goto end;
}
printf("Listening on port %hu\n", outport);
if (handler_loop(h))
{
fprintf(stderr, "%s: handler_loop failed\n", __func__);
goto end;
}
ret = EXIT_SUCCESS;
end:
handler_free(h);
return ret;
}