Overview

group index

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 and HEAD to communicate with the HTTP Server.

Features

  • 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 AnyCloud framework to send HTTP request to the server and receive the response. API state machine to perform HTTP send request operation is given below.

AnyCloud - 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

AnyCloud

Supported Frameworks

This middleware library supports the following frameworks:

  • AnyCloud Framework: AnyCloud is a FreeRTOS-based solution. 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 libraries:

AnyCloud

Quick Start

This library is supported only on AnyCloud framework. The following section provides information on how to build the library in those frameworks.

AnyCloud

  • A set of pre-defined configuration files have been bundled with the wifi-mw-core library for FreeRTOS, lwIP, and mbed TLS. Review the configuration and make the required adjustments. See the “Quick Start” section in README.md.

  • 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
    

Code Snippets

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

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

AnyCloud

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.*

#define MAKE_IPV4_ADDRESS(a, b, c, d)     ((((uint32_t) d) << 24) | \
                                          (((uint32_t) c) << 16) | \
                                          (((uint32_t) b) << 8) |\
                                          ((uint32_t) a))

#define SERVER_IP_ADDRESS                 MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define SERVER_HOST                       "httpbin.org"
#define SERVER_PORT                       80

cy_awsport_server_info_t server_info;
cy_http_client_t handle;

void snippet_http_client_non_secure_create( void )
{
    /* Status variables for various operations. */
    cy_rslt_t TestRes = CY_RSLT_SUCCESS;
    (void)TestRes;

    server_info.host_name = SERVER_HOST;
    server_info.port = SERVER_PORT;

    /* Initialize the HTTP Client Library. */
    TestRes = cy_http_client_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }

    /* Create an instance of HTTP client. */
    TestRes = cy_http_client_create(NULL, &server_info, NULL, &handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }

}

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.*

#define MAKE_IPV4_ADDRESS(a, b, c, d)     ((((uint32_t) d) << 24) | \
                                          (((uint32_t) c) << 16) | \
                                          (((uint32_t) b) << 8) |\
                                          ((uint32_t) a))

#define SERVER_IP_ADDRESS                 MAKE_IPV4_ADDRESS(192, 168, 18, 9)

#define SERVER_HOST                       "httpbin.org"
#define SERVER_PORT                       443

