HTTP client

Overview

The HTTP client library allows you to send HTTP requests and parse HTTP responses. The library communicates over the sockets API but it does not create sockets on its own.

The application must be responsible for creating a socket and passing it to the library. Therefore, depending on the application’s needs, the library can communicate over either a plain TCP socket (HTTP) or a TLS socket (HTTPS).

Sample Usage

The API of the HTTP client library has a single function.

The following is an example of a request structure created correctly:

struct http_request req = { 0 };
static uint8_t recv_buf[512];

req.method = HTTP_GET;
req.url = "/";
req.host = "localhost";
req.protocol = "HTTP/1.1";
req.response = response_cb;
req.recv_buf = recv_buf;
req.recv_buf_len = sizeof(recv_buf);

/* sock is a file descriptor referencing a socket that has been connected
 * to the HTTP server.
 */
ret = http_client_req(sock, &req, 5000, NULL);

If the server responds to the request, the library provides the response to the application through the response callback registered in the request structure. As the library can provide the response in chunks, the application must be able to process these.

Together with the structure containing the response data, the callback function also provides information about whether the library expects to receive more data.

The following is an example of a very simple response handling function:

static void response_cb(struct http_response *rsp,
                        enum http_final_call final_data,
                        void *user_data)
{
    if (final_data == HTTP_DATA_MORE) {
        LOG_INF("Partial data received (%zd bytes)", rsp->data_len);
    } else if (final_data == HTTP_DATA_FINAL) {
        LOG_INF("All the data received (%zd bytes)", rsp->data_len);
    }

    LOG_INF("Response status %s", rsp->http_status);
}

See HTTP client sample application for more information about the library usage.

API Reference

group http_client

HTTP client API.

Defines

HTTP_CRLF
HTTP_STATUS_STR_SIZE

Typedefs

typedef int (*http_payload_cb_t)(int sock, struct http_request *req, void *user_data)

Callback used when data needs to be sent to the server.

Param sock

Socket id of the connection

Param req

HTTP request information

Param user_data

User specified data specified in http_client_req()

Return

>=0 amount of data sent, in this case http_client_req() should continue sending data, <0 if http_client_req() should return the error code to the caller.

typedef int (*http_header_cb_t)(int sock, struct http_request *req, void *user_data)

Callback can be used if application wants to construct additional HTTP headers when the HTTP request is sent. Usage of this is optional.

Param sock

Socket id of the connection

Param req

HTTP request information

Param user_data

User specified data specified in http_client_req()

Return

>=0 amount of data sent, in this case http_client_req() should continue sending data, <0 if http_client_req() should return the error code to the caller.

typedef void (*http_response_cb_t)(struct http_response *rsp, enum http_final_call final_data, void *user_data)

Callback used when data is received from the server.

Param rsp

HTTP response information

Param final_data

Does this data buffer contain all the data or is there still more data to come.

Param user_data

User specified data specified in http_client_req()

Enums

enum http_final_call

Values:

enumerator HTTP_DATA_MORE = 0
enumerator HTTP_DATA_FINAL = 1

Functions

int http_client_req(int sock, struct http_request *req, int32_t timeout, void *user_data)

Do a HTTP request. The callback is called when data is received from the HTTP server. The caller must have created a connection to the server before calling this function so connect() call must have be done successfully for the socket.

Parameters
  • sock – Socket id of the connection.

  • req – HTTP request information

  • timeout – Max timeout to wait for the data. The timeout value cannot be 0 as there would be no time to receive the data. The timeout value is in milliseconds.

  • user_data – User specified data that is passed to the callback.

Returns

<0 if error, >=0 amount of data sent to the server

struct http_response
#include <client.h>

HTTP response from the server.

Public Members

const struct http_parser_settings *http_cb

HTTP parser settings for the application usage

http_response_cb_t cb

User provided HTTP response callback which is called when a response is received to a sent HTTP request.

uint8_t *body_frag_start

                  recv_buffer that contains header + body
                  _______________________________________

                              |←-------- body_frag_len ---------→|
           |←--------------------- data len --------------------→|
       ---------------------------------------------------------------
 ..header  |      header      |               body               |  body..
       ---------------------------------------------------------------
           ↑                  ↑
        recv_buf          body_frag_start


                     recv_buffer that contains body only
                     ___________________________________

            |←------------------ body_frag_len ------------------→|
            |←--------------------- data len --------------------→|
       ---------------------------------------------------------------

size_t body_frag_len

Length of the body fragment contained in the recv_buf

uint8_t *recv_buf

Where the response is stored, this is to be provided by the user.

size_t recv_buf_len

Response buffer maximum length

size_t data_len

Length of the data in the result buf. If the value is larger than recv_buf_len, then it means that the data is truncated and could not be fully copied into recv_buf. This can only happen if the user did not set the response callback. If the callback is set, then the HTTP client API will call response callback many times so that all the data is delivered to the user. Will be zero in the event of a null response.

size_t content_length

HTTP Content-Length field value. Will be set to zero in the event of a null response.

size_t processed

Amount of data given to the response callback so far, including the current data given to the callback. This should be equal to the content_length field once the entire body has been received. Will be zero if a null response is given.

uint16_t http_status_code

Numeric HTTP status code which corresponds to the textual description. Set to zero if null response is given. Otherwise, will be a 3-digit integer code if valid HTTP response is given.

struct http_client_internal_data
#include <client.h>

HTTP client internal data that the application should not touch

Public Members

struct k_work_delayable work

Work for handling timeout

struct http_parser parser

HTTP parser context

struct http_parser_settings parser_settings

HTTP parser settings

struct http_response response

HTTP response specific data (filled by http_client_req() when data is received)

void *user_data

User data

int sock

HTTP socket

k_timeout_t timeout

Request timeout

struct http_request
#include <client.h>

HTTP client request. This contains all the data that is needed when doing a HTTP request.

Public Members

struct http_client_internal_data internal

HTTP client request internal data

enum http_method method

The HTTP method: GET, HEAD, OPTIONS, POST, …

http_response_cb_t response

User supplied callback function to call when response is received.

const struct http_parser_settings *http_cb

User supplied list of HTTP callback functions if the calling application wants to know the parsing status or the HTTP fields. This is optional and normally not needed.

uint8_t *recv_buf

User supplied buffer where received data is stored

size_t recv_buf_len

Length of the user supplied receive buffer

const char *url

The URL for this request, for example: /index.html

const char *protocol

The HTTP protocol, for example “HTTP/1.1”

const char **header_fields

The HTTP header fields (application specific) The Content-Type may be specified here or in the next field. Depending on your application, the Content-Type may vary, however some header fields may remain constant through the application’s life cycle. This is a NULL terminated list of header fields.

const char *content_type_value

The value of the Content-Type header field, may be NULL

const char *host

Hostname to be used in the request

const char *port

Port number to be used in the request

http_payload_cb_t payload_cb

User supplied callback function to call when payload needs to be sent. This can be NULL in which case the payload field in http_request is used. The idea of this payload callback is to allow user to send more data that is practical to store in allocated memory.

const char *payload

Payload, may be NULL

size_t payload_len

Payload length is used to calculate Content-Length. Set to 0 for chunked transfers.

http_header_cb_t optional_headers_cb

User supplied callback function to call when optional headers need to be sent. This can be NULL, in which case the optional_headers field in http_request is used. The idea of this optional_headers callback is to allow user to send more HTTP header data that is practical to store in allocated memory.

const char **optional_headers

A NULL terminated list of any optional headers that should be added to the HTTP request. May be NULL. If the optional_headers_cb is specified, then this field is ignored. Note that there are two similar fields that contain headers, the header_fields above and this optional_headers. This is done like this to support Websocket use case where Websocket will use header_fields variable and any optional application specific headers will be placed into this field.