forked from xavi/libweb
232 lines
4.8 KiB
Groff
232 lines
4.8 KiB
Groff
.TH LIBWEB_HANDLER 7 2023-11-18 0.2.0 "libweb Library Reference"
|
|
|
|
.SH NAME
|
|
libweb_handler \- libweb high-level website configuration
|
|
|
|
.SH SYNOPSIS
|
|
.LP
|
|
.nf
|
|
#include <libweb/handler.h>
|
|
.fi
|
|
|
|
.SH DESCRIPTION
|
|
This component provides abstractions that allow library users to
|
|
define the behaviour of a web server. Whereas
|
|
.IR libweb_http (7)
|
|
defines the HTTP/1.1 server implementation and provides a data type
|
|
(namely
|
|
.IR "struct http_ctx" )
|
|
to handle an incoming connection,
|
|
.IR libweb_handler (7):
|
|
|
|
.IP \(bu 2
|
|
Defines the list of endpoints and supported operations.
|
|
.IP \(bu 2
|
|
Defines the port
|
|
.I libweb
|
|
must listen to.
|
|
.IP \(bu 2
|
|
Keeps track of all
|
|
.I struct http_ctx
|
|
objects.
|
|
|
|
.IR libweb_handler (7)
|
|
provides the following functions:
|
|
|
|
.IP \(bu 2
|
|
.IR handler_alloc (3):
|
|
allocates a
|
|
.I "struct handler"
|
|
object, consumed by other functions from this component.
|
|
|
|
.IP \(bu 2
|
|
.IR handler_free (3):
|
|
frees the memory previously allocated by a call to
|
|
.IR handler_alloc (3).
|
|
|
|
.IP \(bu 2
|
|
.IR handler_add (3):
|
|
adds an endpoint to the server for a given HTTP/1.1
|
|
operation.
|
|
|
|
.IP \(bu 2
|
|
.IR handler_listen (3):
|
|
puts a
|
|
.I "struct handler"
|
|
object to initialize the server and handle connections in a loop.
|
|
|
|
The
|
|
.IR handler_alloc (3)
|
|
function requires some initial configuration parameters, given by
|
|
.IR "struct handler_cfg" ,
|
|
defined as:
|
|
|
|
.PP
|
|
.in +4n
|
|
.EX
|
|
struct handler_cfg
|
|
{
|
|
const char *\fItmpdir\fP;
|
|
int (*\fIlength\fP)(unsigned long long len, const struct http_cookie *c, struct http_response *r, void *user);
|
|
void *\fIuser\fP;
|
|
size_t \fImax_headers\fP;
|
|
};
|
|
.EE
|
|
.in
|
|
.PP
|
|
|
|
.IR tmpdir ,
|
|
.IR length ,
|
|
.I user
|
|
and
|
|
.I max_headers
|
|
are passed directly to the
|
|
.I struct http_cfg
|
|
object used to initialize a
|
|
.I struct http_ctx
|
|
object. See
|
|
.IR libweb_http (7)
|
|
for further reference about these members.
|
|
|
|
However, a
|
|
.I "struct handler"
|
|
object as returned by
|
|
.IR handler_alloc (3)
|
|
alone is not enough. One or more callbacks must be set up to define the
|
|
behaviour of the web server. Every callback must follow the signature
|
|
below, as defined by
|
|
.IR handler_fn :
|
|
|
|
.PP
|
|
.in +4n
|
|
.EX
|
|
typedef int (*\fIhandler_fn\fP)(const struct http_payload *\fIp\fP, struct http_response *\fIr\fP, void *\fIuser\fP);
|
|
.EE
|
|
.in
|
|
.PP
|
|
|
|
Please read
|
|
.IR libweb_http (7)
|
|
for further refence on
|
|
.I "struct http_payload"
|
|
and
|
|
.IR "struct http_response" .
|
|
.I user
|
|
is a user-defined parameter previously defined by a call to
|
|
.IR handler_add (3).
|
|
|
|
.SH EXAMPLE
|
|
|
|
The following source code shows how to set up a simple web server that
|
|
listens to TCP port
|
|
.I 8080
|
|
and defines
|
|
\fI/\fP
|
|
and
|
|
\fI/index.html\fP
|
|
as its endpoints. For the sake of simplicity, a static response body is
|
|
returned, instead of using
|
|
.IR libweb_html (7)
|
|
to generate HTML data. Please read
|
|
.IR libweb_html (7)
|
|
for further reference on how to generate dynamic content.
|
|
|
|
.PP
|
|
.in +4n
|
|
.EX
|
|
#include <libweb/handler.h>
|
|
#include <libweb/http.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
|
|
static int hello(const struct http_payload *const pl,
|
|
struct http_response *const r, void *const user)
|
|
{
|
|
static const char page[] =
|
|
{
|
|
"<html><body><p>Hello from libweb!</p></body></html>"
|
|
};
|
|
|
|
*r = (const struct http_response)
|
|
{
|
|
.status = HTTP_STATUS_OK,
|
|
.buf.ro = page,
|
|
.n = sizeof page - 1
|
|
};
|
|
|
|
if (http_response_add_header(r, "Content-Type", "text/html"))
|
|
{
|
|
fprintf(stderr, "%s: http_response_add_header failed\en", __func__);
|
|
return -1;
|
|
}
|
|
|
|
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
|
|
};
|
|
|
|
struct handler *const h = handler_alloc(&cfg);
|
|
static const char *const urls[] = {"/", "/index.html"};
|
|
|
|
if (!h)
|
|
{
|
|
fprintf(stderr, "%s: handler_alloc failed\en", __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\en", __func__);
|
|
goto end;
|
|
}
|
|
|
|
if (handler_listen(h, port))
|
|
{
|
|
fprintf(stderr, "%s: handler_listen failed\en", __func__);
|
|
goto end;
|
|
}
|
|
|
|
ret = EXIT_SUCCESS;
|
|
|
|
end:
|
|
handler_free(h);
|
|
return ret;
|
|
}
|
|
.EE
|
|
.in
|
|
.PP
|
|
|
|
.SH SEE ALSO
|
|
.BR handler_alloc (3),
|
|
.BR handler_add (3),
|
|
.BR handler_free (3),
|
|
.BR libweb_http (7).
|
|
|
|
.SH COPYRIGHT
|
|
Copyright (C) 2023 Xavier Del Campo Romero.
|
|
.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.
|