Overview

group index

This library provides the HTTP Server implementation that can work on the PSoC 6 MCU platforms with Wi-Fi connectivity.It supports RESTful methods such as GET, PUT, and POST for the client to communicate with this HTTP Server library.

Features

  • Secure [with TLS security] and non-secure modes of connection.

  • Supports RESTful HTTP methods: GET, PUT, and POST.

  • Handles various resource content types such as HTML, Plain, and JSON.

  • Capable of handling content payload greater than the MTU size using the Content-Length HTTP header. This feature is supported only for CY_RAW_DYNAMIC_URL_CONTENT and CY_DYNAMIC_URL_CONTENT content types

  • Supports chunked encoding for GET and POST methods.

  • Supports Server-Sent Events (SSE). SSE is a server push technology, enabling an HTTP client (for example, a browser or any device running an HTTP client) to receive automatic updates from the HTTP server via the HTTP connection.

Supported Platforms

AnyCloud

Mbed OS

Supported Frameworks

This middleware library supports the following frameworks:

  • AnyCloud Framework: AnyCloud is a FreeRTOS-based solution. HTTP Server Library uses the abstraction-rtos library that provides the RTOS abstraction API and uses the secure-sockets library for implementing socket functions.

  • Mbed Framework: Mbed framework is a Mbed OS-based solution. HTTP Server Library uses the abstraction-rtos library that provides RTOS abstraction API and uses the Mbed socket API for implementing socket functions.

Dependencies

This HTTP Server library depends on the following libraries. All these libraries are included by default.

AnyCloud

Mbed OS

Quick Start

This library is supported on both AnyCloud and Mbed OS frameworks. The section below provides information on how to build the library in those framework.

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 following COMPONENTS in the application’s makefile for the HTTP Server Library. For additional information, see the “Quick Start” section in README.md.

    COMPONENTS=FREERTOS MBEDTLS LWIP SECURE_SOCKETS
    

  • HTTP Server Library disables all the debug log messages by default. To enable log messages, the application must perform the following:

    • Add ENABLE_HTTP_SERVER_LOGS macro to the DEFINES in the code example’s Makefile. The Makefile entry would look like as follows:

      DEFINES+=ENABLE_HTTP_SERVER_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 application’s makefile to configure the maximum number of HTTP server resources to ‘N’:

    DEFINES+=MAX_NUMBER_OF_HTTP_SERVER_RESOURCES=<N>
    

Mbed OS

  • HTTP Server Library disables all the debug log messages by default. To enable log messages, the application must perform the following:

    • Add ENABLE_HTTP_SERVER_LOGS macro to the DEFINES in the code example’s JSON file. The JSON file entry would look like as follows:

      "macros": ["ENABLE_HTTP_SERVER_LOGS"],
      "target.components_add": ["MBED"],
      

    • 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 JSON file to configure the maximum number of HTTP server resources to ‘N’:

    "macros": ["MAX_NUMBER_OF_HTTP_SERVER_RESOURCES=<N>"],
    

Code Snippets

This section provides code snippets for this library on AnyCloud and Mbed OS frameworks. The code snippets given under the AnyCloud section uses C APIs, whereas the snippets given under Mbed OS use C++ Class to demonstrate the library usage. In general, the library features are tested on Mbed OS using C++ Class interface, and tested on AnyCloud using C APIs.

  • AnyCloud - Snippets for HTTP Server create, start, stop, and delete (C implementation).

  • Mbed OS - Snippets for HTTP server create, start, stop, and delete (C++ implementation).

AnyCloud

These code snippets demonstrate the initialization of the configuration structures required for the operation such as creating a secure or non-secure connection and registering a static or dynamic resource with the HTTP server.

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

Creates an HTTP server handle for a non-secure HTTP connection using the cy_http_server_create API 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 HTTP_PORT         80
#define MAX_SOCKETS       2

cy_http_server_t          httpSer;
cy_network_interface_t    nw_interface;
cy_socket_sockaddr_t      IP_address;

