net: http_server: Add wildcard support to resource strings

Allow user to specify resource string using wildcard characters
so that multiple URL paths can be served with just one handler.

Fixes #73367

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
Jukka Rissanen 2024-05-29 15:35:41 +03:00 committed by David Leach
commit 08dc8f93fe
3 changed files with 37 additions and 0 deletions

View file

@ -130,6 +130,24 @@ Alternatively, an HTTPS service can be defined with with
Once HTTP(s) service is defined, resources can be registered for it with Once HTTP(s) service is defined, resources can be registered for it with
:c:macro:`HTTP_RESOURCE_DEFINE` macro. :c:macro:`HTTP_RESOURCE_DEFINE` macro.
Application can enable resource wildcard support by enabling
:kconfig:option:`CONFIG_HTTP_SERVER_RESOURCE_WILDCARD` option. When this
option is set, then it is possible to match several incoming HTTP requests
with just one resource handler. The `fnmatch()
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html>`__
POSIX API function is used to match the pattern in the URL paths.
Example:
.. code-block:: c
HTTP_RESOURCE_DEFINE(my_resource, my_service, "/foo*", &resource_detail);
This would match all URLs that start with a string ``foo``. See
`POSIX.2 chapter 2.13
<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13>`__
for pattern matching syntax description.
Static resources Static resources
================ ================

View file

@ -115,6 +115,14 @@ config HTTP_SERVER_WEBSOCKET
handler that is called after upgrading to handle the Websocket network handler that is called after upgrading to handle the Websocket network
traffic. traffic.
config HTTP_SERVER_RESOURCE_WILDCARD
bool "Allow wildcard matching of resources"
select FNMATCH
help
Allow user to specify wildcards when setting up resource strings.
This means that instead of specifying multiple resources with exact
string matches, one resource handler could handle multiple URLs.
endif endif
# Hidden option to avoid having multiple individual options that are ORed together # Hidden option to avoid having multiple individual options that are ORed together

View file

@ -19,6 +19,7 @@
#include <zephyr/net/socket.h> #include <zephyr/net/socket.h>
#include <zephyr/net/tls_credentials.h> #include <zephyr/net/tls_credentials.h>
#include <zephyr/posix/sys/eventfd.h> #include <zephyr/posix/sys/eventfd.h>
#include <zephyr/posix/fnmatch.h>
LOG_MODULE_REGISTER(net_http_server, CONFIG_NET_HTTP_SERVER_LOG_LEVEL); LOG_MODULE_REGISTER(net_http_server, CONFIG_NET_HTTP_SERVER_LOG_LEVEL);
@ -661,6 +662,16 @@ struct http_resource_detail *get_resource_detail(const char *path,
continue; continue;
} }
if (IS_ENABLED(CONFIG_HTTP_SERVER_RESOURCE_WILDCARD)) {
int ret;
ret = fnmatch(resource->resource, path, FNM_PATHNAME);
if (ret == 0) {
*path_len = strlen(resource->resource);
return resource->detail;
}
}
if (compare_strings(path, resource->resource) == 0) { if (compare_strings(path, resource->resource) == 0) {
NET_DBG("Got match for %s", resource->resource); NET_DBG("Got match for %s", resource->resource);