HTTP and HTTPS library for Mbed OS 5

Dependents:   MQTTGateway2 MQTTGatewayK64 http-example-wnc GuardRoom ... more

For the example program, see: sandbox/http-example.

This library is used to make HTTP and HTTPS calls from Mbed OS 5 applications.

HTTP Request API

NetworkInterface* network = /* obtain a NetworkInterface object */

const char body[] = "{\"hello\":\"world\"}";

HttpRequest* request = new HttpRequest(network, HTTP_POST, "http://httpbin.org/post");
request->set_header("Content-Type", "application/json");
HttpResponse* response = request->send(body, strlen(body));
// if response is NULL, check response->get_error()

printf("status is %d - %s\n", response->get_status_code(), response->get_status_message());
printf("body is:\n%s\n", response->get_body_as_string().c_str());

delete request; // also clears out the response

HTTPS Request API

// pass in the root certificates that you trust, there is no central CA registry in Mbed OS
const char SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n"
    /* rest of the CA root certificates */;

NetworkInterface* network = /* obtain a NetworkInterface object */

const char body[] = "{\"hello\":\"world\"}";

HttpsRequest* request = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET "https://httpbin.org/status/418");
HttpResponse* response = request->send();
// if response is NULL, check response->get_error()

printf("status is %d - %s\n", response->get_status_code(), response->get_status_message());
printf("body is:\n%s\n", response->get_body().c_str());

delete request;