/* 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;
cy_http_client_t handle;

void snippet_http_client_secure_create(void)
{
    /* Status variables for various operations. */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    cy_http_disconnect_callback_t http_cb;
    (void)TestRes;

    ( 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 = SERVER_HOST;
    server_info.port = SERVER_PORT;

    /* Initialize the HTTP Client Library. */
    TestRes = cy_http_client_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    http_cb = disconnect_callback;

    /* Create an instance of the HTTP client. */
    TestRes = cy_http_client_create(&credentials, &server_info, http_cb, NULL, &handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

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 MAKE_IPV4_ADDRESS(a, b, c, d)     ((((uint32_t) d) << 24) | \
                                          (((uint32_t) c) << 16) | \
                                          (((uint32_t) b) << 8) |\
                                          ((uint32_t) a))

#define SERVER_IP_ADDRESS                 MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define SERVER_HOST                       "httpbin.org"
#define SERVER_PORT                       80
#define TRANSPORT_SEND_RECV_TIMEOUT_MS    ( 5000 )

cy_awsport_ssl_credentials_t credentials;
cy_awsport_server_info_t server_info;
cy_http_client_t handle;

void snippet_http_client_connect( void )
{
    /* Status variables for various operations. */
    cy_rslt_t TestRes = CY_RSLT_SUCCESS;
    (void)TestRes;

    server_info.host_name = SERVER_HOST;
    server_info.port = SERVER_PORT;

    /* Initialize the HTTP Client Library. */
    TestRes = cy_http_client_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Create an instance of the HTTP client. */
    TestRes = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Connect the HTTP client to server. */
    TestRes = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

}

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 MAKE_IPV4_ADDRESS(a, b, c, d)     ((((uint32_t) d) << 24) | \
                                          (((uint32_t) c) << 16) | \
                                          (((uint32_t) b) << 8) |\
                                          ((uint32_t) a))

#define SERVER_IP_ADDRESS                 MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define SERVER_HOST                       "httpbin.org"
#define SERVER_PORT                       80
#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;
cy_http_client_t handle;
cy_http_client_request_header_t request;
cy_http_client_header_t header;
uint32_t num_header;
cy_http_client_response_t response;

void snippet_http_client_write_header( void )
{
    /* Status variables for various operations. */
    cy_rslt_t TestRes = CY_RSLT_SUCCESS;
    (void)TestRes;

    server_info.host_name = SERVER_HOST;
    server_info.port = SERVER_PORT;

    /* Initialize the HTTP Client Library. */
    TestRes = cy_http_client_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Create an instance of the HTTP client. */
    TestRes = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Connect the HTTP client to server. */
    TestRes = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    request.buffer = userBuffer;
    request.buffer_len = USER_BUFFER_LENGTH;
    request.headers_len = 0;
    request.method = CY_HTTP_CLIENT_METHOD_GET;
    request.range_end = -1;
    request.range_start = 0;
    request.resource_path = GET_PATH;

    header.field = "Connection";
    header.field_len = strlen("Connection");
    header.value = "keep-alive";
    header.value_len = strlen("keep-alive");
    num_header = 1;

    /* Generate the standard header and user-defined header and update in the request structure. */
    TestRes = cy_http_client_write_header(handle, &request, &header, num_header);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }
}

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 MAKE_IPV4_ADDRESS(a, b, c, d)     ((((uint32_t) d) << 24) | \
                                          (((uint32_t) c) << 16) | \
                                          (((uint32_t) b) << 8) |\
                                          ((uint32_t) a))

#define SERVER_IP_ADDRESS                 MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define SERVER_HOST                       "httpbin.org"
#define SERVER_PORT                       80
#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;
cy_http_client_t handle;
cy_http_client_request_header_t request;
cy_http_client_header_t header;
uint32_t num_header;
cy_http_client_response_t response;

void snippet_http_client_send( void )
{
    /* Status variables for various operations. */
    cy_rslt_t TestRes = CY_RSLT_SUCCESS;
    (void)TestRes;

    server_info.host_name = SERVER_HOST;
    server_info.port = SERVER_PORT;

    /* Initialize the HTTP Client Library. */
    TestRes = cy_http_client_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Create an instance of HTTP client. */
    TestRes = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }

    /* Connect HTTP client to server. */
    TestRes = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }

    request.buffer = userBuffer;
    request.buffer_len = USER_BUFFER_LENGTH;
    request.headers_len = 0;
    request.method = CY_HTTP_CLIENT_METHOD_GET;
    request.range_end = -1;
    request.range_start = 0;
    request.resource_path = GET_PATH;

    header.field = "Connection";
    header.field_len = strlen("Connection");
    header.value = "keep-alive";
    header.value_len = strlen("keep-alive");
    num_header = 1;

    /* Generate the standard header and user-defined header, and update in the request structure. */
    TestRes = cy_http_client_write_header(handle, &request, &header, num_header);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Send the HTTP request and body to the server and receive the response from it. */
    TestRes = cy_http_client_send(handle, &request, (uint8_t *)REQUEST_BODY, REQUEST_BODY_LENGTH, &response);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }
}

Code Snippet 6: Read header from the response

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

#define MAKE_IPV4_ADDRESS(a, b, c, d)     ((((uint32_t) d) << 24) | \
                                          (((uint32_t) c) << 16) | \
                                          (((uint32_t) b) << 8) |\
                                          ((uint32_t) a))

#define SERVER_IP_ADDRESS                 MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define SERVER_HOST                       "httpbin.org"
#define SERVER_PORT                       80
#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;
cy_http_client_t handle;
cy_http_client_request_header_t request;
cy_http_client_header_t header;
uint32_t num_header;
cy_http_client_response_t response;

