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:
Fri Jan 04 13:27:32 2019 +0100
Revision:
34:6daf67a96a91
Add integration tests

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jan Jongboom 34:6daf67a96a91 1 /*
Jan Jongboom 34:6daf67a96a91 2 * PackageLicenseDeclared: Apache-2.0
Jan Jongboom 34:6daf67a96a91 3 * Copyright (c) 2018 ARM Limited
Jan Jongboom 34:6daf67a96a91 4 *
Jan Jongboom 34:6daf67a96a91 5 * Licensed under the Apache License, Version 2.0 (the "License");
Jan Jongboom 34:6daf67a96a91 6 * you may not use this file except in compliance with the License.
Jan Jongboom 34:6daf67a96a91 7 * You may obtain a copy of the License at
Jan Jongboom 34:6daf67a96a91 8 *
Jan Jongboom 34:6daf67a96a91 9 * http://www.apache.org/licenses/LICENSE-2.0
Jan Jongboom 34:6daf67a96a91 10 *
Jan Jongboom 34:6daf67a96a91 11 * Unless required by applicable law or agreed to in writing, software
Jan Jongboom 34:6daf67a96a91 12 * distributed under the License is distributed on an "AS IS" BASIS,
Jan Jongboom 34:6daf67a96a91 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Jan Jongboom 34:6daf67a96a91 14 * See the License for the specific language governing permissions and
Jan Jongboom 34:6daf67a96a91 15 * limitations under the License.
Jan Jongboom 34:6daf67a96a91 16 */
Jan Jongboom 34:6daf67a96a91 17
Jan Jongboom 34:6daf67a96a91 18 #include "mbed.h"
Jan Jongboom 34:6daf67a96a91 19 #include "http_request.h"
Jan Jongboom 34:6daf67a96a91 20 #include "https_request.h"
Jan Jongboom 34:6daf67a96a91 21 #include "test_setup.h"
Jan Jongboom 34:6daf67a96a91 22 #include "utest/utest.h"
Jan Jongboom 34:6daf67a96a91 23 #include "unity/unity.h"
Jan Jongboom 34:6daf67a96a91 24 #include "greentea-client/test_env.h"
Jan Jongboom 34:6daf67a96a91 25
Jan Jongboom 34:6daf67a96a91 26 using namespace utest::v1;
Jan Jongboom 34:6daf67a96a91 27
Jan Jongboom 34:6daf67a96a91 28 static NetworkInterface *network;
Jan Jongboom 34:6daf67a96a91 29
Jan Jongboom 34:6daf67a96a91 30 static void setup_verify_network() {
Jan Jongboom 34:6daf67a96a91 31 if (!network) network = connect_to_default_network_interface();
Jan Jongboom 34:6daf67a96a91 32 TEST_ASSERT_NOT_NULL(network);
Jan Jongboom 34:6daf67a96a91 33 }
Jan Jongboom 34:6daf67a96a91 34
Jan Jongboom 34:6daf67a96a91 35 // verifies that the header is present and has a certain value
Jan Jongboom 34:6daf67a96a91 36 static void assert_header(HttpResponse *res, const char *header, const char *value) {
Jan Jongboom 34:6daf67a96a91 37 bool headerPresent = false;
Jan Jongboom 34:6daf67a96a91 38 for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
Jan Jongboom 34:6daf67a96a91 39 if (res->get_headers_fields()[ix]->compare(header)) {
Jan Jongboom 34:6daf67a96a91 40 headerPresent = true;
Jan Jongboom 34:6daf67a96a91 41
Jan Jongboom 34:6daf67a96a91 42 TEST_ASSERT(res->get_headers_values()[ix]->compare(value));
Jan Jongboom 34:6daf67a96a91 43 }
Jan Jongboom 34:6daf67a96a91 44 }
Jan Jongboom 34:6daf67a96a91 45 TEST_ASSERT_EQUAL(true, headerPresent);
Jan Jongboom 34:6daf67a96a91 46 }
Jan Jongboom 34:6daf67a96a91 47
Jan Jongboom 34:6daf67a96a91 48 static control_t http_get(const size_t call_count) {
Jan Jongboom 34:6daf67a96a91 49 setup_verify_network();
Jan Jongboom 34:6daf67a96a91 50
Jan Jongboom 34:6daf67a96a91 51 HttpRequest *req = new HttpRequest(network, HTTP_GET, "http://httpbin.org/status/418");
Jan Jongboom 34:6daf67a96a91 52
Jan Jongboom 34:6daf67a96a91 53 HttpResponse* res = req->send();
Jan Jongboom 34:6daf67a96a91 54 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 55 TEST_ASSERT_EQUAL(418, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 56
Jan Jongboom 34:6daf67a96a91 57 delete req;
Jan Jongboom 34:6daf67a96a91 58
Jan Jongboom 34:6daf67a96a91 59 return CaseNext;
Jan Jongboom 34:6daf67a96a91 60 }
Jan Jongboom 34:6daf67a96a91 61
Jan Jongboom 34:6daf67a96a91 62 static control_t http_post(const size_t call_count) {
Jan Jongboom 34:6daf67a96a91 63 setup_verify_network();
Jan Jongboom 34:6daf67a96a91 64
Jan Jongboom 34:6daf67a96a91 65 HttpRequest* req = new HttpRequest(network, HTTP_POST, "http://httpbin.org/post");
Jan Jongboom 34:6daf67a96a91 66 req->set_header("Content-Type", "application/json");
Jan Jongboom 34:6daf67a96a91 67
Jan Jongboom 34:6daf67a96a91 68 const char body[] = "{\"mykey\":\"mbedvalue\"}";
Jan Jongboom 34:6daf67a96a91 69
Jan Jongboom 34:6daf67a96a91 70 HttpResponse* res = req->send(body, strlen(body));
Jan Jongboom 34:6daf67a96a91 71 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 72 TEST_ASSERT_EQUAL(200, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 73
Jan Jongboom 34:6daf67a96a91 74 // verify that the Content-Type header is present, and set to application/json
Jan Jongboom 34:6daf67a96a91 75 assert_header(res, "Content-Type", "application/json");
Jan Jongboom 34:6daf67a96a91 76
Jan Jongboom 34:6daf67a96a91 77 // verify that both the key and value are present in the response
Jan Jongboom 34:6daf67a96a91 78 TEST_ASSERT(res->get_body_length() > 0);
Jan Jongboom 34:6daf67a96a91 79 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("mykey"), string::npos);
Jan Jongboom 34:6daf67a96a91 80 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("mbedvalue"), string::npos);
Jan Jongboom 34:6daf67a96a91 81
Jan Jongboom 34:6daf67a96a91 82 delete req;
Jan Jongboom 34:6daf67a96a91 83
Jan Jongboom 34:6daf67a96a91 84 return CaseNext;
Jan Jongboom 34:6daf67a96a91 85 }
Jan Jongboom 34:6daf67a96a91 86
Jan Jongboom 34:6daf67a96a91 87 static control_t http_socket_reuse(const size_t call_count) {
Jan Jongboom 34:6daf67a96a91 88 setup_verify_network();
Jan Jongboom 34:6daf67a96a91 89
Jan Jongboom 34:6daf67a96a91 90 TCPSocket socket;
Jan Jongboom 34:6daf67a96a91 91 nsapi_error_t open_result = socket.open(network);
Jan Jongboom 34:6daf67a96a91 92 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, open_result);
Jan Jongboom 34:6daf67a96a91 93
Jan Jongboom 34:6daf67a96a91 94 nsapi_error_t connect_result = socket.connect("httpbin.org", 80);
Jan Jongboom 34:6daf67a96a91 95 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, connect_result);
Jan Jongboom 34:6daf67a96a91 96
Jan Jongboom 34:6daf67a96a91 97 {
Jan Jongboom 34:6daf67a96a91 98 HttpRequest *req = new HttpRequest(&socket, HTTP_GET, "http://httpbin.org/status/404");
Jan Jongboom 34:6daf67a96a91 99
Jan Jongboom 34:6daf67a96a91 100 HttpResponse* res = req->send();
Jan Jongboom 34:6daf67a96a91 101 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 102 TEST_ASSERT_EQUAL(404, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 103
Jan Jongboom 34:6daf67a96a91 104 delete req;
Jan Jongboom 34:6daf67a96a91 105 }
Jan Jongboom 34:6daf67a96a91 106
Jan Jongboom 34:6daf67a96a91 107 {
Jan Jongboom 34:6daf67a96a91 108 HttpRequest *req = new HttpRequest(&socket, HTTP_GET, "http://httpbin.org/status/403");
Jan Jongboom 34:6daf67a96a91 109
Jan Jongboom 34:6daf67a96a91 110 HttpResponse* res = req->send();
Jan Jongboom 34:6daf67a96a91 111 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 112 TEST_ASSERT_EQUAL(403, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 113
Jan Jongboom 34:6daf67a96a91 114 delete req;
Jan Jongboom 34:6daf67a96a91 115 }
Jan Jongboom 34:6daf67a96a91 116
Jan Jongboom 34:6daf67a96a91 117 return CaseNext;
Jan Jongboom 34:6daf67a96a91 118 }
Jan Jongboom 34:6daf67a96a91 119
Jan Jongboom 34:6daf67a96a91 120 static control_t https_get(const size_t call_count) {
Jan Jongboom 34:6daf67a96a91 121 setup_verify_network();
Jan Jongboom 34:6daf67a96a91 122
Jan Jongboom 34:6daf67a96a91 123 HttpsRequest *req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt");
Jan Jongboom 34:6daf67a96a91 124
Jan Jongboom 34:6daf67a96a91 125 HttpResponse* res = req->send();
Jan Jongboom 34:6daf67a96a91 126 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 127 TEST_ASSERT_EQUAL(200, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 128 TEST_ASSERT(res->get_body_length() > 0);
Jan Jongboom 34:6daf67a96a91 129 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("Hello world!"), string::npos);
Jan Jongboom 34:6daf67a96a91 130
Jan Jongboom 34:6daf67a96a91 131 delete req;
Jan Jongboom 34:6daf67a96a91 132
Jan Jongboom 34:6daf67a96a91 133 return CaseNext;
Jan Jongboom 34:6daf67a96a91 134 }
Jan Jongboom 34:6daf67a96a91 135
Jan Jongboom 34:6daf67a96a91 136 static control_t https_post(const size_t call_count) {
Jan Jongboom 34:6daf67a96a91 137 setup_verify_network();
Jan Jongboom 34:6daf67a96a91 138
Jan Jongboom 34:6daf67a96a91 139 HttpsRequest* req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://httpbin.org/post");
Jan Jongboom 34:6daf67a96a91 140 req->set_header("Content-Type", "application/json");
Jan Jongboom 34:6daf67a96a91 141
Jan Jongboom 34:6daf67a96a91 142 const char body[] = "{\"myhttpskey\":\"janjanjan\"}";
Jan Jongboom 34:6daf67a96a91 143
Jan Jongboom 34:6daf67a96a91 144 HttpResponse* res = req->send(body, strlen(body));
Jan Jongboom 34:6daf67a96a91 145 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 146 TEST_ASSERT_EQUAL(200, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 147
Jan Jongboom 34:6daf67a96a91 148 // verify that the Content-Type header is present, and set to application/json
Jan Jongboom 34:6daf67a96a91 149 assert_header(res, "Content-Type", "application/json");
Jan Jongboom 34:6daf67a96a91 150
Jan Jongboom 34:6daf67a96a91 151 // verify that both the key and value are present in the response
Jan Jongboom 34:6daf67a96a91 152 TEST_ASSERT(res->get_body_length() > 0);
Jan Jongboom 34:6daf67a96a91 153 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("myhttpskey"), string::npos);
Jan Jongboom 34:6daf67a96a91 154 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("janjanjan"), string::npos);
Jan Jongboom 34:6daf67a96a91 155
Jan Jongboom 34:6daf67a96a91 156 delete req;
Jan Jongboom 34:6daf67a96a91 157
Jan Jongboom 34:6daf67a96a91 158 return CaseNext;
Jan Jongboom 34:6daf67a96a91 159 }
Jan Jongboom 34:6daf67a96a91 160
Jan Jongboom 34:6daf67a96a91 161 static control_t https_socket_reuse(const size_t call_count) {
Jan Jongboom 34:6daf67a96a91 162 setup_verify_network();
Jan Jongboom 34:6daf67a96a91 163
Jan Jongboom 34:6daf67a96a91 164 TLSSocket socket;
Jan Jongboom 34:6daf67a96a91 165 nsapi_error_t open_result = socket.open(network);
Jan Jongboom 34:6daf67a96a91 166 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, open_result);
Jan Jongboom 34:6daf67a96a91 167
Jan Jongboom 34:6daf67a96a91 168 nsapi_error_t ca_result = socket.set_root_ca_cert(SSL_CA_PEM);
Jan Jongboom 34:6daf67a96a91 169 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, ca_result);
Jan Jongboom 34:6daf67a96a91 170
Jan Jongboom 34:6daf67a96a91 171 nsapi_error_t connect_result = socket.connect("httpbin.org", 443);
Jan Jongboom 34:6daf67a96a91 172 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, connect_result);
Jan Jongboom 34:6daf67a96a91 173
Jan Jongboom 34:6daf67a96a91 174 {
Jan Jongboom 34:6daf67a96a91 175 HttpsRequest *req = new HttpsRequest(&socket, HTTP_GET, "http://httpbin.org/status/404");
Jan Jongboom 34:6daf67a96a91 176
Jan Jongboom 34:6daf67a96a91 177 HttpResponse* res = req->send();
Jan Jongboom 34:6daf67a96a91 178 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 179 TEST_ASSERT_EQUAL(404, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 180
Jan Jongboom 34:6daf67a96a91 181 delete req;
Jan Jongboom 34:6daf67a96a91 182 }
Jan Jongboom 34:6daf67a96a91 183
Jan Jongboom 34:6daf67a96a91 184 {
Jan Jongboom 34:6daf67a96a91 185 HttpsRequest *req = new HttpsRequest(&socket, HTTP_GET, "http://httpbin.org/status/403");
Jan Jongboom 34:6daf67a96a91 186
Jan Jongboom 34:6daf67a96a91 187 HttpResponse* res = req->send();
Jan Jongboom 34:6daf67a96a91 188 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 189 TEST_ASSERT_EQUAL(403, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 190
Jan Jongboom 34:6daf67a96a91 191 delete req;
Jan Jongboom 34:6daf67a96a91 192 }
Jan Jongboom 34:6daf67a96a91 193
Jan Jongboom 34:6daf67a96a91 194 return CaseNext;
Jan Jongboom 34:6daf67a96a91 195 }
Jan Jongboom 34:6daf67a96a91 196
Jan Jongboom 34:6daf67a96a91 197 // Spread the message out over 3 different chunks
Jan Jongboom 34:6daf67a96a91 198 const char * chunks[] = {
Jan Jongboom 34:6daf67a96a91 199 "{\"message\":",
Jan Jongboom 34:6daf67a96a91 200 "\"this is an example",
Jan Jongboom 34:6daf67a96a91 201 " of chunked encoding\"}"
Jan Jongboom 34:6daf67a96a91 202 };
Jan Jongboom 34:6daf67a96a91 203
Jan Jongboom 34:6daf67a96a91 204 int chunk_ix = 0;
Jan Jongboom 34:6daf67a96a91 205
Jan Jongboom 34:6daf67a96a91 206 // Callback function, grab the next chunk and return it
Jan Jongboom 34:6daf67a96a91 207 const void * get_chunk(uint32_t* out_size) {
Jan Jongboom 34:6daf67a96a91 208 // If you don't have any data left, set out_size to 0 and return a null pointer
Jan Jongboom 34:6daf67a96a91 209 if (chunk_ix == (sizeof(chunks) / sizeof(chunks[0]))) {
Jan Jongboom 34:6daf67a96a91 210 *out_size = 0;
Jan Jongboom 34:6daf67a96a91 211 return NULL;
Jan Jongboom 34:6daf67a96a91 212 }
Jan Jongboom 34:6daf67a96a91 213 const char *chunk = chunks[chunk_ix];
Jan Jongboom 34:6daf67a96a91 214 *out_size = strlen(chunk);
Jan Jongboom 34:6daf67a96a91 215 chunk_ix++;
Jan Jongboom 34:6daf67a96a91 216
Jan Jongboom 34:6daf67a96a91 217 return chunk;
Jan Jongboom 34:6daf67a96a91 218 }
Jan Jongboom 34:6daf67a96a91 219
Jan Jongboom 34:6daf67a96a91 220 static control_t chunked_request(const size_t call_count) {
Jan Jongboom 34:6daf67a96a91 221 setup_verify_network();
Jan Jongboom 34:6daf67a96a91 222
Jan Jongboom 34:6daf67a96a91 223 HttpsRequest *req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://reqres.in/api/users");
Jan Jongboom 34:6daf67a96a91 224 req->set_header("Content-Type", "application/json");
Jan Jongboom 34:6daf67a96a91 225
Jan Jongboom 34:6daf67a96a91 226 HttpResponse* res = req->send(&get_chunk);
Jan Jongboom 34:6daf67a96a91 227 TEST_ASSERT(res);
Jan Jongboom 34:6daf67a96a91 228 TEST_ASSERT_EQUAL(201, res->get_status_code());
Jan Jongboom 34:6daf67a96a91 229 TEST_ASSERT(res->get_body_length() > 0);
Jan Jongboom 34:6daf67a96a91 230 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("message"), string::npos);
Jan Jongboom 34:6daf67a96a91 231 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("this is an example of chunked encoding"), string::npos);
Jan Jongboom 34:6daf67a96a91 232 TEST_ASSERT_NOT_EQUAL(res->get_body_as_string().find("createdAt"), string::npos);
Jan Jongboom 34:6daf67a96a91 233
Jan Jongboom 34:6daf67a96a91 234 delete req;
Jan Jongboom 34:6daf67a96a91 235
Jan Jongboom 34:6daf67a96a91 236 return CaseNext;
Jan Jongboom 34:6daf67a96a91 237 }
Jan Jongboom 34:6daf67a96a91 238
Jan Jongboom 34:6daf67a96a91 239 utest::v1::status_t greentea_setup(const size_t number_of_cases) {
Jan Jongboom 34:6daf67a96a91 240 GREENTEA_SETUP(1*60, "default_auto");
Jan Jongboom 34:6daf67a96a91 241 return greentea_test_setup_handler(number_of_cases);
Jan Jongboom 34:6daf67a96a91 242 }
Jan Jongboom 34:6daf67a96a91 243
Jan Jongboom 34:6daf67a96a91 244 Case cases[] = {
Jan Jongboom 34:6daf67a96a91 245 Case("http get", http_get),
Jan Jongboom 34:6daf67a96a91 246 Case("http post", http_post),
Jan Jongboom 34:6daf67a96a91 247 Case("http socket reuse", http_socket_reuse),
Jan Jongboom 34:6daf67a96a91 248 Case("https get", https_get),
Jan Jongboom 34:6daf67a96a91 249 Case("https post", https_post),
Jan Jongboom 34:6daf67a96a91 250 Case("https socket reuse", https_socket_reuse),
Jan Jongboom 34:6daf67a96a91 251 Case("chunked request", chunked_request)
Jan Jongboom 34:6daf67a96a91 252 };
Jan Jongboom 34:6daf67a96a91 253
Jan Jongboom 34:6daf67a96a91 254 Specification specification(greentea_setup, cases);
Jan Jongboom 34:6daf67a96a91 255
Jan Jongboom 34:6daf67a96a91 256 void blink_led() {
Jan Jongboom 34:6daf67a96a91 257 static DigitalOut led(LED1);
Jan Jongboom 34:6daf67a96a91 258 led = !led;
Jan Jongboom 34:6daf67a96a91 259 }
Jan Jongboom 34:6daf67a96a91 260
Jan Jongboom 34:6daf67a96a91 261 int main() {
Jan Jongboom 34:6daf67a96a91 262 Ticker t;
Jan Jongboom 34:6daf67a96a91 263 t.attach(blink_led, 0.5);
Jan Jongboom 34:6daf67a96a91 264
Jan Jongboom 34:6daf67a96a91 265 return !Harness::run(specification);
Jan Jongboom 34:6daf67a96a91 266 }