void snippet_http_non_secure_create(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTP_PORT, MAX_SOCKETS, NULL, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

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

Creates an HTTP server handle for a secure HTTP connection using the cy_http_server_create API 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 HTTPS_PORT             443
#define MAX_SOCKETS            2

/* 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-----"

cy_http_server_t          httpSer;
cy_network_interface_t    nw_interface;
cy_socket_sockaddr_t      IP_address;

void snippet_http_secure_create(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    cy_https_server_security_info_t security_cred;

    security_cred.certificate                = (uint8_t*) SSL_SERVERCERT_PEM;
    security_cred.certificate_length         = strlen(SSL_SERVERCERT_PEM);
    security_cred.private_key                = (uint8_t*) SSL_SERVERKEY_PEM;
    security_cred.key_length                 = strlen(SSL_SERVERKEY_PEM);
    security_cred.root_ca_certificate        = NULL;
    security_cred.root_ca_certificate_length = 0;

    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTPS_PORT, MAX_SOCKETS, &security_cred, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

Code Snippet 3: Registering a Static Resource

Registers a static resource with the HTTP server using the cy_http_server_register_resource API 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 HTTP_PORT            80
#define MAX_SOCKETS          2

/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

cy_http_server_t          httpSer;
cy_network_interface_t    nw_interface;
cy_socket_sockaddr_t      IP_address;

void snippet_http_static_reg_resource(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTP_PORT, MAX_SOCKETS, NULL, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Register a static resource with the HTTP server */
    cy_resource_static_data_t static_resource;
    static_resource.data = CAPTIVE_PORTAL_REDIRECT_PAGE;
    static_resource.length = sizeof( CAPTIVE_PORTAL_REDIRECT_PAGE );
    TestRes = cy_http_server_register_resource( httpSer, (uint8_t*) "/get", (uint8_t*)"text/html", CY_STATIC_URL_CONTENT, &static_resource);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

Code Snippet 4: Registering a Dynamic Resource

Registers a dynamic resource with the HTTP server using the cy_http_server_register_resource API 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 HTTP_PORT            80
#define MAX_SOCKETS          2
#define BUFFER_LENGTH        1500

/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

cy_http_server_t          httpSer;
cy_network_interface_t    nw_interface;
cy_socket_sockaddr_t      IP_address;
static char               buffer[BUFFER_LENGTH];
int                       length = 0;

int32_t process_handler( const char* url_path, const char* url_parameters, cy_http_response_stream_t* stream,
                         void* arg, cy_http_message_body_t* http_message_body )
{
    memset(buffer, 0, BUFFER_LENGTH);
    memcpy( buffer, http_message_body->data, http_message_body->data_length);
    length += http_message_body->data_length;
    if (http_message_body->data_remaining == 0)
    {
        cy_http_server_response_stream_write_payload(stream, CAPTIVE_PORTAL_REDIRECT_PAGE, sizeof(CAPTIVE_PORTAL_REDIRECT_PAGE));
        length = 0;
        memset(buffer, 0, BUFFER_LENGTH);
    }
    return 0;
}

void snippet_http_dynamic_reg_resource(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTP_PORT, MAX_SOCKETS, NULL, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Register a dynamic resource with the HTTP server */
    cy_resource_dynamic_data_t dynamic_resource;
    dynamic_resource.resource_handler = process_handler;
    dynamic_resource.arg = NULL;
    TestRes = cy_http_server_register_resource( httpSer, (uint8_t*) "/post", (uint8_t*)"text/html", CY_DYNAMIC_URL_CONTENT, &dynamic_resource);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

Code Snippet 5: Registering a Server-Sent Event (SSE)

Registers a Server-Sent Event using the cy_http_server_register_resource API 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 HTTP_PORT                80
#define MAX_SOCKETS              2
#define CHUNKED_CONTENT_LENGTH   0

cy_http_server_t               httpSer;
cy_network_interface_t         nw_interface;
cy_http_response_stream_t*     http_event_stream;
cy_socket_sockaddr_t           IP_address;

int32_t anycloud_process_SSE_handler( const char* url_path, const char* url_parameters,
                                      cy_http_response_stream_t* stream, void* arg,
                                      cy_http_message_body_t* http_message_body )
{
    http_event_stream = stream;
    /* Enable chunked transfer encoding on the HTTP stream */
    cy_http_server_response_stream_enable_chunked_transfer( http_event_stream );
    cy_http_server_response_stream_write_header( http_event_stream, CY_HTTP_200_TYPE, CHUNKED_CONTENT_LENGTH,
                                               CY_HTTP_CACHE_DISABLED, MIME_TYPE_TEXT_EVENT_STREAM );
    /* Disable chunked transfer encoding on the HTTP stream after header write is completed */
    cy_http_server_response_stream_disable_chunked_transfer( http_event_stream );
    return 0;
}

void snippet_http_server_event_reg(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTP_PORT, MAX_SOCKETS, NULL, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    cy_resource_dynamic_data_t dynamic_sse_resource;
    dynamic_sse_resource.resource_handler = anycloud_process_SSE_handler;
    dynamic_sse_resource.arg = NULL;
    TestRes = cy_http_server_register_resource( httpSer, (uint8_t*) "/events", (uint8_t*)"text/event-stream", CY_RAW_DYNAMIC_URL_CONTENT, &dynamic_sse_resource);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

Code Snippet 6: HTTP Server Start

Starts the HTTP server using the cy_http_server_start API 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 HTTP_PORT            80
#define MAX_SOCKETS          2

/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

cy_http_server_t          httpSer;
cy_network_interface_t    nw_interface;
cy_socket_sockaddr_t      IP_address;

void snippet_http_server_start(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTP_PORT, MAX_SOCKETS, NULL, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Register a static resource with the HTTP server */
    cy_resource_static_data_t static_resource;
    static_resource.data = CAPTIVE_PORTAL_REDIRECT_PAGE;
    static_resource.length = sizeof( CAPTIVE_PORTAL_REDIRECT_PAGE );
    TestRes = cy_http_server_register_resource( httpSer, (uint8_t*) "/get", (uint8_t*)"text/html", CY_STATIC_URL_CONTENT, &static_resource );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Start HTTP server */
    TestRes = cy_http_server_start( httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

Code Snippet 7: Sending HTTP Server Events

Sends HTTP server events using the cy_http_server_response_stream_write_header API 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 HTTP_PORT              80
#define MAX_SOCKETS            2

#define SSE_PAYLOAD            "Hello, This is server sent events \r\n"
#define LFLF                   "\n\n"
#define EVENT_STREAM_DATA      "data: "
#define CHUNKED_CONTENT_LENGTH 0

cy_http_response_stream_t*     http_event_stream;
cy_http_server_t               httpSer;
cy_network_interface_t         nw_interface;
cy_socket_sockaddr_t           IP_address;

int32_t process_SSE_handler( const char* url_path, const char* url_parameters,
                                           cy_http_response_stream_t* stream, void* arg,
                                           cy_http_message_body_t* http_message_body )
{
    http_event_stream = stream;
    cy_http_server_response_stream_enable_chunked_transfer( http_event_stream );
    cy_http_server_response_stream_write_header( http_event_stream, CY_HTTP_200_TYPE, CHUNKED_CONTENT_LENGTH,
                                                 CY_HTTP_CACHE_DISABLED, MIME_TYPE_TEXT_EVENT_STREAM );
    return 0;
}

void send_events()
{
    cy_rslt_t result;
    if( http_event_stream == NULL )
    {
        return;
    }
    result = cy_http_server_response_stream_write_payload( http_event_stream, (const void*)EVENT_STREAM_DATA, sizeof( EVENT_STREAM_DATA ) - 1 );
    if ( result != CY_RSLT_SUCCESS )
    {
        http_event_stream = NULL;
        return;
    }
    /* Send message to client */
    result = cy_http_server_response_stream_write_payload( http_event_stream, SSE_PAYLOAD, sizeof(SSE_PAYLOAD) - 1);
    if ( result != CY_RSLT_SUCCESS )
    {
        http_event_stream = NULL;
        return;
    }
    /* SSE is ended with two line feeds */
    result = cy_http_server_response_stream_write_payload( http_event_stream, (const void*)LFLF, sizeof( LFLF ) - 1 );
    if ( result != CY_RSLT_SUCCESS )
    {
        http_event_stream = NULL;
        return;
    }

    return;
}

void snippet_http_server_send_events(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTP_PORT, MAX_SOCKETS, NULL, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    cy_resource_dynamic_data_t dynamic_sse_resource;
    dynamic_sse_resource.resource_handler = process_SSE_handler;
    dynamic_sse_resource.arg = NULL;
    TestRes = cy_http_server_register_resource( httpSer, (uint8_t*) "/events", (uint8_t*)"text/event-stream", CY_RAW_DYNAMIC_URL_CONTENT, &dynamic_sse_resource);
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Start HTTP server */
    TestRes = cy_http_server_start( httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Send server events */
    if( http_event_stream != NULL )
    {
        send_events();
    }
    /* Disconnect event stream */
    TestRes = cy_http_server_response_stream_disconnect( http_event_stream );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Disconnect all streams */
    TestRes = cy_http_server_response_stream_disconnect_all( httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

Code Snippet 8: HTTP Server Stop

Stops the HTTP server using the cy_http_server_stop API 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 HTTP_PORT            80
#define MAX_SOCKETS          2

/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

cy_http_server_t          httpSer;
cy_network_interface_t    nw_interface;
cy_socket_sockaddr_t      IP_address;

void snippet_http_server_stop(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    /* IP address of the server */
    IP_address.ip_address.ip.v4 = SERVER_IP_ADDRESS;
    IP_address.ip_address.version = CY_SOCKET_IP_VER_V4;

    /* Add the IP_address information to the network interface object */
    nw_interface.object  = (void *) &IP_address;
    nw_interface.type = CY_NW_INF_TYPE_WIFI;

    /* Initialize the network socket */
    TestRes = cy_http_server_network_init();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    TestRes = cy_http_server_create( &nw_interface, HTTP_PORT, MAX_SOCKETS, NULL, &httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Register a static resource with the HTTP server */
    cy_resource_static_data_t static_resource;
    static_resource.data = CAPTIVE_PORTAL_REDIRECT_PAGE;
    static_resource.length = sizeof( CAPTIVE_PORTAL_REDIRECT_PAGE );
    cy_http_server_register_resource( httpSer, (uint8_t*) "/get", (uint8_t*)"text/html", CY_STATIC_URL_CONTENT, &static_resource );
    /* Start HTTP server */
    TestRes = cy_http_server_start( httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Stop the HTTP server */
    TestRes = cy_http_server_stop( httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Delete the HTTP server object */
    TestRes = cy_http_server_delete( httpSer );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
    /* Deinitialize the network socket */
    TestRes = cy_http_server_network_deinit();
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* Failure path */
    }
}

Code Snippet 9: HTTP URL query

Search a key-value pair, fetch the value of a key, and get the number of queries from the given URL using URL-processing functions.

void snippet_http_server_url_query(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    (void)TestRes;
    const char url[] = "https://example.com/?product=shirt&color=blue&newuser&size=m\n";
    const char key[] = "product\n";
    const char value[] = "shirt\n";
    char *value_found = NULL;
    uint32_t value_length = 0;
    uint32_t query_param_count = 0;

    /* Check if the provided key-value pair is present in the given URL */
    TestRes = cy_http_server_match_query_parameter( url, key, value );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* URL query failed */
    }
    /* Retrieve the value and length for a given key from the URL */
    TestRes = cy_http_server_get_query_parameter_value( url, key, &value_found, &value_length );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* URL query failed */
    }
    /* Get the number of query parameters found in the URL query string. */
    TestRes = cy_http_server_get_query_parameter_count( url, &query_param_count );
    if( TestRes != CY_RSLT_SUCCESS )
    {
        /* URL query failed */
    }
}

Mbed OS

These code snippets demonstrate the initialization of the configuration structures required for the operation such as creating a secure or non-secure connection and registering a static or dynamic resource with the HTTP server.

Code Snippet 1: Creation and initialization of a non-secure HTTP server object

Creates a non-secure HTTP connection using the HTTPServer() constructor.

#define HTTP_PORT         80
#define MAX_SOCKETS       2

void snippet_http_non_secure_new(void)
{
    cy_network_interface_t nw_interface;
    HTTPServer*            server;
    NetworkInterface*      network;
    (void)server;
    
    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create instance of HTTP server */
    server = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);
    if(server != NULL)
    {
        /* HTTP server object created successfully */
    }
}

Code Snippet 2: Creation and initialization of a secure HTTP server object

Creates a secure HTTP connection using the HTTPServer() constructor.

#define HTTPS_PORT         443
#define MAX_SOCKETS        2

/* Configure the following credentials for an HTTP secure 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-----"

void snippet_http_secure_new(void)
{
    NetworkInterface*      network;
    cy_network_interface_t nw_interface;
    HTTPServer*            server;
    (void)server;
        
    cy_https_server_security_info_t security_cred;
    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    security_cred.certificate                = (uint8_t*) SSL_SERVERCERT_PEM;
    security_cred.certificate_length         = strlen(SSL_SERVERCERT_PEM);
    security_cred.private_key                = (uint8_t*) SSL_SERVERKEY_PEM;
    security_cred.key_length                 = strlen(SSL_SERVERKEY_PEM);
    security_cred.root_ca_certificate        = NULL;
    security_cred.root_ca_certificate_length = 0;

    server = new HTTPServer(&nw_interface, HTTPS_PORT, MAX_SOCKETS, &security_cred);
    if(server != NULL)
    {
        /* HTTP server object created successfully */
    }
}

Code Snippet 3: Registering a static resource

Registers a static resource with the HTTP server using the register_resource() API function.

#define HTTP_PORT         80
#define MAX_SOCKETS       2

/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

void snippet_mbed_http_static_reg_resource(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    NetworkInterface*      network;
    cy_network_interface_t nw_interface;
    HTTPServer*            server;
    (void)TestRes;

    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create an instance of the HTTP server */
    server = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);

    /* Register a static resource with the HTTP server */
    cy_resource_static_data_t static_resource;
    static_resource.data = CAPTIVE_PORTAL_REDIRECT_PAGE;
    static_resource.length = sizeof( CAPTIVE_PORTAL_REDIRECT_PAGE );
    TestRes = server->register_resource((uint8_t*) "/get", (uint8_t*)"text/html", CY_STATIC_URL_CONTENT, &static_resource);
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Register Static resource completed */
    }
}

Code Snippet 4: Registering a dynamic resource

Registers a dynamic resource with the HTTP server using the register_resource() API function.

#define HTTP_PORT         80
#define MAX_SOCKETS       2
#define BUFFER_LENGTH     1500
/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

HTTPServer             *server;
static char            buffer[BUFFER_LENGTH];

int32_t process_handler( const char* url_path, const char* url_parameters, cy_http_response_stream_t* stream, void* arg, cy_http_message_body_t* http_message_body )
{
    int    length = 0;
    memset(buffer, 0, BUFFER_LENGTH);
    memcpy( buffer, http_message_body->data, http_message_body->data_length);
    length += http_message_body->data_length;
    if (http_message_body->data_remaining == 0)
    {
        server->http_response_stream_write(stream, CAPTIVE_PORTAL_REDIRECT_PAGE, sizeof(CAPTIVE_PORTAL_REDIRECT_PAGE));
        length = 0;
        memset(buffer, 0, BUFFER_LENGTH);
    }
    return 0;
}

void snippet_mbed_http_dynamic_reg_resource(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    NetworkInterface*      network;
    cy_network_interface_t nw_interface;

    (void)TestRes;
    
    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create an instance of the HTTP server */
    server = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);

    /* Register a dynamic resource with the HTTP server */
    cy_resource_dynamic_data_t dynamic_resource;
    dynamic_resource.resource_handler = process_handler;
    dynamic_resource.arg = NULL;
    TestRes = server->register_resource((uint8_t*) "/post", (uint8_t*)"text/html", CY_DYNAMIC_URL_CONTENT, &dynamic_resource);
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Register dynamic resource completed */
    }
}

Code Snippet 5: Registering a Server-Sent Events

Registers a Server-Sent Events using the register_resource() API function.

#define HTTP_PORT                80
#define MAX_SOCKETS              2
#define CHUNKED_CONTENT_LENGTH   0

cy_http_response_stream_t      *event_stream ;
HTTPServer                     *server_obj;

int32_t snip_mbed_process_SSE_handler( const char* url_path, const char* url_parameters,
                                       cy_http_response_stream_t* stream, void* arg,
                                       cy_http_message_body_t* http_message_body )
{
    event_stream = stream;
    /* Enable chunked transfer encoding on the HTTP stream */
    server_obj->http_response_stream_enable_chunked_transfer( event_stream );
    server_obj->http_response_stream_write_header( event_stream, CY_HTTP_200_TYPE,
                                               CHUNKED_CONTENT_LENGTH, CY_HTTP_CACHE_DISABLED,
                                               MIME_TYPE_TEXT_EVENT_STREAM );
    /* Disable chunked transfer encoding on the HTTP stream after header write is completed */
    server_obj->http_response_stream_disable_chunked_transfer( event_stream );
    return 0;
}

void snippet_mbed_http_server_event_reg(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes       = CY_RSLT_ERROR;
    NetworkInterface*         network;
    cy_network_interface_t    nw_interface;

    (void)TestRes;
    
    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create an instance of the HTTP server */
    server_obj = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);

    cy_resource_dynamic_data_t dynamic_sse_resource;
    dynamic_sse_resource.resource_handler = snip_mbed_process_SSE_handler;
    dynamic_sse_resource.arg = NULL;
    TestRes = server_obj->register_resource((uint8_t*) "/events", (uint8_t*)"text/event-stream", CY_RAW_DYNAMIC_URL_CONTENT, &dynamic_sse_resource);
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Register dynamic SSE resource completed */
    }
}