Note: You can get the root CA for a domain easily from Firefox. Click on the green padlock, click More information > Security > View certificate > Details. Select the top entry in the 'Certificate Hierarchy' and click Export.... This gives you a PEM file. Add the content of the PEM file to your root CA list (here's an image).

Mbed TLS Entropy configuration

If your target does not have a built-in TRNG, or other entropy sources, add the following macros to your mbed_app.json file to disable entropy:

{
    "macros": [
        "MBEDTLS_TEST_NULL_ENTROPY",
        "MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES"
    ]
}

Note that this is not secure, and you should not deploy this device into production with this configuration.

Memory usage

Small requests where the body of the response is cached by the library (like the one found in main-http.cpp), require 4K of RAM. When the request is finished they require 1.5K of RAM, depending on the size of the response. This applies both to HTTP and HTTPS. If you need to handle requests that return a large response body, see 'Dealing with large body'.

HTTPS requires additional memory: on FRDM-K64F about 50K of heap space (at its peak). This means that you cannot use HTTPS on devices with less than 128K of memory, asyou also need to reserve memory for the stack and network interface.

Dealing with large response body

By default the library will store the full request body on the heap. This works well for small responses, but you'll run out of memory when receiving a large response body. To mitigate this you can pass in a callback as the last argument to the request constructor. This callback will be called whenever a chunk of the body is received. You can set the request chunk size in the HTTP_RECEIVE_BUFFER_SIZE macro (see mbed_lib.json for the definition) although it also depends on the buffer size ofthe underlying network connection.

void body_callback(const char* data, uint32_t data_len) {
    // do something with the data
}

HttpRequest* req = new HttpRequest(network, HTTP_GET, "http://pathtolargefile.com", &body_callback);
req->send(NULL, 0);

Dealing with a large request body

If you cannot load the full request into memory, you can pass a callback into the send function. Through this callback you can feed in chunks of the request body. This is very useful if you want to send files from a file system.

const void * get_chunk(uint32_t* out_size) {
    // set the value of out_size (via *out_size = 10) to the size of the buffer
    // return the buffer

    // if you don't have any more data, set *out_size to 0
}

HttpRequest* req = new HttpRequest(network, HTTP_POST, "http://my_api.com/upload");
req->send(callback(&get_chunk));

Socket re-use

By default the library opens a new socket per request. This is wasteful, especially when dealing with TLS requests. You can re-use sockets like this:

HTTP

TCPSocket* socket = new TCPSocket();

nsapi_error_t open_result = socket->open(network);
// check open_result

nsapi_error_t connect_result = socket->connect("httpbin.org", 80);
// check connect_result

// Pass in `socket`, instead of `network` as first argument
HttpRequest* req = new HttpRequest(socket, HTTP_GET, "http://httpbin.org/status/418");

HTTPS

TLSSocket* socket = new TLSSocket();

nsapi_error_t r;
// make sure to check the return values for the calls below (should return NSAPI_ERROR_OK)
r = socket->open(network);
r = socket->set_root_ca_cert(SSL_CA_PEM);
r = socket->connect("httpbin.org", 443);

// Pass in `socket`, instead of `network` as first argument, and omit the `SSL_CA_PEM` argument
HttpsRequest* get_req = new HttpsRequest(socket, HTTP_GET, "https://httpbin.org/status/418");

Request logging

To make debugging easier you can log the raw request body that goes over the line. This also works with chunked encoding.

uint8_t *request_buffer = (uint8_t*)calloc(2048, 1);
req->set_request_log_buffer(request_buffer, 2048);

// after the request is done:
printf("\n----- Request buffer -----\n");
for (size_t ix = 0; ix < req->get_request_log_buffer_length(); ix++) {
    printf("%02x ", request_buffer[ix]);
}
printf("\n");

Integration tests

Integration tests are located in the TESTS folder and are ran through Greentea. Instructions on how to run the tests are in http-example.

Mbed OS 5.10 or lower

If you want to use this library on Mbed OS 5.10 or lower, you need to add the TLSSocket library to your project. This library is included in Mbed OS 5.11 and up.

Tested on

  • K64F with Ethernet.
  • NUCLEO_F411RE with ESP8266.
  • ODIN-W2 with WiFi.
  • K64F with Atmel 6LoWPAN shield.
  • DISCO-L475VG-IOT01A with WiFi.
  • Mbed Simulator.
Committer:
Jan Jongboom
Date:
Mon Aug 12 11:45:31 2019 +0200
Revision:
39:a8d157986ad8
Parent:
34:6daf67a96a91
Fix parsed url leaking memory if path is empty

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jan Jongboom 34:6daf67a96a91 1 #ifndef _MBED_HTTP_TEST_SETUP_H_
Jan Jongboom 34:6daf67a96a91 2 #define _MBED_HTTP_TEST_SETUP_H_
Jan Jongboom 34:6daf67a96a91 3
Jan Jongboom 34:6daf67a96a91 4 #include "mbed.h"
Jan Jongboom 34:6daf67a96a91 5 #include "NetworkInterface.h"
Jan Jongboom 34:6daf67a96a91 6
Jan Jongboom 34:6daf67a96a91 7 /**
Jan Jongboom 34:6daf67a96a91 8 * Connect to the network using the default networking interface,
Jan Jongboom 34:6daf67a96a91 9 * you can also swap this out with a driver for a different networking interface
Jan Jongboom 34:6daf67a96a91 10 * if you use WiFi: see mbed_app.json for the credentials
Jan Jongboom 34:6daf67a96a91 11 */
Jan Jongboom 34:6daf67a96a91 12 NetworkInterface *connect_to_default_network_interface() {
Jan Jongboom 34:6daf67a96a91 13 NetworkInterface* network = NetworkInterface::get_default_instance();
Jan Jongboom 34:6daf67a96a91 14
Jan Jongboom 34:6daf67a96a91 15 if (!network) {
Jan Jongboom 34:6daf67a96a91 16 return NULL;
Jan Jongboom 34:6daf67a96a91 17 }
Jan Jongboom 34:6daf67a96a91 18
Jan Jongboom 34:6daf67a96a91 19 nsapi_error_t connect_status = network->connect();
Jan Jongboom 34:6daf67a96a91 20
Jan Jongboom 34:6daf67a96a91 21 if (connect_status != NSAPI_ERROR_OK) {
Jan Jongboom 34:6daf67a96a91 22 return NULL;
Jan Jongboom 34:6daf67a96a91 23 }
Jan Jongboom 34:6daf67a96a91 24
Jan Jongboom 34:6daf67a96a91 25 return network;
Jan Jongboom 34:6daf67a96a91 26 }
Jan Jongboom 34:6daf67a96a91 27
Jan Jongboom 34:6daf67a96a91 28
Jan Jongboom 34:6daf67a96a91 29 /* List of trusted root CA certificates
Jan Jongboom 34:6daf67a96a91 30 *
Jan Jongboom 34:6daf67a96a91 31 * - Amazon, the CA for os.mbed.com
Jan Jongboom 34:6daf67a96a91 32 * - Let's Encrypt, the CA for httpbin.org
Jan Jongboom 34:6daf67a96a91 33 * - Comodo, the CA for reqres.in
Jan Jongboom 34:6daf67a96a91 34 *
Jan Jongboom 34:6daf67a96a91 35 * To add more root certificates, just concatenate them.
Jan Jongboom 34:6daf67a96a91 36 */
Jan Jongboom 34:6daf67a96a91 37 const char SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n"
Jan Jongboom 34:6daf67a96a91 38 "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n"
Jan Jongboom 34:6daf67a96a91 39 "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n"
Jan Jongboom 34:6daf67a96a91 40 "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n"
Jan Jongboom 34:6daf67a96a91 41 "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n"
Jan Jongboom 34:6daf67a96a91 42 "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n"
Jan Jongboom 34:6daf67a96a91 43 "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n"
Jan Jongboom 34:6daf67a96a91 44 "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n"
Jan Jongboom 34:6daf67a96a91 45 "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n"
Jan Jongboom 34:6daf67a96a91 46 "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n"
Jan Jongboom 34:6daf67a96a91 47 "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n"
Jan Jongboom 34:6daf67a96a91 48 "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
Jan Jongboom 34:6daf67a96a91 49 "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n"
Jan Jongboom 34:6daf67a96a91 50 "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n"
Jan Jongboom 34:6daf67a96a91 51 "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n"
Jan Jongboom 34:6daf67a96a91 52 "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n"
Jan Jongboom 34:6daf67a96a91 53 "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n"
Jan Jongboom 34:6daf67a96a91 54 "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n"
Jan Jongboom 34:6daf67a96a91 55 "rqXRfboQnoZsG4q5WTP468SQvvG5\n"
Jan Jongboom 34:6daf67a96a91 56 "-----END CERTIFICATE-----\n"
Jan Jongboom 34:6daf67a96a91 57 "-----BEGIN CERTIFICATE-----\n"
Jan Jongboom 34:6daf67a96a91 58 "MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n"
Jan Jongboom 34:6daf67a96a91 59 "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"
Jan Jongboom 34:6daf67a96a91 60 "DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n"
Jan Jongboom 34:6daf67a96a91 61 "SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n"
Jan Jongboom 34:6daf67a96a91 62 "GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n"
Jan Jongboom 34:6daf67a96a91 63 "AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n"
Jan Jongboom 34:6daf67a96a91 64 "q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n"
Jan Jongboom 34:6daf67a96a91 65 "SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n"
Jan Jongboom 34:6daf67a96a91 66 "Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n"
Jan Jongboom 34:6daf67a96a91 67 "a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n"
Jan Jongboom 34:6daf67a96a91 68 "/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n"
Jan Jongboom 34:6daf67a96a91 69 "AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n"
Jan Jongboom 34:6daf67a96a91 70 "CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n"
Jan Jongboom 34:6daf67a96a91 71 "bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n"
Jan Jongboom 34:6daf67a96a91 72 "c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n"
Jan Jongboom 34:6daf67a96a91 73 "VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n"
Jan Jongboom 34:6daf67a96a91 74 "ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n"
Jan Jongboom 34:6daf67a96a91 75 "MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n"
Jan Jongboom 34:6daf67a96a91 76 "Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n"
Jan Jongboom 34:6daf67a96a91 77 "AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n"
Jan Jongboom 34:6daf67a96a91 78 "uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n"
Jan Jongboom 34:6daf67a96a91 79 "wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n"
Jan Jongboom 34:6daf67a96a91 80 "X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n"
Jan Jongboom 34:6daf67a96a91 81 "PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n"
Jan Jongboom 34:6daf67a96a91 82 "KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n"
Jan Jongboom 34:6daf67a96a91 83 "-----END CERTIFICATE-----\n"
Jan Jongboom 34:6daf67a96a91 84 "-----BEGIN CERTIFICATE-----\n"
Jan Jongboom 34:6daf67a96a91 85 "MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL\n"
Jan Jongboom 34:6daf67a96a91 86 "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n"
Jan Jongboom 34:6daf67a96a91 87 "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT\n"
Jan Jongboom 34:6daf67a96a91 88 "IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw\n"
Jan Jongboom 34:6daf67a96a91 89 "MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy\n"
Jan Jongboom 34:6daf67a96a91 90 "ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N\n"
Jan Jongboom 34:6daf67a96a91 91 "T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv\n"
Jan Jongboom 34:6daf67a96a91 92 "biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR\n"
Jan Jongboom 34:6daf67a96a91 93 "FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J\n"
Jan Jongboom 34:6daf67a96a91 94 "cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW\n"
Jan Jongboom 34:6daf67a96a91 95 "BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\n"
Jan Jongboom 34:6daf67a96a91 96 "BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm\n"
Jan Jongboom 34:6daf67a96a91 97 "fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv\n"
Jan Jongboom 34:6daf67a96a91 98 "GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=\n"
Jan Jongboom 34:6daf67a96a91 99 "-----END CERTIFICATE-----\n";
Jan Jongboom 34:6daf67a96a91 100
Jan Jongboom 34:6daf67a96a91 101 #endif // MBED_HTTP_TEST_SETUP_H_