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