Code Snippet 6: HTTP server start

Starts an HTTP server using the start() API function.

#define HTTP_PORT         80
#define MAX_SOCKETS       2

/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

void snippet_mbed_http_server_start(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    NetworkInterface*      network;
    cy_network_interface_t nw_interface;
    HTTPServer*            server;

    (void)TestRes;
    
    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create an instance of the HTTP server */
    server = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);

    /* Register a static resource with then HTTP server */
    cy_resource_static_data_t static_resource;
    static_resource.data = CAPTIVE_PORTAL_REDIRECT_PAGE;
    static_resource.length = sizeof( CAPTIVE_PORTAL_REDIRECT_PAGE );
    TestRes = server->register_resource((uint8_t*) "/get", (uint8_t*)"text/html", CY_STATIC_URL_CONTENT, &static_resource);
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Start the HTTP server */
        TestRes = server->start();
    }
}

Code Snippet 7: Sending HTTP server events

Sends HTTP server events using the http_response_stream_write() API function.

#define SSE_PAYLOAD            "Hello, This is server sent events \r\n"
#define LFLF                   "\n\n"
#define EVENT_STREAM_DATA      "data: "

#define HTTP_PORT              80
#define MAX_SOCKETS            2
#define CHUNKED_CONTENT_LENGTH 0