void snippet_http_client_read_header( void )
{
    /* Status variables for various operations. */
    cy_rslt_t TestRes = CY_RSLT_SUCCESS;
    (void)TestRes;

    server_info.host_name = SERVER_HOST;
    server_info.port = SERVER_PORT;

    /* Initialize the HTTP Client Library. */
    TestRes = cy_http_client_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Create an instance of the HTTP client. */
    TestRes = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Connect the HTTP client to the server. */
    TestRes = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    request.buffer = userBuffer;
    request.buffer_len = USER_BUFFER_LENGTH;
    request.headers_len = 0;
    request.method = CY_HTTP_CLIENT_METHOD_GET;
    request.range_end = -1;
    request.range_start = 0;
    request.resource_path = GET_PATH;

    header.field = "Connection";
    header.field_len = strlen("Connection");
    header.value = "keep-alive";
    header.value_len = strlen("keep-alive");
    num_header = 1;

    /* Generate the standard header and user-defined header, and update in the request structure. */
    TestRes = cy_http_client_write_header(handle, &request, &header, num_header);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Send the HTTP request and body to the server, and receive the response from it. */
    TestRes = cy_http_client_send(handle, &request, (uint8_t *)REQUEST_BODY, REQUEST_BODY_LENGTH, &response);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    ( void ) memset( &header, 0, sizeof( header ) );
    header.field = "Connection";
    header.field_len = strlen("Connection");
    num_header = 1;

    /* Read the header value from the HTTP response. */
    TestRes = cy_http_client_read_header(handle, &response, &header, num_header );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }
}

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 MAKE_IPV4_ADDRESS(a, b, c, d)     ((((uint32_t) d) << 24) | \
                                          (((uint32_t) c) << 16) | \
                                          (((uint32_t) b) << 8) |\
                                          ((uint32_t) a))

#define SERVER_IP_ADDRESS                 MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define SERVER_HOST                       "httpbin.org"
#define SERVER_PORT                       80
#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;
cy_http_client_t handle;
cy_http_client_request_header_t request;
cy_http_client_header_t header;
uint32_t num_header;
cy_http_client_response_t response;

void snippet_http_client_teardown( void )
{
    /* Status variables for various operations. */
    cy_rslt_t TestRes = CY_RSLT_SUCCESS;
    (void)TestRes;

    server_info.host_name = SERVER_HOST;
    server_info.port = SERVER_PORT;

    /* Initialize the HTTP Client Library. */
    TestRes = cy_http_client_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Create an instance of the HTTP client. */
    TestRes = cy_http_client_create(&credentials, &server_info, NULL, NULL, &handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Connect the HTTP client to the server. */
    TestRes = cy_http_client_connect(handle, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    request.buffer = userBuffer;
    request.buffer_len = USER_BUFFER_LENGTH;
    request.headers_len = 0;
    request.method = CY_HTTP_CLIENT_METHOD_GET;
    request.range_end = -1;
    request.range_start = 0;
    request.resource_path = GET_PATH;

    header.field = "Connection";
    header.field_len = strlen("Connection");
    header.value = "keep-alive";
    header.value_len = strlen("keep-alive");
    num_header = 1;

    /* Generate the standard header and user-defined header, and update in the request structure. */
    TestRes = cy_http_client_write_header(handle, &request, &header, num_header);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Send the HTTP request and body to the server, and receive the response from it. */
    TestRes = cy_http_client_send(handle, &request, (uint8_t *)REQUEST_BODY, REQUEST_BODY_LENGTH, &response);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    ( void ) memset( &header, 0, sizeof( header ) );
    header.field = "Connection";
    header.field_len = strlen("Connection");
    num_header = 1;

    /* Read the header value from the HTTP response. */
    TestRes = cy_http_client_read_header(handle, &response, &header, num_header);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Disconnect the HTTP client from the server. */
    TestRes = cy_http_client_disconnect(handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Delete the instance of the HTTP client. */
    TestRes = cy_http_client_delete(handle);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }

    /* Deinit the HTTP library. */
    TestRes = cy_http_client_deinit();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path. */
    }
}