LCOV - code coverage report
Current view: top level - zephyr/net/http - server.h Coverage Total Hit
Test: new.info Lines: 94.2 % 104 98
Test Date: 2025-09-05 20:47:19

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2023, Emna Rekik
       3              :  * Copyright (c) 2024 Nordic Semiconductor ASA
       4              :  *
       5              :  * SPDX-License-Identifier: Apache-2.0
       6              :  */
       7              : 
       8              : #ifndef ZEPHYR_INCLUDE_NET_HTTP_SERVER_H_
       9              : #define ZEPHYR_INCLUDE_NET_HTTP_SERVER_H_
      10              : 
      11              : /**
      12              :  * @file server.h
      13              :  *
      14              :  * @brief HTTP server API
      15              :  *
      16              :  * @defgroup http_server HTTP server API
      17              :  * @since 3.7
      18              :  * @version 0.1.0
      19              :  * @ingroup networking
      20              :  * @{
      21              :  */
      22              : 
      23              : #include <stdint.h>
      24              : 
      25              : #include <zephyr/kernel.h>
      26              : #include <zephyr/net/http/parser.h>
      27              : #include <zephyr/net/http/hpack.h>
      28              : #include <zephyr/net/http/status.h>
      29              : #include <zephyr/net/socket.h>
      30              : #include <zephyr/sys/iterable_sections.h>
      31              : 
      32              : #ifdef __cplusplus
      33              : extern "C" {
      34              : #endif
      35              : 
      36              : /** @cond INTERNAL_HIDDEN */
      37              : 
      38              : #if defined(CONFIG_HTTP_SERVER)
      39              : #define HTTP_SERVER_CLIENT_BUFFER_SIZE   CONFIG_HTTP_SERVER_CLIENT_BUFFER_SIZE
      40              : #define HTTP_SERVER_MAX_STREAMS          CONFIG_HTTP_SERVER_MAX_STREAMS
      41              : #define HTTP_SERVER_MAX_CONTENT_TYPE_LEN CONFIG_HTTP_SERVER_MAX_CONTENT_TYPE_LENGTH
      42              : #define HTTP_SERVER_MAX_URL_LENGTH       CONFIG_HTTP_SERVER_MAX_URL_LENGTH
      43              : #define HTTP_SERVER_MAX_HEADER_LEN       CONFIG_HTTP_SERVER_MAX_HEADER_LEN
      44              : #else
      45              : #define HTTP_SERVER_CLIENT_BUFFER_SIZE   0
      46              : #define HTTP_SERVER_MAX_STREAMS          0
      47              : #define HTTP_SERVER_MAX_CONTENT_TYPE_LEN 0
      48              : #define HTTP_SERVER_MAX_URL_LENGTH       0
      49              : #define HTTP_SERVER_MAX_HEADER_LEN       0
      50              : #endif
      51              : 
      52              : #if defined(CONFIG_HTTP_SERVER_CAPTURE_HEADERS)
      53              : #define HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE CONFIG_HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE
      54              : #define HTTP_SERVER_CAPTURE_HEADER_COUNT       CONFIG_HTTP_SERVER_CAPTURE_HEADER_COUNT
      55              : #else
      56              : #define HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE 0
      57              : #define HTTP_SERVER_CAPTURE_HEADER_COUNT       0
      58              : #endif
      59              : 
      60              : #define HTTP2_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
      61              : 
      62              : /** @endcond */
      63              : 
      64              : /**
      65              :  *  @brief HTTP server resource type.
      66              :  */
      67            1 : enum http_resource_type {
      68              :         /** Static resource, cannot be modified on runtime. */
      69              :         HTTP_RESOURCE_TYPE_STATIC,
      70              : 
      71              :         /** serves static gzipped files from a filesystem */
      72              :         HTTP_RESOURCE_TYPE_STATIC_FS,
      73              : 
      74              :         /** Dynamic resource, server interacts with the application via registered
      75              :          *  @ref http_resource_dynamic_cb_t.
      76              :          */
      77              :         HTTP_RESOURCE_TYPE_DYNAMIC,
      78              : 
      79              :         /** Websocket resource, application takes control over Websocket connection
      80              :          *  after and upgrade.
      81              :          */
      82              :         HTTP_RESOURCE_TYPE_WEBSOCKET,
      83              : };
      84              : 
      85              : /**
      86              :  * @brief Representation of a server resource, common for all resource types.
      87              :  */
      88            1 : struct http_resource_detail {
      89              :         /** Bitmask of supported HTTP methods (@ref http_method). */
      90            1 :         uint32_t bitmask_of_supported_http_methods;
      91              : 
      92              :         /** Resource type. */
      93            1 :         enum http_resource_type type;
      94              : 
      95              :         /** Length of the URL path. */
      96            1 :         int path_len;
      97              : 
      98              :         /** Content encoding of the resource. */
      99            1 :         const char *content_encoding;
     100              : 
     101              :         /** Content type of the resource. */
     102            1 :         const char *content_type;
     103              : };
     104              : 
     105              : /** @cond INTERNAL_HIDDEN */
     106              : BUILD_ASSERT(NUM_BITS(
     107              :              sizeof(((struct http_resource_detail *)0)->bitmask_of_supported_http_methods))
     108              :              >= (HTTP_METHOD_END_VALUE - 1));
     109              : /** @endcond */
     110              : 
     111              : /**
     112              :  * @brief Representation of a static server resource.
     113              :  */
     114            1 : struct http_resource_detail_static {
     115              :         /** Common resource details. */
     116            1 :         struct http_resource_detail common;
     117              : 
     118              :         /** Content of the static resource. */
     119            1 :         const void *static_data;
     120              : 
     121              :         /** Size of the static resource. */
     122            1 :         size_t static_data_len;
     123              : };
     124              : 
     125              : /** @cond INTERNAL_HIDDEN */
     126              : /* Make sure that the common is the first in the struct. */
     127              : BUILD_ASSERT(offsetof(struct http_resource_detail_static, common) == 0);
     128              : /** @endcond */
     129              : 
     130              : /**
     131              :  * @brief Representation of a static filesystem server resource.
     132              :  */
     133            1 : struct http_resource_detail_static_fs {
     134              :         /** Common resource details. */
     135            1 :         struct http_resource_detail common;
     136              : 
     137              :         /** Path in the local filesystem */
     138            1 :         const char *fs_path;
     139              : };
     140              : 
     141              : /** @brief HTTP compressions */
     142            1 : enum http_compression {
     143              :         HTTP_NONE = 0,     /**< NONE */
     144              :         HTTP_GZIP = 1,     /**< GZIP */
     145              :         HTTP_COMPRESS = 2, /**< COMPRESS */
     146              :         HTTP_DEFLATE = 3,  /**< DEFLATE */
     147              :         HTTP_BR = 4,       /**< BR */
     148              :         HTTP_ZSTD = 5      /**< ZSTD */
     149              : };
     150              : 
     151              : /** @cond INTERNAL_HIDDEN */
     152              : /* Make sure that the common is the first in the struct. */
     153              : BUILD_ASSERT(offsetof(struct http_resource_detail_static_fs, common) == 0);
     154              : /** @endcond */
     155              : 
     156            0 : struct http_content_type {
     157            0 :         const char *extension;
     158            0 :         size_t extension_len;
     159            0 :         const char *content_type;
     160              : };
     161              : 
     162            0 : #define HTTP_SERVER_CONTENT_TYPE(_extension, _content_type)                                        \
     163              :         const STRUCT_SECTION_ITERABLE(http_content_type, _extension) = {                           \
     164              :                 .extension = STRINGIFY(_extension),                                                \
     165              :                 .extension_len = sizeof(STRINGIFY(_extension)) - 1,                                \
     166              :                 .content_type = _content_type,                                                     \
     167              :         };
     168              : 
     169            0 : #define HTTP_SERVER_CONTENT_TYPE_FOREACH(_it) STRUCT_SECTION_FOREACH(http_content_type, _it)
     170              : 
     171              : struct http_client_ctx;
     172              : 
     173              : /** Indicates the status of the currently processed piece of data.  */
     174            1 : enum http_data_status {
     175              :         /** Transaction aborted, data incomplete. */
     176              :         HTTP_SERVER_DATA_ABORTED = -1,
     177              :         /** Transaction incomplete, more data expected. */
     178              :         HTTP_SERVER_DATA_MORE = 0,
     179              :         /** Final data fragment in current transaction. */
     180              :         HTTP_SERVER_DATA_FINAL = 1,
     181              : };
     182              : 
     183              : /** @brief Status of captured request headers */
     184            1 : enum http_header_status {
     185              :         HTTP_HEADER_STATUS_OK,      /**< All available headers were successfully captured. */
     186              :         HTTP_HEADER_STATUS_DROPPED, /**< One or more headers were dropped due to lack of space. */
     187              :         HTTP_HEADER_STATUS_NONE,    /**< No header status is available. */
     188              : };
     189              : 
     190              : /** @brief HTTP header representation */
     191            1 : struct http_header {
     192            1 :         const char *name;  /**< Pointer to header name NULL-terminated string. */
     193            1 :         const char *value; /**< Pointer to header value NULL-terminated string. */
     194              : };
     195              : 
     196              : /** @brief HTTP request context */
     197            1 : struct http_request_ctx {
     198            1 :         uint8_t *data;                          /**< HTTP request data */
     199            1 :         size_t data_len;                        /**< Length of HTTP request data */
     200            1 :         struct http_header *headers;            /**< Array of HTTP request headers */
     201            1 :         size_t header_count;                    /**< Array length of HTTP request headers */
     202            1 :         enum http_header_status headers_status; /**< Status of HTTP request headers */
     203              : };
     204              : 
     205              : /** @brief HTTP response context */
     206            1 : struct http_response_ctx {
     207            1 :         enum http_status status;           /**< HTTP status code to include in response */
     208            1 :         const struct http_header *headers; /**< Array of HTTP headers */
     209            1 :         size_t header_count;               /**< Length of headers array */
     210            1 :         const uint8_t *body;               /**< Pointer to body data */
     211            1 :         size_t body_len;                   /**< Length of body data */
     212            1 :         bool final_chunk; /**< Flag set to true when the application has no more data to send */
     213              : };
     214              : 
     215              : /**
     216              :  * @typedef http_resource_dynamic_cb_t
     217              :  * @brief Callback used when data is received. Data to be sent to client
     218              :  *        can be specified.
     219              :  *
     220              :  * @param client HTTP context information for this client connection.
     221              :  * @param status HTTP data status, indicate whether more data is expected or not.
     222              :  * @param request_ctx Request context structure containing HTTP request data that was received.
     223              :  * @param response_ctx Response context structure for application to populate with response data.
     224              :  * @param user_data User specified data.
     225              :  *
     226              :  * @return 0 success, server can send any response data provided in the response_ctx.
     227              :  *         <0 error, close the connection.
     228              :  */
     229            1 : typedef int (*http_resource_dynamic_cb_t)(struct http_client_ctx *client,
     230              :                                           enum http_data_status status,
     231              :                                           const struct http_request_ctx *request_ctx,
     232              :                                           struct http_response_ctx *response_ctx,
     233              :                                           void *user_data);
     234              : 
     235              : /**
     236              :  * @brief Representation of a dynamic server resource.
     237              :  */
     238            1 : struct http_resource_detail_dynamic {
     239              :         /** Common resource details. */
     240            1 :         struct http_resource_detail common;
     241              : 
     242              :         /** Resource callback used by the server to interact with the
     243              :          *  application.
     244              :          */
     245            1 :         http_resource_dynamic_cb_t cb;
     246              : 
     247              :         /** A pointer to the client currently processing resource, used to
     248              :          *  prevent concurrent access to the resource from multiple clients.
     249              :          */
     250            1 :         struct http_client_ctx *holder;
     251              : 
     252              :         /** A pointer to the user data registered by the application.  */
     253            1 :         void *user_data;
     254              : };
     255              : 
     256              : /** @cond INTERNAL_HIDDEN */
     257              : BUILD_ASSERT(offsetof(struct http_resource_detail_dynamic, common) == 0);
     258              : /** @endcond */
     259              : 
     260              : /**
     261              :  * @typedef http_resource_websocket_cb_t
     262              :  * @brief Callback used when a Websocket connection is setup. The application
     263              :  *        will need to handle all functionality related to the connection like
     264              :  *        reading and writing websocket data, and closing the connection.
     265              :  *
     266              :  * @param ws_socket A socket for the Websocket data.
     267              :  * @param request_ctx Request context structure associated with HTTP upgrade request
     268              :  * @param user_data User specified data.
     269              :  *
     270              :  * @return  0 Accepting the connection, HTTP server library will no longer
     271              :  *            handle data to/from the socket and it is application responsibility
     272              :  *            to send and receive data to/from the supplied socket.
     273              :  *         <0 error, close the connection.
     274              :  */
     275            1 : typedef int (*http_resource_websocket_cb_t)(int ws_socket, struct http_request_ctx *request_ctx,
     276              :                                             void *user_data);
     277              : 
     278              : /** @brief Representation of a websocket server resource */
     279            1 : struct http_resource_detail_websocket {
     280              :         /** Common resource details. */
     281            1 :         struct http_resource_detail common;
     282              : 
     283              :         /** Websocket socket value */
     284            1 :         int ws_sock;
     285              : 
     286              :         /** Resource callback used by the server to interact with the
     287              :          *  application.
     288              :          */
     289            1 :         http_resource_websocket_cb_t cb;
     290              : 
     291              :         /** Data buffer used to exchanged data between server and the,
     292              :          *  application.
     293              :          */
     294            1 :         uint8_t *data_buffer;
     295              : 
     296              :         /** Length of the data in the data buffer. */
     297            1 :         size_t data_buffer_len;
     298              : 
     299              :         /** A pointer to the user data registered by the application.  */
     300            1 :         void *user_data;
     301              : };
     302              : 
     303              : /** @cond INTERNAL_HIDDEN */
     304              : BUILD_ASSERT(offsetof(struct http_resource_detail_websocket, common) == 0);
     305              : /** @endcond */
     306              : 
     307              : /** @cond INTERNAL_HIDDEN */
     308              : 
     309              : enum http2_stream_state {
     310              :         HTTP2_STREAM_IDLE,
     311              :         HTTP2_STREAM_RESERVED_LOCAL,
     312              :         HTTP2_STREAM_RESERVED_REMOTE,
     313              :         HTTP2_STREAM_OPEN,
     314              :         HTTP2_STREAM_HALF_CLOSED_LOCAL,
     315              :         HTTP2_STREAM_HALF_CLOSED_REMOTE,
     316              :         HTTP2_STREAM_CLOSED
     317              : };
     318              : 
     319              : enum http_server_state {
     320              :         HTTP_SERVER_FRAME_HEADER_STATE,
     321              :         HTTP_SERVER_PREFACE_STATE,
     322              :         HTTP_SERVER_REQUEST_STATE,
     323              :         HTTP_SERVER_FRAME_DATA_STATE,
     324              :         HTTP_SERVER_FRAME_HEADERS_STATE,
     325              :         HTTP_SERVER_FRAME_SETTINGS_STATE,
     326              :         HTTP_SERVER_FRAME_PRIORITY_STATE,
     327              :         HTTP_SERVER_FRAME_WINDOW_UPDATE_STATE,
     328              :         HTTP_SERVER_FRAME_CONTINUATION_STATE,
     329              :         HTTP_SERVER_FRAME_PING_STATE,
     330              :         HTTP_SERVER_FRAME_RST_STREAM_STATE,
     331              :         HTTP_SERVER_FRAME_GOAWAY_STATE,
     332              :         HTTP_SERVER_FRAME_PADDING_STATE,
     333              :         HTTP_SERVER_DONE_STATE,
     334              : };
     335              : 
     336              : enum http1_parser_state {
     337              :         HTTP1_INIT_HEADER_STATE,
     338              :         HTTP1_WAITING_HEADER_STATE,
     339              :         HTTP1_RECEIVING_HEADER_STATE,
     340              :         HTTP1_RECEIVED_HEADER_STATE,
     341              :         HTTP1_RECEIVING_DATA_STATE,
     342              :         HTTP1_MESSAGE_COMPLETE_STATE,
     343              : };
     344              : 
     345              : #define HTTP_SERVER_INITIAL_WINDOW_SIZE 65536
     346              : #define HTTP_SERVER_WS_MAX_SEC_KEY_LEN 32
     347              : 
     348              : /** @endcond */
     349              : 
     350              : /** @brief HTTP/2 stream representation. */
     351            1 : struct http2_stream_ctx {
     352            1 :         int stream_id; /**< Stream identifier. */
     353            1 :         enum http2_stream_state stream_state; /**< Stream state. */
     354            1 :         int window_size; /**< Stream-level window size. */
     355              : 
     356              :         /** Currently processed resource detail. */
     357            1 :         struct http_resource_detail *current_detail;
     358              : 
     359              :         /** Flag indicating that headers were sent in the reply. */
     360            1 :         bool headers_sent : 1;
     361              : 
     362              :         /** Flag indicating that END_STREAM flag was sent. */
     363            1 :         bool end_stream_sent : 1;
     364              : };
     365              : 
     366              : /** @brief HTTP/2 frame representation. */
     367            1 : struct http2_frame {
     368            1 :         uint32_t length; /**< Frame payload length. */
     369            1 :         uint32_t stream_identifier; /**< Stream ID the frame belongs to. */
     370            1 :         uint8_t type; /**< Frame type. */
     371            1 :         uint8_t flags; /**< Frame flags. */
     372            1 :         uint8_t padding_len; /**< Frame padding length. */
     373              : };
     374              : 
     375              : /** @cond INTERNAL_HIDDEN */
     376              : /** @brief Context for capturing HTTP headers */
     377              : struct http_header_capture_ctx {
     378              :         /** Buffer for HTTP headers captured for application use */
     379              :         unsigned char buffer[HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE];
     380              : 
     381              :         /** Descriptor of each captured HTTP header */
     382              :         struct http_header headers[HTTP_SERVER_CAPTURE_HEADER_COUNT];
     383              : 
     384              :         /** Status of captured headers */
     385              :         enum http_header_status status;
     386              : 
     387              :         /** Number of headers captured */
     388              :         size_t count;
     389              : 
     390              :         /** Current position in buffer */
     391              :         size_t cursor;
     392              : 
     393              :         /** The HTTP2 stream associated with the current headers */
     394              :         struct http2_stream_ctx *current_stream;
     395              : 
     396              :         /** The next HTTP header value should be stored */
     397              :         bool store_next_value;
     398              : };
     399              : /** @endcond */
     400              : 
     401              : /** @brief HTTP header name representation */
     402            1 : struct http_header_name {
     403            1 :         const char *name; /**< Pointer to header name NULL-terminated string. */
     404              : };
     405              : 
     406              : /**
     407              :  * @brief Representation of an HTTP client connected to the server.
     408              :  */
     409            1 : struct http_client_ctx {
     410              :         /** Socket descriptor associated with the server. */
     411            1 :         int fd;
     412              : 
     413              :         /** HTTP service on which the client is connected */
     414            1 :         const struct http_service_desc *service;
     415              : 
     416              :         /** Client data buffer.  */
     417            1 :         unsigned char buffer[HTTP_SERVER_CLIENT_BUFFER_SIZE];
     418              : 
     419              :         /** Cursor indicating currently processed byte. */
     420            1 :         unsigned char *cursor;
     421              : 
     422              :         /** Data left to process in the buffer. */
     423            1 :         size_t data_len;
     424              : 
     425              :         /** Connection-level window size. */
     426            1 :         int window_size;
     427              : 
     428              :         /** Server state for the associated client. */
     429            1 :         enum http_server_state server_state;
     430              : 
     431              :         /** Currently processed HTTP/2 frame. */
     432            1 :         struct http2_frame current_frame;
     433              : 
     434              :         /** Currently processed resource detail. */
     435            1 :         struct http_resource_detail *current_detail;
     436              : 
     437              :         /** Currently processed stream. */
     438            1 :         struct http2_stream_ctx *current_stream;
     439              : 
     440              :         /** HTTP/2 header parser context. */
     441            1 :         struct http_hpack_header_buf header_field;
     442              : 
     443              :         /** HTTP/2 streams context. */
     444            1 :         struct http2_stream_ctx streams[HTTP_SERVER_MAX_STREAMS];
     445              : 
     446              :         /** HTTP/1 parser configuration. */
     447            1 :         struct http_parser_settings parser_settings;
     448              : 
     449              :         /** HTTP/1 parser context. */
     450            1 :         struct http_parser parser;
     451              : 
     452              :         /** Header capture context */
     453            1 :         struct http_header_capture_ctx header_capture_ctx;
     454              : 
     455              :         /** Request URL. */
     456            1 :         unsigned char url_buffer[HTTP_SERVER_MAX_URL_LENGTH];
     457              : 
     458              :         /** Request content type. */
     459            1 :         unsigned char content_type[HTTP_SERVER_MAX_CONTENT_TYPE_LEN];
     460              : 
     461              :         /** Temp buffer for currently processed header (HTTP/1 only). */
     462            1 :         unsigned char header_buffer[HTTP_SERVER_MAX_HEADER_LEN];
     463              : 
     464              :         /** Request content length. */
     465            1 :         size_t content_len;
     466              : 
     467              :         /** Request method. */
     468            1 :         enum http_method method;
     469              : 
     470              :         /** HTTP/1 parser state. */
     471            1 :         enum http1_parser_state parser_state;
     472              : 
     473              :         /** Length of the payload length in the currently processed request
     474              :          * fragment (HTTP/1 only).
     475              :          */
     476            1 :         int http1_frag_data_len;
     477              : 
     478              :         /** Client inactivity timer. The client connection is closed by the
     479              :          *  server when it expires.
     480              :          */
     481            1 :         struct k_work_delayable inactivity_timer;
     482              : 
     483              : /** @cond INTERNAL_HIDDEN */
     484              :         /** Websocket security key. */
     485              :         IF_ENABLED(CONFIG_WEBSOCKET, (uint8_t ws_sec_key[HTTP_SERVER_WS_MAX_SEC_KEY_LEN]));
     486              : /** @endcond */
     487              : 
     488              : /** @cond INTERNAL_HIDDEN */
     489              :         /** Client supported compression. */
     490              :         IF_ENABLED(CONFIG_HTTP_SERVER_COMPRESSION, (uint8_t supported_compression));
     491              : /** @endcond */
     492              : 
     493              :         /** Flag indicating that HTTP2 preface was sent. */
     494            1 :         bool preface_sent : 1;
     495              : 
     496              :         /** Flag indicating that HTTP1 headers were sent. */
     497            1 :         bool http1_headers_sent : 1;
     498              : 
     499              :         /** Flag indicating that upgrade header was present in the request. */
     500            1 :         bool has_upgrade_header : 1;
     501              : 
     502              :         /** Flag indicating HTTP/2 upgrade takes place. */
     503            1 :         bool http2_upgrade : 1;
     504              : 
     505              :         /** Flag indicating Websocket upgrade takes place. */
     506            1 :         bool websocket_upgrade : 1;
     507              : 
     508              :         /** Flag indicating Websocket key is being processed. */
     509            1 :         bool websocket_sec_key_next : 1;
     510              : 
     511              :         /** Flag indicating accept encoding is being processed. */
     512            1 :         IF_ENABLED(CONFIG_HTTP_SERVER_COMPRESSION, (bool accept_encoding_next: 1));
     513              : 
     514              :         /** The next frame on the stream is expectd to be a continuation frame. */
     515            1 :         bool expect_continuation : 1;
     516              : };
     517              : 
     518              : /**
     519              :  * @brief Register an HTTP request header to be captured by the server
     520              :  *
     521              :  * @param _id variable name for the header capture instance
     522              :  * @param _header header to be captured, as literal string
     523              :  */
     524            1 : #define HTTP_SERVER_REGISTER_HEADER_CAPTURE(_id, _header)                                          \
     525              :         BUILD_ASSERT(sizeof(_header) <= CONFIG_HTTP_SERVER_MAX_HEADER_LEN,                         \
     526              :                      "Header is too long to be captured, try increasing "                          \
     527              :                      "CONFIG_HTTP_SERVER_MAX_HEADER_LEN");                                         \
     528              :         static const char *const _id##_str = _header;                                              \
     529              :         static const STRUCT_SECTION_ITERABLE(http_header_name, _id) = {                            \
     530              :                 .name = _id##_str,                                                                 \
     531              :         }
     532              : 
     533              : /** @brief Start the HTTP2 server.
     534              :  *
     535              :  * The server runs in a background thread. Once started, the server will create
     536              :  * a server socket for all HTTP services registered in the system and accept
     537              :  * connections from clients (see @ref HTTP_SERVICE_DEFINE).
     538              :  */
     539            1 : int http_server_start(void);
     540              : 
     541              : /** @brief Stop the HTTP2 server.
     542              :  *
     543              :  * All server sockets are closed and the server thread is suspended.
     544              :  */
     545            1 : int http_server_stop(void);
     546              : 
     547              : #ifdef __cplusplus
     548              : }
     549              : #endif
     550              : 
     551              : /**
     552              :  * @}
     553              :  */
     554              : 
     555              : #endif
        

Generated by: LCOV version 2.0-1