HTTPServer                     *server_object;
cy_http_response_stream_t*     http_event_stream;

int32_t process_SSE_handler( const char* url_path, const char* url_parameters,
                                           cy_http_response_stream_t* stream, void* arg, 
                                           cy_http_message_body_t* http_message_body )
{
    http_event_stream = stream;
    server_object->http_response_stream_enable_chunked_transfer( http_event_stream );
    server_object->http_response_stream_write_header( http_event_stream, CY_HTTP_200_TYPE,
                                               CHUNKED_CONTENT_LENGTH, CY_HTTP_CACHE_DISABLED,
                                               MIME_TYPE_TEXT_EVENT_STREAM );
    return 0;
}

void send_events()
{
    cy_rslt_t result;
    if( http_event_stream == NULL )
    {
        return;
    }
    result = server_object->http_response_stream_write( http_event_stream, (const void*)EVENT_STREAM_DATA, sizeof( EVENT_STREAM_DATA ) - 1 );
    if ( result != CY_RSLT_SUCCESS )
    {
        http_event_stream = NULL;
        return;
    }
    /* Send the message to the client */
    result = server_object->http_response_stream_write( http_event_stream, SSE_PAYLOAD, sizeof(SSE_PAYLOAD) - 1);
    if ( result != CY_RSLT_SUCCESS )
    {
        http_event_stream = NULL;
        return;
    }
    /* SSE is ended with two line feeds */
    result = server_object->http_response_stream_write( http_event_stream, (const void*)LFLF, sizeof( LFLF ) - 1 );
    if ( result != CY_RSLT_SUCCESS )
    {
        http_event_stream = NULL;
        return;
    }
    return;
}

