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 #include <stdint.h> 11 #include <stddef.h> 12 13 #include <zephyr/sys/iterable_sections.h> 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 struct http_resource_desc { 20 const char *resource; 21 void *detail; 22 }; 23 24 /** 25 * @brief Define a static HTTP resource 26 * 27 * A static HTTP resource is one that is known prior to system initialization. In contrast, 28 * dynamic resources may be discovered upon system initialization. Dynamic resources may also be 29 * inserted, or removed by events originating internally or externally to the system at runtime. 30 * 31 * @note The @p _resource is the URL without the associated protocol, host, or URL parameters. E.g. 32 * the resource for `http://www.foo.com/bar/baz.html#param1=value1` would be `/bar/baz.html`. It 33 * is often referred to as the "path" of the URL. Every `(service, resource)` pair should be 34 * unique. The @p _resource must be non-NULL. 35 * 36 * @param _name Name of the resource. 37 * @param _service Name of the associated service. 38 * @param _resource Pathname-like string identifying the resource. 39 * @param _detail Implementation-specific detail associated with the resource. 40 */ 41 #define HTTP_RESOURCE_DEFINE(_name, _service, _resource, _detail) \ 42 const STRUCT_SECTION_ITERABLE_ALTERNATE(http_resource_desc_##_service, http_resource_desc, \ 43 _name) = { \ 44 .resource = _resource, \ 45 .detail = (_detail), \ 46 } 47 48 struct http_service_desc { 49 const char *host; 50 uint16_t *port; 51 void *detail; 52 size_t concurrent; 53 size_t backlog; 54 struct http_resource_desc *res_begin; 55 struct http_resource_desc *res_end; 56 }; 57 58 #define __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, _res_begin, \ 59 _res_end) \ 60 static const STRUCT_SECTION_ITERABLE(http_service_desc, _name) = { \ 61 .host = _host, \ 62 .port = (uint16_t *)(_port), \ 63 .detail = (void *)(_detail), \ 64 .concurrent = (_concurrent), \ 65 .backlog = (_backlog), \ 66 .res_begin = (_res_begin), \ 67 .res_end = (_res_end), \ 68 } 69 70 /** 71 * @brief Define an HTTP service without static resources. 72 * 73 * @note The @p _host parameter must be non-`NULL`. It is used to specify an IP address either in 74 * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. 75 * 76 * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port 77 * number to use for the service. If the specified port number is zero, then an ephemeral port 78 * number will be used and the actual port number assigned will be written back to memory. For 79 * ephemeral port numbers, the memory pointed to by @p _port must be writeable. 80 * 81 * @param _name Name of the service. 82 * @param _host IP address or hostname associated with the service. 83 * @param[inout] _port Pointer to port associated with the service. 84 * @param _concurrent Maximum number of concurrent clients. 85 * @param _backlog Maximum number queued connections. 86 * @param _detail Implementation-specific detail associated with the service. 87 */ 88 #define HTTP_SERVICE_DEFINE_EMPTY(_name, _host, _port, _concurrent, _backlog, _detail) \ 89 __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, NULL, NULL) 90 91 /** 92 * @brief Define an HTTP service with static resources. 93 * 94 * @note The @p _host parameter must be non-`NULL`. It is used to specify an IP address either in 95 * IPv4 or IPv6 format a fully-qualified hostname or a virtual host. 96 * 97 * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port 98 * number to use for the service. If the specified port number is zero, then an ephemeral port 99 * number will be used and the actual port number assigned will be written back to memory. For 100 * ephemeral port numbers, the memory pointed to by @p _port must be writeable. 101 * 102 * @param _name Name of the service. 103 * @param _host IP address or hostname associated with the service. 104 * @param[inout] _port Pointer to port associated with the service. 105 * @param _concurrent Maximum number of concurrent clients. 106 * @param _backlog Maximum number queued connections. 107 * @param _detail Implementation-specific detail associated with the service. 108 */ 109 #define HTTP_SERVICE_DEFINE(_name, _host, _port, _concurrent, _backlog, _detail) \ 110 extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_start)[]; \ 111 extern struct http_resource_desc _CONCAT(_http_resource_desc_##_name, _list_end)[]; \ 112 __z_http_service_define(_name, _host, _port, _concurrent, _backlog, _detail, \ 113 &_CONCAT(_http_resource_desc_##_name, _list_start)[0], \ 114 &_CONCAT(_http_resource_desc_##_name, _list_end)[0]) 115 116 /** 117 * @brief Count the number of HTTP services. 118 * 119 * @param[out] _dst Pointer to location where result is written. 120 */ 121 #define HTTP_SERVICE_COUNT(_dst) STRUCT_SECTION_COUNT(http_service_desc, _dst) 122 123 /** 124 * @brief Count HTTP service static resources. 125 * 126 * @param _service Pointer to a service. 127 */ 128 #define HTTP_SERVICE_RESOURCE_COUNT(_service) ((_service)->res_end - (_service)->res_begin) 129 130 /** 131 * @brief Iterate over all HTTP services. 132 * 133 * @param _it Name of iterator (of type @ref http_service_desc) 134 */ 135 #define HTTP_SERVICE_FOREACH(_it) STRUCT_SECTION_FOREACH(http_service_desc, _it) 136 137 /** 138 * @brief Iterate over static HTTP resources associated with a given @p _service. 139 * 140 * @note This macro requires that @p _service is defined with @ref HTTP_SERVICE_DEFINE. 141 * 142 * @param _service Name of HTTP service 143 * @param _it Name of iterator (of type @ref http_resource_desc) 144 */ 145 #define HTTP_RESOURCE_FOREACH(_service, _it) \ 146 STRUCT_SECTION_FOREACH_ALTERNATE(http_resource_desc_##_service, http_resource_desc, _it) 147 148 /** 149 * @brief Iterate over all static resources associated with @p _service . 150 * 151 * @note This macro is suitable for a @p _service defined with either @ref HTTP_SERVICE_DEFINE 152 * or @ref HTTP_SERVICE_DEFINE_EMPTY. 153 * 154 * @param _service Pointer to HTTP service 155 * @param _it Name of iterator (of type @ref http_resource_desc) 156 */ 157 #define HTTP_SERVICE_FOREACH_RESOURCE(_service, _it) \ 158 for (struct http_resource_desc *_it = (_service)->res_begin; ({ \ 159 __ASSERT(_it <= (_service)->res_end, "unexpected list end location"); \ 160 _it < (_service)->res_end; \ 161 }); \ 162 _it++) 163 164 #ifdef __cplusplus 165 } 166 #endif 167 168 #endif /* ZEPHYR_INCLUDE_NET_HTTP_SERVICE_H_ */ 169