| /* |
| * Copyright (c) 2022 Meta |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_NET_HTTP_SERVICE_H_ |
| #define ZEPHYR_INCLUDE_NET_HTTP_SERVICE_H_ |
| |
| #include <stdint.h> |
| #include <stddef.h> |
| |
| #include <zephyr/sys/iterable_sections.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| struct http_resource_desc { |
| const char *resource; |
| void *detail; |
| }; |
| |
| /** |
| * @brief Define a static HTTP resource |
| * |
| * A static HTTP resource is one that is known prior to system initialization. In contrast, |
| * dynamic resources may be discovered upon system initialization. Dynamic resources may also be |
| * inserted, or removed by events originating internally or externally to the system at runtime. |
| * |
| * @note The @p _resource is the URL without the associated protocol, host, or URL parameters. E.g. |
| * the resource for `http://www.foo.com/bar/baz.html#param1=value1` would be `/bar/baz.html`. It |
| * is often referred to as the "path" of the URL. Every `(service, resource)` pair should be |
| * unique. The @p _resource must be non-NULL. |
| * |
| * @param _name Name of the resource. |
| * @param _service Name of the associated service. |
| * @param _resource Pathname-like string identifying the resource. |
| * @param _detail Implementation-specific detail associated with the resource. |
| */ |
| #define HTTP_RESOURCE_DEFINE(_name, _service, _resource, _detail) \ |
| const STRUCT_SECTION_ITERABLE_ALTERNATE(http_resource_desc_##_service, http_resource_desc, \ |
| _name) = { \ |
| .resource = _resource, \ |
| .detail = (_detail), \ |
| } |
| |
| struct http_service_desc { |
| const char *host; |
| uint16_t *port; |
| void *detail; |
| size_t concurrent; |
| size_t backlog; |
| struct http_resource_desc *res_begin; |
| struct http_resource_desc *res_end; |
| }; |
| |
| #define __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, _res_begin, \ |
| _res_end) \ |
| static const STRUCT_SECTION_ITERABLE(http_service_desc, _name) = { \ |
| .host = _host, \ |
| .port = (uint16_t *)(_port), \ |
| .detail = (void *)(_detail), \ |
| .concurrent = (_concurrent), \ |
| .backlog = (_backlog), \ |
| .res_begin = (_res_begin), \ |
| .res_end = (_res_end), \ |
| } |
| |
| /** |
| * @brief Define an HTTP service without static resources. |
| * |
| * @note The @p _host parameter must be non-`NULL`. It is used to specify an IP address either in |
| * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. |
| * |
| * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port |
| * number to use for the service. If the specified port number is zero, then an ephemeral port |
| * number will be used and the actual port number assigned will be written back to memory. For |
| * ephemeral port numbers, the memory pointed to by @p _port must be writeable. |
| * |
| * @param _name Name of the service. |
| * @param _host IP address or hostname associated with the service. |
| * @param[inout] _port Pointer to port associated with the service. |
| * @param _concurrent Maximum number of concurrent clients. |
| * @param _backlog Maximum number queued connections. |
| * @param _detail Implementation-specific detail associated with the service. |
| */ |
| #define HTTP_SERVICE_DEFINE_EMPTY(_name, _host, _port, _concurrent, _backlog, _detail) \ |
| __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, NULL, NULL) |
| |
| /** |
| * @brief Define an HTTP service with static resources. |
| * |
| * @note The @p _host parameter must be non-`NULL`. It is used to specify an IP address either in |
| * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. |
| * |
| * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port |
| * number to use for the service. If the specified port number is zero, then an ephemeral port |
| * number will be used and the actual port number assigned will be written back to memory. For |
| * ephemeral port numbers, the memory pointed to by @p _port must be writeable. |
| * |
| * @param _name Name of the service. |
| * @param _host IP address or hostname associated with the service. |
| * @param[inout] _port Pointer to port associated with the service. |
| * @param _concurrent Maximum number of concurrent clients. |
| * @param _backlog Maximum number queued connections. |
| * @param _detail Implementation-specific detail associated with the service. |
| */ |
| #define HTTP_SERVICE_DEFINE(_name, _host, _port, _concurrent, _backlog, _detail) \ |
| extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_start)[]; \ |
| extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_end)[]; \ |
| __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, \ |
| &_CONCAT(_http_resource_desc_##_name, _list_start)[0], \ |
| &_CONCAT(_http_resource_desc_##_name, _list_end)[0]) |
| |
| /** |
| * @brief Count the number of HTTP services. |
| * |
| * @param[out] _dst Pointer to location where result is written. |
| */ |
| #define HTTP_SERVICE_COUNT(_dst) STRUCT_SECTION_COUNT(http_service_desc, _dst) |
| |
| /** |
| * @brief Count HTTP service static resources. |
| * |
| * @param _service Pointer to a service. |
| */ |
| #define HTTP_SERVICE_RESOURCE_COUNT(_service) ((_service)->res_end - (_service)->res_begin) |
| |
| /** |
| * @brief Iterate over all HTTP services. |
| * |
| * @param _it Name of iterator (of type @ref http_service_desc) |
| */ |
| #define HTTP_SERVICE_FOREACH(_it) STRUCT_SECTION_FOREACH(http_service_desc, _it) |
| |
| /** |
| * @brief Iterate over static HTTP resources associated with a given @p _service. |
| * |
| * @note This macro requires that @p _service is defined with @ref HTTP_SERVICE_DEFINE. |
| * |
| * @param _service Name of HTTP service |
| * @param _it Name of iterator (of type @ref http_resource_desc) |
| */ |
| #define HTTP_RESOURCE_FOREACH(_service, _it) \ |
| STRUCT_SECTION_FOREACH_ALTERNATE(http_resource_desc_##_service, http_resource_desc, _it) |
| |
| /** |
| * @brief Iterate over all static resources associated with @p _service . |
| * |
| * @note This macro is suitable for a @p _service defined with either @ref HTTP_SERVICE_DEFINE |
| * or @ref HTTP_SERVICE_DEFINE_EMPTY. |
| * |
| * @param _service Pointer to HTTP service |
| * @param _it Name of iterator (of type @ref http_resource_desc) |
| */ |
| #define HTTP_SERVICE_FOREACH_RESOURCE(_service, _it) \ |
| for (struct http_resource_desc *_it = (_service)->res_begin; ({ \ |
| __ASSERT(_it <= (_service)->res_end, "unexpected list end location"); \ |
| _it < (_service)->res_end; \ |
| }); \ |
| _it++) |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ZEPHYR_INCLUDE_NET_HTTP_SERVICE_H_ */ |