void snippet_mbed_http_server_send_events(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes        = CY_RSLT_ERROR;
    NetworkInterface*          network;
    cy_network_interface_t     nw_interface;

    (void)TestRes;
    
    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create an instance of the HTTP server */
    server_object = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);

    cy_resource_dynamic_data_t dynamic_sse_resource;
    dynamic_sse_resource.resource_handler = process_SSE_handler;
    dynamic_sse_resource.arg = NULL;
    TestRes = server_object->register_resource((uint8_t*) "/events", (uint8_t*)"text/event-stream", CY_RAW_DYNAMIC_URL_CONTENT, &dynamic_sse_resource);
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Start the HTTP server */
        TestRes = server->start();

        /* Send server events */
        if( http_event_stream != NULL )
        {
            send_events();
        }
    }
    /* Disconnect event stream */
    TestRes = server->http_response_stream_disconnect( http_event_stream );
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Disconnect given stream completed */
    }
    /* Disconnect all stream */
    TestRes = server->http_disconnect_all_response_stream();
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Disconnect all stream associated with server completed */
    }

}

Code Snippet 8: HTTP server stop

Stops an HTTP server using the stop() API function.

#define HTTP_PORT         80
#define MAX_SOCKETS       2

/* HTML page sent in response to the client */
#define CAPTIVE_PORTAL_REDIRECT_PAGE \
"<html><head>" \
"Hello, This is a reference HTTP server application" \
"</head></html>"

