/* * 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 #include #include #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_ */