LCOV - code coverage report
Current view: top level - zephyr/net/http - client.h Hit Total Coverage
Test: new.info Lines: 45 45 100.0 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           1 : /** @file
       2             :  * @brief HTTP client API
       3             :  *
       4             :  * An API for applications do HTTP requests
       5             :  */
       6             : 
       7             : /*
       8             :  * Copyright (c) 2019 Intel Corporation
       9             :  *
      10             :  * SPDX-License-Identifier: Apache-2.0
      11             :  */
      12             : 
      13             : #ifndef ZEPHYR_INCLUDE_NET_HTTP_CLIENT_H_
      14             : #define ZEPHYR_INCLUDE_NET_HTTP_CLIENT_H_
      15             : 
      16             : /**
      17             :  * @brief HTTP client API
      18             :  * @defgroup http_client HTTP client API
      19             :  * @since 2.1
      20             :  * @version 0.2.0
      21             :  * @ingroup networking
      22             :  * @{
      23             :  */
      24             : 
      25             : #include <zephyr/kernel.h>
      26             : #include <zephyr/net/net_ip.h>
      27             : #include <zephyr/net/http/parser.h>
      28             : 
      29             : #ifdef __cplusplus
      30             : extern "C" {
      31             : #endif
      32             : 
      33             : /** @cond INTERNAL_HIDDEN */
      34             : 
      35             : #if !defined(HTTP_CRLF)
      36             : #define HTTP_CRLF "\r\n"
      37             : #endif
      38             : 
      39             : #if !defined(HTTP_STATUS_STR_SIZE)
      40             : #define HTTP_STATUS_STR_SIZE    32
      41             : #endif
      42             : 
      43             : /** @endcond */
      44             : 
      45             : /** Is there more data to come */
      46           1 : enum http_final_call {
      47             :         HTTP_DATA_MORE = 0,  /**< More data will come */
      48             :         HTTP_DATA_FINAL = 1, /**< End of data */
      49             : };
      50             : 
      51             : struct http_request;
      52             : struct http_response;
      53             : 
      54             : /**
      55             :  * @typedef http_payload_cb_t
      56             :  * @brief Callback used when data needs to be sent to the server.
      57             :  *
      58             :  * @param sock Socket id of the connection
      59             :  * @param req HTTP request information
      60             :  * @param user_data User specified data specified in http_client_req()
      61             :  *
      62             :  * @return >=0 amount of data sent, in this case http_client_req() should
      63             :  *             continue sending data,
      64             :  *         <0  if http_client_req() should return the error code to the
      65             :  *             caller.
      66             :  */
      67           1 : typedef int (*http_payload_cb_t)(int sock,
      68             :                                  struct http_request *req,
      69             :                                  void *user_data);
      70             : 
      71             : /**
      72             :  * @typedef http_header_cb_t
      73             :  * @brief Callback can be used if application wants to construct additional
      74             :  * HTTP headers when the HTTP request is sent. Usage of this is optional.
      75             :  *
      76             :  * @param sock Socket id of the connection
      77             :  * @param req HTTP request information
      78             :  * @param user_data User specified data specified in http_client_req()
      79             :  *
      80             :  * @return >=0 amount of data sent, in this case http_client_req() should
      81             :  *             continue sending data,
      82             :  *         <0  if http_client_req() should return the error code to the
      83             :  *             caller.
      84             :  */
      85           1 : typedef int (*http_header_cb_t)(int sock,
      86             :                                 struct http_request *req,
      87             :                                 void *user_data);
      88             : 
      89             : /**
      90             :  * @typedef http_response_cb_t
      91             :  * @brief Callback used when data is received from the server.
      92             :  *
      93             :  * @param rsp HTTP response information
      94             :  * @param final_data Does this data buffer contain all the data or
      95             :  *        is there still more data to come.
      96             :  * @param user_data User specified data specified in http_client_req()
      97             :  */
      98           1 : typedef void (*http_response_cb_t)(struct http_response *rsp,
      99             :                                    enum http_final_call final_data,
     100             :                                    void *user_data);
     101             : 
     102             : /**
     103             :  * HTTP response from the server.
     104             :  */
     105           1 : struct http_response {
     106             :         /** HTTP parser settings for the application usage */
     107           1 :         const struct http_parser_settings *http_cb;
     108             : 
     109             :         /** User provided HTTP response callback which is
     110             :          * called when a response is received to a sent HTTP
     111             :          * request.
     112             :          */
     113           1 :         http_response_cb_t cb;
     114             : 
     115             :         /**
     116             :          *                       recv_buffer that contains header + body
     117             :          *                       _______________________________________
     118             :          *
     119             :          *                                   |←-------- body_frag_len ---------→|
     120             :          *                |←--------------------- data len --------------------→|
     121             :          *            ---------------------------------------------------------------
     122             :          *      ..header  |      header      |               body               |  body..
     123             :          *            ---------------------------------------------------------------
     124             :          *                ↑                  ↑
     125             :          *             recv_buf          body_frag_start
     126             :          *
     127             :          *
     128             :          *                          recv_buffer that contains body only
     129             :          *                          ___________________________________
     130             :          *
     131             :          *                 |←------------------ body_frag_len ------------------→|
     132             :          *                 |←--------------------- data len --------------------→|
     133             :          *            ---------------------------------------------------------------
     134             :          *  ..header/body  |                         body                        |  body..
     135             :          *            ---------------------------------------------------------------
     136             :          *                 ↑
     137             :          *              recv_buf
     138             :          *          body_frag_start
     139             :          *
     140             :          * body_frag_start >= recv_buf
     141             :          * body_frag_len = data_len - (body_frag_start - recv_buf)
     142             :          */
     143             :         /** Start address of the body fragment contained in the recv_buf */
     144           1 :         uint8_t *body_frag_start;
     145             : 
     146             :         /** Length of the body fragment contained in the recv_buf */
     147           1 :         size_t body_frag_len;
     148             : 
     149             :         /** Where the response is stored, this is to be
     150             :          * provided by the user.
     151             :          */
     152           1 :         uint8_t *recv_buf;
     153             : 
     154             :         /** Response buffer maximum length */
     155           1 :         size_t recv_buf_len;
     156             : 
     157             :         /** Length of the data in the result buf. If the value
     158             :          * is larger than recv_buf_len, then it means that
     159             :          * the data is truncated and could not be fully copied
     160             :          * into recv_buf. This can only happen if the user
     161             :          * did not set the response callback. If the callback
     162             :          * is set, then the HTTP client API will call response
     163             :          * callback many times so that all the data is
     164             :          * delivered to the user. Will be zero in the event of
     165             :          * a null response.
     166             :          */
     167           1 :         size_t data_len;
     168             : 
     169             :         /** HTTP Content-Length field value. Will be set to zero
     170             :          * in the event of a null response.
     171             :          */
     172           1 :         size_t content_length;
     173             : 
     174             :         /** Amount of data given to the response callback so far, including the
     175             :          * current data given to the callback. This should be equal to the
     176             :          * content_length field once the entire body has been received. Will be
     177             :          * zero if a null response is given.
     178             :          */
     179           1 :         size_t processed;
     180             : 
     181             :         /** See https://tools.ietf.org/html/rfc7230#section-3.1.2 for more information.
     182             :          * The status-code element is a 3-digit integer code
     183             :          *
     184             :          * The reason-phrase element exists for the sole
     185             :          * purpose of providing a textual description
     186             :          * associated with the numeric status code. A client
     187             :          * SHOULD ignore the reason-phrase content.
     188             :          *
     189             :          * Will be blank if a null HTTP response is given.
     190             :          */
     191           1 :         char http_status[HTTP_STATUS_STR_SIZE];
     192             : 
     193             :         /** Numeric HTTP status code which corresponds to the
     194             :          * textual description. Set to zero if null response is
     195             :          * given. Otherwise, will be a 3-digit integer code if
     196             :          * valid HTTP response is given.
     197             :          */
     198           1 :         uint16_t http_status_code;
     199             : 
     200           1 :         uint8_t cl_present : 1;       /**< Is Content-Length field present */
     201           1 :         uint8_t body_found : 1;       /**< Is message body found */
     202           1 :         uint8_t message_complete : 1; /**< Is HTTP message parsing complete */
     203             : };
     204             : 
     205             : /** HTTP client internal data that the application should not touch
     206             :  */
     207           1 : struct http_client_internal_data {
     208             :         /** HTTP parser context */
     209           1 :         struct http_parser parser;
     210             : 
     211             :         /** HTTP parser settings */
     212           1 :         struct http_parser_settings parser_settings;
     213             : 
     214             :         /** HTTP response specific data (filled by http_client_req() when
     215             :          * data is received)
     216             :          */
     217           1 :         struct http_response response;
     218             : 
     219             :         /** User data */
     220           1 :         void *user_data;
     221             : 
     222             :         /** HTTP socket */
     223           1 :         int sock;
     224             : };
     225             : 
     226             : /**
     227             :  * HTTP client request. This contains all the data that is needed when doing
     228             :  * a HTTP request.
     229             :  */
     230           1 : struct http_request {
     231             :         /** HTTP client request internal data */
     232           1 :         struct http_client_internal_data internal;
     233             : 
     234             :         /* User should fill in following parameters */
     235             : 
     236             :         /** The HTTP method: GET, HEAD, OPTIONS, POST, ... */
     237           1 :         enum http_method method;
     238             : 
     239             :         /** User supplied callback function to call when response is
     240             :          * received.
     241             :          */
     242           1 :         http_response_cb_t response;
     243             : 
     244             :         /** User supplied list of HTTP callback functions if the
     245             :          * calling application wants to know the parsing status or the HTTP
     246             :          * fields. This is optional and normally not needed.
     247             :          */
     248           1 :         const struct http_parser_settings *http_cb;
     249             : 
     250             :         /** User supplied buffer where received data is stored */
     251           1 :         uint8_t *recv_buf;
     252             : 
     253             :         /** Length of the user supplied receive buffer */
     254           1 :         size_t recv_buf_len;
     255             : 
     256             :         /** The URL for this request, for example: /index.html */
     257           1 :         const char *url;
     258             : 
     259             :         /** The HTTP protocol, for example "HTTP/1.1" */
     260           1 :         const char *protocol;
     261             : 
     262             :         /** The HTTP header fields (application specific)
     263             :          * The Content-Type may be specified here or in the next field.
     264             :          * Depending on your application, the Content-Type may vary, however
     265             :          * some header fields may remain constant through the application's
     266             :          * life cycle. This is a NULL terminated list of header fields.
     267             :          */
     268           1 :         const char **header_fields;
     269             : 
     270             :         /** The value of the Content-Type header field, may be NULL */
     271           1 :         const char *content_type_value;
     272             : 
     273             :         /** Hostname to be used in the request */
     274           1 :         const char *host;
     275             : 
     276             :         /** Port number to be used in the request */
     277           1 :         const char *port;
     278             : 
     279             :         /** User supplied callback function to call when payload
     280             :          * needs to be sent. This can be NULL in which case the payload field
     281             :          * in http_request is used. The idea of this payload callback is to
     282             :          * allow user to send more data that is practical to store in allocated
     283             :          * memory.
     284             :          */
     285           1 :         http_payload_cb_t payload_cb;
     286             : 
     287             :         /** Payload, may be NULL */
     288           1 :         const char *payload;
     289             : 
     290             :         /** Payload length is used to calculate Content-Length. Set to 0
     291             :          * for chunked transfers.
     292             :          */
     293           1 :         size_t payload_len;
     294             : 
     295             :         /** User supplied callback function to call when optional headers need
     296             :          * to be sent. This can be NULL, in which case the optional_headers
     297             :          * field in http_request is used. The idea of this optional_headers
     298             :          * callback is to allow user to send more HTTP header data that is
     299             :          * practical to store in allocated memory.
     300             :          */
     301           1 :         http_header_cb_t optional_headers_cb;
     302             : 
     303             :         /** A NULL terminated list of any optional headers that
     304             :          * should be added to the HTTP request. May be NULL.
     305             :          * If the optional_headers_cb is specified, then this field is ignored.
     306             :          * Note that there are two similar fields that contain headers,
     307             :          * the header_fields above and this optional_headers. This is done
     308             :          * like this to support Websocket use case where Websocket will use
     309             :          * header_fields variable and any optional application specific
     310             :          * headers will be placed into this field.
     311             :          */
     312           1 :         const char **optional_headers;
     313             : };
     314             : 
     315             : /**
     316             :  * @brief Do a HTTP request. The callback is called when data is received
     317             :  * from the HTTP server. The caller must have created a connection to the
     318             :  * server before calling this function so connect() call must have be done
     319             :  * successfully for the socket.
     320             :  *
     321             :  * @param sock Socket id of the connection.
     322             :  * @param req HTTP request information
     323             :  * @param timeout Max timeout to wait for the data. The timeout value cannot be
     324             :  *        0 as there would be no time to receive the data.
     325             :  *        The timeout value is in milliseconds.
     326             :  * @param user_data User specified data that is passed to the callback.
     327             :  *
     328             :  * @return <0 if error, >=0 amount of data sent to the server
     329             :  */
     330           1 : int http_client_req(int sock, struct http_request *req,
     331             :                     int32_t timeout, void *user_data);
     332             : 
     333             : #ifdef __cplusplus
     334             : }
     335             : #endif
     336             : 
     337             : /**
     338             :  * @}
     339             :  */
     340             : 
     341             : #endif /* ZEPHYR_INCLUDE_NET_HTTP_CLIENT_H_ */

Generated by: LCOV version 1.14