void snippet_mbed_http_server_stop(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    NetworkInterface*      network;
    cy_network_interface_t nw_interface;
    HTTPServer*            server;

    (void)TestRes;
    
    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create an instance of the HTTP server */
    server = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);

    /* Register a static resource with the HTTP server */
    cy_resource_static_data_t static_resource;
    static_resource.data = CAPTIVE_PORTAL_REDIRECT_PAGE;
    static_resource.length = sizeof( CAPTIVE_PORTAL_REDIRECT_PAGE );
    TestRes = server->register_resource((uint8_t*) "/get", (uint8_t*)"text/html", CY_STATIC_URL_CONTENT, &static_resource);
    if(TestRes == CY_RSLT_SUCCESS)
    {
        /* Start the HTTP server */
        TestRes = server->start();
        /* Stop HTTP server */
        TestRes = server->stop();
    }
}

Code Snippet 9: HTTP URL query

Search a key-value pair, fetch the value of a key, and get the number of queries from the given URL using URL-processing functions

void snippet_mbed_http_server_url_query(void)
{
    /* Status variables for various operations */
    cy_rslt_t TestRes = CY_RSLT_ERROR;
    NetworkInterface*      network;
    cy_network_interface_t nw_interface;
    HTTPServer*            server;
    const char url[] = "https://example.com/?product=shirt&color=blue&newuser&size=m\n";
    const char key[] = "product\n";
    const char value[] = "shirt\n";
    char *value_found = NULL;
    uint32_t value_length = 0;
    uint32_t query_param_count = 0;
    (void)TestRes;

    network = NetworkInterface::get_default_instance();
    network->connect();
    nw_interface.object = (void*) network;

    /* Create an instance of the HTTP server */
    server = new HTTPServer(&nw_interface, HTTP_PORT, MAX_SOCKETS);
    if( server != NULL )
    {
        /* Check if the provided key-value pair is present in the given URL */
        TestRes = server->http_match_query_parameter( url, key, value );
        if( TestRes != CY_RSLT_SUCCESS )
        {
            /* URL query failed */
        }

        /* Retrieve the value and the length of the value for a given key from the URL */
        TestRes = server->http_get_query_parameter_value( url, key, &value_found, &value_length );
        if( TestRes != CY_RSLT_SUCCESS )
        {
            /* URL query failed */
        }

        /* Get number of query parameters found in the URL query string */
        TestRes = server->http_get_query_parameter_count( url, &query_param_count );
        if( TestRes != CY_RSLT_SUCCESS )
        {
            /* URL query failed */
        }
    }
}