LCOV - code coverage report
Current view: top level - zephyr/net/http - service.h Coverage Total Hit
Test: new.info Lines: 100.0 % 14 14
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2022 Meta
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_NET_HTTP_SERVICE_H_
       8              : #define ZEPHYR_INCLUDE_NET_HTTP_SERVICE_H_
       9              : 
      10              : /**
      11              :  * @file service.h
      12              :  *
      13              :  * @brief HTTP service API
      14              :  *
      15              :  * @defgroup http_service HTTP service API
      16              :  * @since 3.4
      17              :  * @version 0.1.0
      18              :  * @ingroup networking
      19              :  * @{
      20              :  */
      21              : 
      22              : #include "zephyr/net/http/server.h"
      23              : #include <stdint.h>
      24              : #include <stddef.h>
      25              : 
      26              : #include <zephyr/sys/util_macro.h>
      27              : #include <zephyr/sys/iterable_sections.h>
      28              : #include <zephyr/net/tls_credentials.h>
      29              : 
      30              : #ifdef __cplusplus
      31              : extern "C" {
      32              : #endif
      33              : 
      34              : /** HTTP resource description */
      35            1 : struct http_resource_desc {
      36              :         /** Resource name */
      37            1 :         const char *resource;
      38              :         /** Detail associated with this resource */
      39            1 :         void *detail;
      40              : };
      41              : 
      42              : /**
      43              :  * @brief Define a static HTTP resource
      44              :  *
      45              :  * A static HTTP resource is one that is known prior to system initialization. In contrast,
      46              :  * dynamic resources may be discovered upon system initialization. Dynamic resources may also be
      47              :  * inserted, or removed by events originating internally or externally to the system at runtime.
      48              :  *
      49              :  * @note The @p _resource is the URL without the associated protocol, host, or URL parameters. E.g.
      50              :  * the resource for `http://www.foo.com/bar/baz.html#param1=value1` would be `/bar/baz.html`. It
      51              :  * is often referred to as the "path" of the URL. Every `(service, resource)` pair should be
      52              :  * unique. The @p _resource must be non-NULL.
      53              :  *
      54              :  * @param _name Name of the resource.
      55              :  * @param _service Name of the associated service.
      56              :  * @param _resource Pathname-like string identifying the resource.
      57              :  * @param _detail Implementation-specific detail associated with the resource.
      58              :  */
      59            1 : #define HTTP_RESOURCE_DEFINE(_name, _service, _resource, _detail)                                  \
      60              :         const STRUCT_SECTION_ITERABLE_ALTERNATE(http_resource_desc_##_service, http_resource_desc, \
      61              :                                                 _name) = {                                         \
      62              :                 .resource = _resource,                                                             \
      63              :                 .detail = (void *)(_detail),                                                       \
      64              :         }
      65              : 
      66              : /** @cond INTERNAL_HIDDEN */
      67              : 
      68              : struct http_service_runtime_data {
      69              :         int num_clients;
      70              : };
      71              : 
      72              : struct http_service_desc;
      73              : 
      74              : /** Custom socket creation function type */
      75              : typedef int (*http_socket_create_fn)(const struct http_service_desc *svc, int af, int proto);
      76              : 
      77              : /** HTTP service configuration */
      78              : struct http_service_config {
      79              :         /** Custom socket creation for the service if needed */
      80              :         http_socket_create_fn socket_create;
      81              :         /* If any more service-specific configuration is needed, it can be added here. */
      82              : };
      83              : 
      84              : struct http_service_desc {
      85              :         const char *host;
      86              :         uint16_t *port;
      87              :         int *fd;
      88              :         void *detail;
      89              :         size_t concurrent;
      90              :         size_t backlog;
      91              :         struct http_service_runtime_data *data;
      92              :         struct http_resource_desc *res_begin;
      93              :         struct http_resource_desc *res_end;
      94              :         struct http_resource_detail *res_fallback;
      95              :         const struct http_service_config *config;
      96              : #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
      97              :         const sec_tag_t *sec_tag_list;
      98              :         size_t sec_tag_list_size;
      99              : #endif
     100              : };
     101              : 
     102              : #define __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail,               \
     103              :                                 _res_fallback, _res_begin, _res_end, _config, ...)                 \
     104              :         BUILD_ASSERT(_concurrent <= CONFIG_HTTP_SERVER_MAX_CLIENTS,                                \
     105              :                      "can't accept more then MAX_CLIENTS");                                        \
     106              :         BUILD_ASSERT(_backlog > 0, "backlog can't be 0");                                          \
     107              :         static int _name##_fd = -1;                                                                \
     108              :         static struct http_service_runtime_data _name##_data = {0};                                \
     109              :         const STRUCT_SECTION_ITERABLE(http_service_desc, _name) = {                                \
     110              :                 .host = _host,                                                                     \
     111              :                 .port = (uint16_t *)(_port),                                                       \
     112              :                 .fd = &_name##_fd,                                                                 \
     113              :                 .detail = (void *)(_detail),                                                       \
     114              :                 .concurrent = (_concurrent),                                                       \
     115              :                 .backlog = (_backlog),                                                             \
     116              :                 .data = &_name##_data,                                                             \
     117              :                 .res_begin = (_res_begin),                                                         \
     118              :                 .res_end = (_res_end),                                                             \
     119              :                 .res_fallback = (_res_fallback),                                                   \
     120              :                 .config = (_config),                                                               \
     121              :                 COND_CODE_1(CONFIG_NET_SOCKETS_SOCKOPT_TLS,                                        \
     122              :                             (.sec_tag_list = COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), (NULL),  \
     123              :                                                          (GET_ARG_N(1, __VA_ARGS__))),), ())       \
     124              :                 COND_CODE_1(CONFIG_NET_SOCKETS_SOCKOPT_TLS,                                        \
     125              :                             (.sec_tag_list_size = COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), (0),\
     126              :                                              (GET_ARG_N(1, GET_ARGS_LESS_N(1, __VA_ARGS__))))), ())\
     127              :         }
     128              : 
     129              : /** @endcond */
     130              : 
     131              : /**
     132              :  * @brief Define an HTTP service without static resources.
     133              :  *
     134              :  * @note The @p _host parameter is used to specify an IP address either in
     135              :  * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. If left NULL, the listening
     136              :  * port will listen on all addresses.
     137              :  *
     138              :  * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port
     139              :  * number to use for the service. If the specified port number is zero, then an ephemeral port
     140              :  * number will be used and the actual port number assigned will be written back to memory. For
     141              :  * ephemeral port numbers, the memory pointed to by @p _port must be writeable.
     142              :  *
     143              :  * @param _name Name of the service.
     144              :  * @param _host IP address or hostname associated with the service.
     145              :  * @param[inout] _port Pointer to port associated with the service.
     146              :  * @param _concurrent Maximum number of concurrent clients. (max. CONFIG_HTTP_SERVER_MAX_CLIENTS)
     147              :  * @param _backlog Maximum number of queued connections. (min. 1)
     148              :  * @param _detail User-defined detail associated with the service.
     149              :  * @param _res_fallback Fallback resource to be served if no other resource matches path
     150              :  * @param _config Pointer to http_service_config structure (can be NULL for default behavior)
     151              :  */
     152              : #define HTTP_SERVICE_DEFINE_EMPTY(_name, _host, _port, _concurrent, _backlog, _detail,             \
     153            1 :                                   _res_fallback, _config)                                          \
     154              :         __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail,               \
     155              :                                 _res_fallback, NULL, NULL, _config)
     156              : 
     157              : /**
     158              :  * @brief Define an HTTPS service without static resources.
     159              :  *
     160              :  * @note The @p _host parameter is used to specify an IP address either in
     161              :  * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. If left NULL, the listening
     162              :  * port will listen on all addresses.
     163              :  *
     164              :  * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port
     165              :  * number to use for the service. If the specified port number is zero, then an ephemeral port
     166              :  * number will be used and the actual port number assigned will be written back to memory. For
     167              :  * ephemeral port numbers, the memory pointed to by @p _port must be writeable.
     168              :  *
     169              :  * @param _name Name of the service.
     170              :  * @param _host IP address or hostname associated with the service.
     171              :  * @param[inout] _port Pointer to port associated with the service.
     172              :  * @param _concurrent Maximum number of concurrent clients. (max. CONFIG_HTTP_SERVER_MAX_CLIENTS)
     173              :  * @param _backlog Maximum number of queued connections. (min. 1)
     174              :  * @param _detail User-defined detail associated with the service.
     175              :  * @param _res_fallback Fallback resource to be served if no other resource matches path
     176              :  * @param _config Pointer to http_service_config structure (can be NULL for default behavior)
     177              :  * @param _sec_tag_list TLS security tag list used to setup a HTTPS socket.
     178              :  * @param _sec_tag_list_size TLS security tag list size used to setup a HTTPS socket.
     179              :  */
     180              : #define HTTPS_SERVICE_DEFINE_EMPTY(_name, _host, _port, _concurrent, _backlog, _detail,          \
     181            1 :                                    _res_fallback, _config, _sec_tag_list, _sec_tag_list_size)    \
     182              :         __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail,             \
     183              :                                 _res_fallback, NULL, NULL, _config,                              \
     184              :                                 _sec_tag_list, _sec_tag_list_size);                              \
     185              :         BUILD_ASSERT(IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS),                                 \
     186              :                      "TLS is required for HTTP secure (CONFIG_NET_SOCKETS_SOCKOPT_TLS)")
     187              : 
     188              : /**
     189              :  * @brief Define an HTTP service with static resources.
     190              :  *
     191              :  * @note The @p _host parameter is used to specify an IP address either in
     192              :  * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. If left NULL, the listening
     193              :  * port will listen on all addresses.
     194              :  *
     195              :  * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port
     196              :  * number to use for the service. If the specified port number is zero, then an ephemeral port
     197              :  * number will be used and the actual port number assigned will be written back to memory. For
     198              :  * ephemeral port numbers, the memory pointed to by @p _port must be writeable.
     199              :  *
     200              :  * @param _name Name of the service.
     201              :  * @param _host IP address or hostname associated with the service.
     202              :  * @param[inout] _port Pointer to port associated with the service.
     203              :  * @param _concurrent Maximum number of concurrent clients. (max. CONFIG_HTTP_SERVER_MAX_CLIENTS)
     204              :  * @param _backlog Maximum number of queued connections. (min. 1)
     205              :  * @param _detail User-defined detail associated with the service.
     206              :  * @param _res_fallback Fallback resource to be served if no other resource matches path
     207              :  * @param _config Pointer to http_service_config structure (can be NULL for default behavior)
     208              :  */
     209              : #define HTTP_SERVICE_DEFINE(_name, _host, _port, _concurrent, _backlog, _detail, _res_fallback,    \
     210            1 :                             _config)                                                               \
     211              :         extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_start)[];      \
     212              :         extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_end)[];        \
     213              :         __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail,               \
     214              :                                 _res_fallback,                                                     \
     215              :                                 &_CONCAT(_http_resource_desc_##_name, _list_start)[0],             \
     216              :                                 &_CONCAT(_http_resource_desc_##_name, _list_end)[0], _config);
     217              : 
     218              : /**
     219              :  * @brief Define an HTTPS service with static resources.
     220              :  *
     221              :  * @note The @p _host parameter is used to specify an IP address either in
     222              :  * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. If left NULL, the listening
     223              :  * port will listen on all addresses.
     224              :  *
     225              :  * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port
     226              :  * number to use for the service. If the specified port number is zero, then an ephemeral port
     227              :  * number will be used and the actual port number assigned will be written back to memory. For
     228              :  * ephemeral port numbers, the memory pointed to by @p _port must be writeable.
     229              :  *
     230              :  * @param _name Name of the service.
     231              :  * @param _host IP address or hostname associated with the service.
     232              :  * @param[inout] _port Pointer to port associated with the service.
     233              :  * @param _concurrent Maximum number of concurrent clients. (max. CONFIG_HTTP_SERVER_MAX_CLIENTS)
     234              :  * @param _backlog Maximum number of queued connections. (min. 1)
     235              :  * @param _detail User-defined detail associated with the service.
     236              :  * @param _res_fallback Fallback resource to be served if no other resource matches path
     237              :  * @param _config Pointer to http_service_config structure (can be NULL for default behavior)
     238              :  * @param _sec_tag_list TLS security tag list used to setup a HTTPS socket.
     239              :  * @param _sec_tag_list_size TLS security tag list size used to setup a HTTPS socket.
     240              :  */
     241              : #define HTTPS_SERVICE_DEFINE(_name, _host, _port, _concurrent, _backlog, _detail,              \
     242            1 :                              _res_fallback, _config, _sec_tag_list, _sec_tag_list_size)        \
     243              :         extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_start)[];  \
     244              :         extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_end)[];    \
     245              :         __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail,           \
     246              :                                 _res_fallback,                                                 \
     247              :                                 &_CONCAT(_http_resource_desc_##_name, _list_start)[0],         \
     248              :                                 &_CONCAT(_http_resource_desc_##_name, _list_end)[0], _config,  \
     249              :                                 _sec_tag_list, _sec_tag_list_size);                            \
     250              :         BUILD_ASSERT(IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS),                               \
     251              :                      "TLS is required for HTTP secure (CONFIG_NET_SOCKETS_SOCKOPT_TLS)")
     252              : 
     253              : /**
     254              :  * @brief Count the number of HTTP services.
     255              :  *
     256              :  * @param[out] _dst Pointer to location where result is written.
     257              :  */
     258            1 : #define HTTP_SERVICE_COUNT(_dst) STRUCT_SECTION_COUNT(http_service_desc, _dst)
     259              : 
     260              : /**
     261              :  * @brief Count HTTP service static resources.
     262              :  *
     263              :  * @param _service Pointer to a service.
     264              :  */
     265            1 : #define HTTP_SERVICE_RESOURCE_COUNT(_service) ((_service)->res_end - (_service)->res_begin)
     266              : 
     267              : /**
     268              :  * @brief Iterate over all HTTP services.
     269              :  *
     270              :  * @param _it Name of http_service_desc iterator
     271              :  */
     272            1 : #define HTTP_SERVICE_FOREACH(_it) STRUCT_SECTION_FOREACH(http_service_desc, _it)
     273              : 
     274              : /**
     275              :  * @brief Iterate over static HTTP resources associated with a given @p _service.
     276              :  *
     277              :  * @note This macro requires that @p _service is defined with @ref HTTP_SERVICE_DEFINE.
     278              :  *
     279              :  * @param _service Name of HTTP service
     280              :  * @param _it Name of iterator (of type @ref http_resource_desc)
     281              :  */
     282            1 : #define HTTP_RESOURCE_FOREACH(_service, _it)                                                       \
     283              :         STRUCT_SECTION_FOREACH_ALTERNATE(http_resource_desc_##_service, http_resource_desc, _it)
     284              : 
     285              : /**
     286              :  * @brief Iterate over all static resources associated with @p _service .
     287              :  *
     288              :  * @note This macro is suitable for a @p _service defined with either @ref HTTP_SERVICE_DEFINE
     289              :  * or @ref HTTP_SERVICE_DEFINE_EMPTY.
     290              :  *
     291              :  * @param _service Pointer to HTTP service
     292              :  * @param _it Name of iterator (of type @ref http_resource_desc)
     293              :  */
     294            1 : #define HTTP_SERVICE_FOREACH_RESOURCE(_service, _it)                                               \
     295              :         for (struct http_resource_desc *_it = (_service)->res_begin; ({                            \
     296              :                      __ASSERT(_it <= (_service)->res_end, "unexpected list end location");         \
     297              :                      _it < (_service)->res_end;                                                    \
     298              :              });                                                                                   \
     299              :              _it++)
     300              : 
     301              : #ifdef __cplusplus
     302              : }
     303              : #endif
     304              : 
     305              : /**
     306              :  * @}
     307              :  */
     308              : 
     309              : #endif /* ZEPHYR_INCLUDE_NET_HTTP_SERVICE_H_ */
        

Generated by: LCOV version 2.0-1