aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--doc/man3/Makefile1
-rw-r--r--doc/man3/handler_add.33
-rw-r--r--doc/man3/handler_alloc.35
-rw-r--r--doc/man3/handler_listen.351
-rw-r--r--doc/man3/handler_loop.375
-rw-r--r--doc/man7/libweb_handler.719
-rw-r--r--examples/hello/README.md10
-rw-r--r--examples/hello/main.c13
-rw-r--r--handler.c10
-rw-r--r--include/libweb/handler.h4
-rw-r--r--include/libweb/server.h2
-rw-r--r--server.c6
13 files changed, 149 insertions, 52 deletions
diff --git a/README.md b/README.md
index 7fba559..3ca44ef 100644
--- a/README.md
+++ b/README.md
@@ -178,7 +178,7 @@ essential for `slcl`.
```
libweb, a simple and lightweight web framework.
-Copyright (C) 2023 Xavier Del Campo Romero
+Copyright (C) 2023 libweb contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
diff --git a/doc/man3/Makefile b/doc/man3/Makefile
index c1a111d..6c0d414 100644
--- a/doc/man3/Makefile
+++ b/doc/man3/Makefile
@@ -9,6 +9,7 @@ OBJECTS = \
$(DESTDIR)$(man3dir)/handler_alloc.3 \
$(DESTDIR)$(man3dir)/handler_free.3 \
$(DESTDIR)$(man3dir)/handler_listen.3 \
+ $(DESTDIR)$(man3dir)/handler_loop.3 \
$(DESTDIR)$(man3dir)/html_node_add_attr.3 \
$(DESTDIR)$(man3dir)/html_node_add_child.3 \
$(DESTDIR)$(man3dir)/html_node_add_sibling.3 \
diff --git a/doc/man3/handler_add.3 b/doc/man3/handler_add.3
index 2ee404b..3a022ef 100644
--- a/doc/man3/handler_add.3
+++ b/doc/man3/handler_add.3
@@ -77,10 +77,11 @@ for a list of possible errors.
.BR handler_alloc (3),
.BR handler_free (3),
.BR handler_listen (3),
+.BR handler_loop (3),
.BR libweb_handler (7).
.SH COPYRIGHT
-Copyright (C) 2023 Xavier Del Campo Romero.
+Copyright (C) 2023 libweb contributors.
.P
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
diff --git a/doc/man3/handler_alloc.3 b/doc/man3/handler_alloc.3
index 3b602dc..040bc98 100644
--- a/doc/man3/handler_alloc.3
+++ b/doc/man3/handler_alloc.3
@@ -1,4 +1,4 @@
-.TH HANDLER_ALLOC 3 2023-09-13 0.1.0 "libweb Library Reference"
+.TH HANDLER_ALLOC 3 2023-11-16 0.2.0 "libweb Library Reference"
.SH NAME
handler_alloc \- allocate a web server handler object
@@ -48,10 +48,11 @@ for a list of possible errors.
.BR handler_free (3),
.BR handler_add (3),
.BR handler_listen (3),
+.BR handler_loop (3),
.BR libweb_handler (7).
.SH COPYRIGHT
-Copyright (C) 2023 Xavier Del Campo Romero.
+Copyright (C) 2023 libweb contributors.
.P
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
diff --git a/doc/man3/handler_listen.3 b/doc/man3/handler_listen.3
index ce001c7..416069d 100644
--- a/doc/man3/handler_listen.3
+++ b/doc/man3/handler_listen.3
@@ -1,42 +1,37 @@
-.TH HANDLER_LISTEN 3 2023-09-14 0.1.0 "libweb Library Reference"
+.TH HANDLER_LISTEN 3 2023-11-16 0.2.0 "libweb Library Reference"
.SH NAME
-handler_listen \- listen to and handle incoming connections on a web
-server
+handler_listen \- initialize server to listen to a given port
.SH SYNOPSIS
.LP
.nf
#include <libweb/handler.h>
.P
-int handler_listen(struct handler *\fIh\fP, unsigned short \fIport\fP);
+int handler_listen(struct handler *\fIh\fP, unsigned short \fIport\fP, unsigned short *\fIoutport\fP);
.fi
.SH DESCRIPTION
The
.IR handler_listen (3)
-function listens for connections on the TCP port number given by
-.I port
-on a
+function initializes the internal server on a
.I struct handler
object pointed to by
.IR h ,
which must be previously allocated by a call to
-.IR handler_alloc (3).
+.IR handler_alloc (3),
+to listen on the TCP port given by
+.IR port .
-Also, the
+If
+.I outport
+is a valid pointer,
.IR handler_listen (3)
-function validates incoming requests and calls the configured
-callbacks previously given by one or more calls to
-.IR handler_add (3).
-
-The
-.IR handler_listen (3)
-function blocks until either
-.I SIGTERM
-or
-.I SIGINT
-are triggered.
+shall assign the object pointed to by
+.I outport
+to the port number the server shall listen to. This is typically meant
+for servers that listen on any port, but the caller needs to know which
+port was eventually selected by the implementation.
.SH RETURN VALUE
On success, zero is returned. On error, a negative integer is returned.
@@ -44,28 +39,16 @@ On success, zero is returned. On error, a negative integer is returned.
.SH ERRORS
No errors are defined.
-.SH FUTURE DIRECTIONS
-When no configured endpoint matches the incoming request,
-.I libweb
-shall respond with a
-.B 404 Not Found
-HTTP status code with no payload. Since some library users might want
-to provide custom pages for such error condition, future versions of
-this library shall replace the harcoded response with an additional
-callback on
-.IR "struct handler_cfg" ,
-similarly to its member
-.IR length .
-
.SH SEE ALSO
.BR handler_alloc (3),
.BR handler_free (3),
.BR handler_add (3),
+.BR handler_loop (3),
.BR libweb_handler (7),
.BR signal (7).
.SH COPYRIGHT
-Copyright (C) 2023 Xavier Del Campo Romero.
+Copyright (C) 2023 libweb contributors.
.P
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
diff --git a/doc/man3/handler_loop.3 b/doc/man3/handler_loop.3
new file mode 100644
index 0000000..d442e41
--- /dev/null
+++ b/doc/man3/handler_loop.3
@@ -0,0 +1,75 @@
+.TH HANDLER_LOOP 3 2023-11-16 0.2.0 "libweb Library Reference"
+
+.SH NAME
+handler_loop \- listen to and handle incoming connections on a web
+server
+
+.SH SYNOPSIS
+.LP
+.nf
+#include <libweb/handler.h>
+.P
+int handler_loop(struct handler *\fIh\fP);
+.fi
+
+.SH DESCRIPTION
+The
+.IR handler_loop (3)
+function listens for connections on a
+.I struct handler
+object pointed to by
+.IR h ,
+which must be previously allocated by a call to
+.IR handler_alloc (3)
+and initialized by a call to
+.IR handler_listen (3),
+in a loop.
+
+Also, the
+.IR handler_loop (3)
+function validates incoming requests and calls the configured
+callbacks previously given by one or more calls to
+.IR handler_add (3).
+
+The
+.IR handler_loop (3)
+function blocks until either
+.I SIGTERM
+or
+.I SIGINT
+are triggered.
+
+.SH RETURN VALUE
+On success, zero is returned. On error, a negative integer is returned.
+
+.SH ERRORS
+No errors are defined.
+
+.SH FUTURE DIRECTIONS
+When no configured endpoint matches the incoming request,
+.I libweb
+shall respond with a
+.B 404 Not Found
+HTTP status code with no payload. Since some library users might want
+to provide custom pages for such error condition, future versions of
+this library shall replace the harcoded response with an additional
+callback on
+.IR "struct handler_cfg" ,
+similarly to its member
+.IR length .
+
+.SH SEE ALSO
+.BR handler_alloc (3),
+.BR handler_free (3),
+.BR handler_add (3),
+.BR handler_listen (3),
+.BR libweb_handler (7),
+.BR signal (7).
+
+.SH COPYRIGHT
+Copyright (C) 2023 libweb contributors.
+.P
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
diff --git a/doc/man7/libweb_handler.7 b/doc/man7/libweb_handler.7
index b9fd53f..1548b6b 100644
--- a/doc/man7/libweb_handler.7
+++ b/doc/man7/libweb_handler.7
@@ -51,9 +51,15 @@ operation.
.IP \(bu 2
.IR handler_listen (3):
+initializes the server on a
+.I "struct handler"
+object to listen on a given port.
+
+.IP \(bu 2
+.IR handler_loop (3):
puts a
.I "struct handler"
-object to initialize the server and handle connections in a loop.
+object to handle connections in a loop.
The
.IR handler_alloc (3)
@@ -200,11 +206,16 @@ int main(int argc, char *argv[])
goto end;
}
- if (handler_listen(h, port))
+ if (handler_listen(h, port, NULL))
{
fprintf(stderr, "%s: handler_listen failed\en", __func__);
goto end;
}
+ else if (handler_loop(h))
+ {
+ fprintf(stderr, "%s: handler_loop failed\en", __func__);
+ goto end;
+ }
ret = EXIT_SUCCESS;
@@ -220,10 +231,12 @@ end:
.BR handler_alloc (3),
.BR handler_add (3),
.BR handler_free (3),
+.BR handler_listen (3),
+.BR handler_loop (3),
.BR libweb_http (7).
.SH COPYRIGHT
-Copyright (C) 2023 Xavier Del Campo Romero.
+Copyright (C) 2023 libweb contributors.
.P
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
diff --git a/examples/hello/README.md b/examples/hello/README.md
index 24b747b..79c57fc 100644
--- a/examples/hello/README.md
+++ b/examples/hello/README.md
@@ -1,9 +1,13 @@
# "Hello world" example
This example shows a minimal setup for an application using `libweb`. When
-executed, it starts a HTTP/1.1 server on port `8080` and returns an example
-website reading "Hello from libweb!" when either `/` or `/index.html` are
-accessed by clients.
+executed, it starts a HTTP/1.1 server on a random port, which is then printed
+to the standard output, and returns an example website when either `/` or
+`/index.html` are accessed by clients, reading:
+
+```
+Hello from libweb!
+```
## How to build
diff --git a/examples/hello/main.c b/examples/hello/main.c
index 59643ec..62e2a9e 100644
--- a/examples/hello/main.c
+++ b/examples/hello/main.c
@@ -81,7 +81,6 @@ static int on_length(const unsigned long long len,
int main(int argc, char *argv[])
{
int ret = EXIT_FAILURE;
- const short port = 8080;
const struct handler_cfg cfg =
{
.length = on_length
@@ -103,12 +102,22 @@ int main(int argc, char *argv[])
goto end;
}
- if (handler_listen(h, port))
+ 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:
diff --git a/handler.c b/handler.c
index f6e47a3..4abbdb8 100644
--- a/handler.c
+++ b/handler.c
@@ -182,14 +182,20 @@ end:
return ret;
}
-int handler_listen(struct handler *const h, const unsigned short port)
+int handler_listen(struct handler *const h, const unsigned short port,
+ unsigned short *const outport)
{
- if (!(h->server = server_init(port)))
+ if (!(h->server = server_init(port, outport)))
{
fprintf(stderr, "%s: server_init failed\n", __func__);
return -1;
}
+ return 0;
+}
+
+int handler_loop(struct handler *const h)
+{
for (;;)
{
bool exit, io;
diff --git a/include/libweb/handler.h b/include/libweb/handler.h
index f7bc76a..493e24c 100644
--- a/include/libweb/handler.h
+++ b/include/libweb/handler.h
@@ -20,6 +20,8 @@ struct handler *handler_alloc(const struct handler_cfg *cfg);
void handler_free(struct handler *h);
int handler_add(struct handler *h, const char *url, enum http_op op,
handler_fn f, void *user);
-int handler_listen(struct handler *h, unsigned short port);
+int handler_listen(struct handler *h, unsigned short port,
+ unsigned short *outport);
+int handler_loop(struct handler *h);
#endif /* HANDLER_H */
diff --git a/include/libweb/server.h b/include/libweb/server.h
index 74f06ae..b3691aa 100644
--- a/include/libweb/server.h
+++ b/include/libweb/server.h
@@ -4,7 +4,7 @@
#include <stdbool.h>
#include <stddef.h>
-struct server *server_init(unsigned short port);
+struct server *server_init(unsigned short port, unsigned short *outport);
struct server_client *server_poll(struct server *s, bool *io, bool *exit);
int server_read(void *buf, size_t n, struct server_client *c);
int server_write(const void *buf, size_t n, struct server_client *c);
diff --git a/server.c b/server.c
index 8cea044..d460155 100644
--- a/server.c
+++ b/server.c
@@ -320,7 +320,8 @@ static int init_signals(void)
return 0;
}
-struct server *server_init(const unsigned short port)
+struct server *server_init(const unsigned short port,
+ unsigned short *const outport)
{
struct server *const s = malloc(sizeof *s);
@@ -373,8 +374,9 @@ struct server *server_init(const unsigned short port)
fprintf(stderr, "%s: getsockname(2): %s\n", __func__, strerror(errno));
goto failure;
}
+ else if (outport)
+ *outport = ntohs(in.sin_port);
- printf("Listening on port %hu\n", ntohs(in.sin_port));
return s;
failure: