HTTP Client Middleware Library
Overview

This library provides the HTTP Client implementation that can work on the PSoC™ 6 MCU platforms with Wi-Fi connectivity.This library supports RESTful methods such as GET, PUT, POST, HEAD, DELETE, PATCH, CONNECT, OPTIONS and TRACE to communicate with the HTTP Server. This library uses coreHTTP module of AWS IoT Device SDK for Embedded C library. Please refer to AWS IoT Device SDK for Embedded C library's readme for the HTTP protocol versions supported.

Features

  • Supports Wi-Fi and Ethernet connections.
  • Secure [with TLS security] and non-secure modes of connection.
  • Supports RESTful HTTP methods: GET, PUT, POST, HEAD, DELETE, PATCH, CONNECT, OPTIONS and TRACE.
  • Handles various resource content types such as HTML, Plain, and JSON.
  • Provides synchronous API to send the request and receive the response.
  • Provide utility APIs to create HTTP headers for forming the HTTP request. And to parse the HTTP headers received in the response.
  • Supports large data downloads through range requests.

AnyCloud State Machine

The HTTP Client library provides C APIs in ModusToolbox™ environment to send HTTP request to the server and receive the response. API state machine to perform HTTP send request operation is given below.

HTTP Client send request

          +-----------------------+
          | cy_http_client_init() |
          +-----------------------+
                     |
                     v
        +----------------------------+
        |    cy_http_client_create() |
        +----------------------------+
                     |
                     v
         +--------------------------+
         | cy_http_client_connect() |
         +--------------------------+
                     |
                     v
       +------------------------------+
       | cy_http_client_write_header()|
       +------------------------------+
                     |
                     v
          +-----------------------+
          | cy_http_client_send() |
          +-----------------------+
                     |
                     v
        +-----------------------------+
        | cy_http_client_disconnect() |
        +-----------------------------+
                     |
                     v
          +-------------------------+
          | cy_http_client_delete() |
          +-------------------------+
                     |
                     v
          +-------------------------+
          | cy_http_client_deinit() |
          +-------------------------+

Supported Platform

Supported Frameworks

This middleware library supports the following frameworks:

  • ModusToolbox™ environment: In this environment the HTTP Client Library uses the abstraction-rtos library that provides the RTOS abstraction API and uses the secure-sockets library for implementing socket functions.

Dependencies

This HTTP Client library depends on the following library:

Quick Start

This library is supported only on ModusToolbox™ environment. The following section provides information on how to build the library in those frameworks.

ModusToolbox™

  • To use http-client library with Wi-Fi kits on FreeRTOS, lwIP, and Mbed TLS combination, the application should pull http-client library and wifi-core-freertos-lwip-mbedtls library which will internally pull secure-sockets, wifi-connection-manager, FreeRTOS, lwIP, Mbed TLS and other dependent modules. To pull wifi-core-freertos-lwip-mbedtls and http-client libraries create the following *.mtb* files in deps folder.
  • To use http-client library with Ethernet kits on FreeRTOS, lwIP, and Mbed TLS combination, the application should pull http-client library and ethernet-core-freertos-lwip-mbedtls library which will internally pull secure-sockets, ethernet-connection-manager, FreeRTOS, lwIP, Mbed TLS and other dependent modules. To pull ethernet-core-freertos-lwip-mbedtls and http-client libraries create the following *.mtb* files in deps folder.
  • Review and make the required changes to the pre-defined configuration files.
    • The configuration files are bundled with the wifi-mw-core library for FreeRTOS, lwIP, and Mbed TLS. See README.md for more details.
    • If the application is using bundle library then the configuration files are in the bundle library. For example if the application is using Wi-Fi core freertos lwip mbedtls bundle library, the configuration files are in wifi-core-freertos-lwip-mbedtls/configs folder. Similarly if the application is using Ethernet Core FreeRTOS lwIP mbedtls library, the configuration files are in ethernet-core-freertos-lwip-mbedtls/configs folder.
  • Define the following COMPONENTS in the application's Makefile for the HTTP client library. For additional information, see the "Quick Start" section in README.md.
    COMPONENTS=FREERTOS MBEDTLS LWIP SECURE_SOCKETS
  • HTTP Client Library disables all the debug log messages by default. To enable log messages, the application must perform the following:
    • Add the ENABLE_HTTP_CLIENT_LOGS macro to the DEFINES in the code example's Makefile. The Makefile entry would look as follows:
      DEFINES+=ENABLE_HTTP_CLIENT_LOGS
    • Call the cy_log_init() function provided by the cy-log module. cy-log is part of the connectivity-utilities library. See connectivity-utilities library API documentation for cy-log details.
  • Define the following macro in the application's Makefile to configure the response header maximum length to 'N'. By default, this value will be set to 2048:
    DEFINES+=HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES=<N>
  • Define the following macro in the application's Makefile to configure the user agent name in all request headers. By default, this component will be added to the request header:
    DEFINES += HTTP_USER_AGENT_VALUE="\"anycloud-http-client\""
  • Define the following macro in the application's Makefile to mandatorily disable the custom configuration header file.
    DEFINES += HTTP_DO_NOT_USE_CUSTOM_CONFIG
    DEFINES += MQTT_DO_NOT_USE_CUSTOM_CONFIG
  • The "aws-iot-device-sdk-port" layer includes the "coreHTTP" and "coreMQTT" modules of the "aws-iot-device-sdk-embedded-C" library by default. If the user application doesn't use MQTT client features, add the following path in the .cyignore file of the application to exclude the coreMQTT source files from the build.
    $(SEARCH_aws-iot-device-sdk-embedded-C)/libraries/standard/coreMQTT
    libs/aws-iot-device-sdk-embedded-C/libraries/standard/coreMQTT

Code Snippets

This section provides code snippets for this library on the ModusToolbox™. The code snippets given under the ModusToolbox™ section use C APIs. In general, the library features are tested on ModusToolbox™ using C APIs.

  • ModusToolbox™ - Snippets for HTTP Client create, connect, send, disconnect and delete (C implementation).

ModusToolbox™

This code snippet demonstrates the initialization of the configuration structures required for the operation such as creating a secure or non-secure connection and communicating with the HTTP server using the supported methods.

Code Snippet 1: Creation and Initialization of Handle for Non-Secure HTTP Client

Creates an HTTP Client handle for a non-secure HTTP connection using the cy_http_client_create function.*

cy_awsport_server_info_t server_info;
void snippet_http_client_non_secure_create( void )
{
/* Status variables for various operations. */
cy_rslt_t res = CY_RSLT_SUCCESS;
server_info.host_name = SNIPPET_SERVER_HOST;
server_info.port = SNIPPET_SERVER_NON_SECURE_PORT;
/* Initialize the HTTP Client Library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path */
}
/* Create an instance of HTTP client. */
res = cy_http_client_create(NULL, &server_info, NULL, NULL, &handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path */
}
}
cy_rslt_t cy_http_client_init(void)
Initializes the Http Client library and its components.
cy_rslt_t cy_http_client_create(cy_awsport_ssl_credentials_t *security, cy_awsport_server_info_t *server_info, cy_http_disconnect_callback_t disconn_cb, void *user_data, cy_http_client_t *handle)
Creates a HTTP Client instance and initializes its members based on the input arguments.
void * cy_http_client_t
HTTP Client handle.
Definition: cy_http_client_api.h:175

Code Snippet 2: Creation and Initialization of Handle for Secure HTTP Client

Creates an HTTP Client handle for a secure HTTP connection using the cy_http_client_create function.*

/* Configure the following credentials for a secure HTTP connection. */
/* SSL server certificate. */
#define SSL_SERVERCERT_PEM \
"-----BEGIN CERTIFICATE-----\n" \
"........base64 data........\n" \
"-----END CERTIFICATE-----"
/* SSL server private key. */
#define SSL_SERVERKEY_PEM \
"-----BEGIN RSA PRIVATE KEY-----\n" \
"..........base64 data..........\n" \
"-----END RSA PRIVATE KEY-----"
#define SSL_ROOTCA_PEM \
"-----BEGIN CERTIFICATE-----\n" \
"........base64 data........\n" \
"-----END CERTIFICATE-----"
cy_awsport_ssl_credentials_t credentials;
cy_awsport_server_info_t server_info;
void disconn_callback( cy_http_client_t handle, cy_http_client_disconn_type_t type, void *user_data )
{
/* Handle the disconnection */
}
void snippet_http_client_secure_create(void)
{
/* Status variables for various operations. */
cy_rslt_t res = CY_RSLT_SUCCESS;
( void ) memset( &credentials, 0, sizeof( credentials ) );
( void ) memset( &server_info, 0, sizeof( server_info ) );
/* Set the credential information. */
credentials.client_cert = (const char *) &SSL_SERVERCERT_PEM;
credentials.client_cert_size = sizeof( SSL_SERVERCERT_PEM );
credentials.private_key = (const char *) &SSL_SERVERKEY_PEM;
credentials.private_key_size = sizeof( SSL_SERVERKEY_PEM );
credentials.root_ca = (const char *) &SSL_ROOTCA_PEM;
credentials.root_ca_size = sizeof( SSL_ROOTCA_PEM );
server_info.host_name = SNIPPET_SERVER_HOST;
server_info.port = SNIPPET_SERVER_SECURE_PORT;
/* Initialize the HTTP Client Library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
http_cb = disconn_callback;
/* Create an instance of the HTTP client. */
res = cy_http_client_create(&credentials, &server_info, http_cb, NULL, &handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path */
}
}
cy_http_client_disconn_type_t
HTTP Client disconnect type.
Definition: cy_http_client_api.h:164
void(* cy_http_disconnect_callback_t)(cy_http_client_t handle, cy_http_client_disconn_type_t type, void *user_data)
Disconnect notification callback function which was registered while invoking /ref cy_http_client_cre...
Definition: cy_http_client_api.h:187

Code Snippet 3: Establish connection to the given server

Establish connection of http client to given HTTP server using the cy_http_client_connect function.*

#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 5000 )
cy_awsport_ssl_credentials_t credentials;
cy_awsport_server_info_t server_info;
void snippet_http_client_connect( void )
{
/* Status variables for various operations. */
cy_rslt_t res = CY_RSLT_SUCCESS;
server_info.host_name = SNIPPET_SERVER_HOST;
server_info.port = SNIPPET_SERVER_NON_SECURE_PORT;
/* Initialize the HTTP Client Library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Create an instance of the HTTP client. */
res = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Connect the HTTP client to server. */
res = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
}
cy_rslt_t cy_http_client_connect(cy_http_client_t handle, uint32_t send_timeout_ms, uint32_t receive_timeout_ms)
Connects to the given HTTP server and establishes a connection.

Code Snippet 4: Generation of HTTP request header

Generate HTTP request header with the provided input using the cy_http_client_write_header function.*

#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 5000 )
#define GET_PATH "/get"
#define USER_BUFFER_LENGTH ( 2048 )
uint8_t userBuffer[ USER_BUFFER_LENGTH ];
cy_awsport_ssl_credentials_t credentials;
cy_awsport_server_info_t server_info;
uint32_t num_header;
void snippet_http_client_write_header( void )
{
/* Status variables for various operations. */
cy_rslt_t res = CY_RSLT_SUCCESS;
server_info.host_name = SNIPPET_SERVER_HOST;
server_info.port = SNIPPET_SERVER_NON_SECURE_PORT;
/* Initialize the HTTP Client Library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Create an instance of the HTTP client. */
res = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Connect the HTTP client to server. */
res = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
request.buffer = userBuffer;
request.buffer_len = USER_BUFFER_LENGTH;
request.headers_len = 0;
request.range_end = -1;
request.range_start = 0;
request.resource_path = GET_PATH;
header[0].field = "Connection";
header[0].field_len = strlen("Connection");
header[0].value = "keep-alive";
header[0].value_len = strlen("keep-alive");
num_header = 1;
/* Generate the standard header and user-defined header and update in the request structure. */
res = cy_http_client_write_header(handle, &request, &header[0], num_header);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
}
cy_rslt_t cy_http_client_write_header(cy_http_client_t handle, cy_http_client_request_header_t *request, cy_http_client_header_t *header, uint32_t num_header)
Generates the request Header used as HTTP Client request header during cy_http_client_send.
@ CY_HTTP_CLIENT_METHOD_GET
HTTP GET Method
Definition: cy_http_client_api.h:149
HTTP structure containing the HTTP header fields.
Definition: cy_http_client_api.h:196
char * value
HTTP header value corresponding to the field.
Definition: cy_http_client_api.h:199
size_t field_len
HTTP field length.
Definition: cy_http_client_api.h:198
size_t value_len
HTTP header value length.
Definition: cy_http_client_api.h:200
char * field
HTTP header field such as host, date, content_length, etc.
Definition: cy_http_client_api.h:197
HTTP structure containing the fields required for the request header.
Definition: cy_http_client_api.h:207
int32_t range_end
Indicates the End Range until where the data is expected.
Definition: cy_http_client_api.h:216
uint8_t * buffer
Pointer to the buffer to store HTTP request and the HTTP response received from the server.
Definition: cy_http_client_api.h:210
int32_t range_start
Indicates the Start Range from where the server should return.
Definition: cy_http_client_api.h:215
size_t headers_len
Length of the request header updated in cy_http_client_write_header, or the user has to update this f...
Definition: cy_http_client_api.h:213
const char * resource_path
Path to which HTTP Client request has to be sent; NULL terminated.
Definition: cy_http_client_api.h:209
cy_http_client_method_t method
Method for which the HTTP Client request has to be sent.
Definition: cy_http_client_api.h:208
size_t buffer_len
Length of the buffer in bytes.
Definition: cy_http_client_api.h:212
HTTP structure containing the fields required for response header and body.
Definition: cy_http_client_api.h:225

Code Snippet 5: Send a HTTP request to server

Send a HTTP request (header + body) to the server and receive response by using cy_http_client_send function.*

#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 5000 )
#define GET_PATH "/get"
#define USER_BUFFER_LENGTH ( 2048 )
#define REQUEST_BODY "Hello, world!"
#define REQUEST_BODY_LENGTH ( sizeof( REQUEST_BODY ) - 1 )
uint8_t userBuffer[ USER_BUFFER_LENGTH ];
cy_awsport_ssl_credentials_t credentials;
cy_awsport_server_info_t server_info;
uint32_t num_header;
void snippet_http_client_send( void )
{
/* Status variables for various operations. */
cy_rslt_t res = CY_RSLT_SUCCESS;
server_info.host_name = SNIPPET_SERVER_HOST;
server_info.port = SNIPPET_SERVER_NON_SECURE_PORT;
/* Initialize the HTTP Client Library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Create an instance of HTTP client. */
res = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path */
}
/* Connect HTTP client to server. */
res = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path */
}
request.buffer = userBuffer;
request.buffer_len = USER_BUFFER_LENGTH;
request.headers_len = 0;
request.range_end = -1;
request.range_start = 0;
request.resource_path = GET_PATH;
header[0].field = "Connection";
header[0].field_len = strlen("Connection");
header[0].value = "keep-alive";
header[0].value_len = strlen("keep-alive");
num_header = 1;
/* Generate the standard header and user-defined header, and update in the request structure. */
res = cy_http_client_write_header(handle, &request, &header[0], num_header);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Send the HTTP request and body to the server and receive the response from it. */
res = cy_http_client_send(handle, &request, (uint8_t *)REQUEST_BODY, REQUEST_BODY_LENGTH, &response);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
}
cy_rslt_t cy_http_client_send(cy_http_client_t handle, cy_http_client_request_header_t *request, uint8_t *payload, uint32_t payload_len, cy_http_client_response_t *response)
Sends the HTTP request to the server and returns the received HTTP response from the server.

Code Snippet 6: Read header from the response

Read HTTP header from the received response using the cy_http_client_read_header function.*

#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 5000 )
#define GET_PATH "/get"
#define USER_BUFFER_LENGTH ( 2048 )
#define REQUEST_BODY "Hello, world!"
#define REQUEST_BODY_LENGTH ( sizeof( REQUEST_BODY ) - 1 )
uint8_t userBuffer[ USER_BUFFER_LENGTH ];
cy_awsport_ssl_credentials_t credentials;
cy_awsport_server_info_t server_info;
uint32_t num_header;
void snippet_http_client_read_header( void )
{
/* Status variables for various operations. */
cy_rslt_t res = CY_RSLT_SUCCESS;
server_info.host_name = SNIPPET_SERVER_HOST;
server_info.port = SNIPPET_SERVER_NON_SECURE_PORT;
/* Initialize the HTTP Client Library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Create an instance of the HTTP client. */
res = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Connect the HTTP client to the server. */
res = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
request.buffer = userBuffer;
request.buffer_len = USER_BUFFER_LENGTH;
request.headers_len = 0;
request.range_end = -1;
request.range_start = 0;
request.resource_path = GET_PATH;
header[0].field = "Connection";
header[0].field_len = strlen("Connection");
header[0].value = "keep-alive";
header[0].value_len = strlen("keep-alive");
num_header = 1;
/* Generate the standard header and user-defined header, and update in the request structure. */
res = cy_http_client_write_header(handle, &request, &header[0], num_header);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Send the HTTP request and body to the server, and receive the response from it. */
res = cy_http_client_send(handle, &request, (uint8_t *)REQUEST_BODY, REQUEST_BODY_LENGTH, &response);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
( void ) memset( &header[0], 0, sizeof( header[0] ) );
header[0].field = "Connection";
header[0].field_len = strlen("Connection");
num_header = 1;
/* Read the header value from the HTTP response. */
res = cy_http_client_read_header(handle, &response, &header[0], num_header );
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
}
cy_rslt_t cy_http_client_read_header(cy_http_client_t handle, cy_http_client_response_t *response, cy_http_client_header_t *header, uint32_t num_header)
Parses the headers received in the HTTP response.

Code Snippet 7: Close the connection with server

Disconnect from the HTTP server, and release the HTTP Client library resources by using cy_http_client_disconnect, cy_http_client_delete and cy_http_client_deinit API functions.*

#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 5000 )
#define GET_PATH "/get"
#define USER_BUFFER_LENGTH ( 2048 )
#define REQUEST_BODY "Hello, world!"
#define REQUEST_BODY_LENGTH ( sizeof( REQUEST_BODY ) - 1 )
uint8_t userBuffer[ USER_BUFFER_LENGTH ];
cy_awsport_ssl_credentials_t credentials;
cy_awsport_server_info_t server_info;
uint32_t num_header;
void snippet_http_client_teardown( void )
{
/* Status variables for various operations. */
cy_rslt_t res = CY_RSLT_SUCCESS;
server_info.host_name = SNIPPET_SERVER_HOST;
server_info.port = SNIPPET_SERVER_NON_SECURE_PORT;
/* Initialize the HTTP Client Library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Create an instance of the HTTP client. */
res = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Connect the HTTP client to the server. */
res = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
request.buffer = userBuffer;
request.buffer_len = USER_BUFFER_LENGTH;
request.headers_len = 0;
request.range_end = -1;
request.range_start = 0;
request.resource_path = GET_PATH;
header[0].field = "Connection";
header[0].field_len = strlen("Connection");
header[0].value = "keep-alive";
header[0].value_len = strlen("keep-alive");
num_header = 1;
/* Generate the standard header and user-defined header, and update in the request structure. */
res = cy_http_client_write_header(handle, &request, &header[0], num_header);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Send the HTTP request and body to the server, and receive the response from it. */
res = cy_http_client_send(handle, &request, (uint8_t *)REQUEST_BODY, REQUEST_BODY_LENGTH, &response);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
( void ) memset( &header[0], 0, sizeof( header[0] ) );
header[0].field = "Connection";
header[0].field_len = strlen("Connection");
num_header = 1;
/* Read the header value from the HTTP response. */
res = cy_http_client_read_header(handle, &response, &header[0], num_header);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Disconnect the HTTP client from the server. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Delete the instance of the HTTP client. */
res = cy_http_client_delete(handle);
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
/* Deinit the HTTP library. */
if( res != CY_RSLT_SUCCESS )
{
/* Failure path. */
}
}
cy_rslt_t cy_http_client_deinit(void)
De-initializes the global resources used by the HTTP Client library.
cy_rslt_t cy_http_client_disconnect(cy_http_client_t handle)
Disconnects the HTTP Client network connection.
cy_rslt_t cy_http_client_delete(cy_http_client_t handle)
Deletes the HTTP Client library Object.