9 // #include "protocol_examples_common.h"
10 // #include "protocol_examples_utils.h"
12 #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
13 #include "esp_crt_bundle.h"
16 #if !CONFIG_IDF_TARGET_LINUX
17 #include "freertos/FreeRTOS.h"
18 #include "freertos/task.h"
19 #include "esp_system.h"
22 #include "esp_http_client.h"
24 /* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem
26 The PEM file was extracted from the output of this command:
27 openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null
29 The CA root cert is the last cert given in the chain of certs.
31 To embed it in the app binary, the PEM file is named
32 in the component.mk COMPONENT_EMBED_TXTFILES variable.
34 // extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");
35 // extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com_root_cert_pem_end");
37 // extern const char postman_root_cert_pem_start[] asm("_binary_postman_root_cert_pem_start");
38 // extern const char postman_root_cert_pem_end[] asm("_binary_postman_root_cert_pem_end");
42 #define HTTP_CONNECTION_DATA_SIZE 1024*64
43 #define AUTHORIZATION_HEADER_LEN 64
45 struct MatrixHttpConnection {
46 esp_http_client_handle_t client;
49 const char * accessToken;
51 // char data[HTTP_CONNECTION_DATA_SIZE];
58 static const char *TAG = "HTTP_CLIENT";
60 esp_err_t _http_event_handler(esp_http_client_event_t *evt)
62 vTaskDelay(10/portTICK_PERIOD_MS);
64 MatrixHttpConnection * hc = (MatrixHttpConnection *)evt->user_data;
65 switch(evt->event_id) {
66 case HTTP_EVENT_ERROR:
67 ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
69 case HTTP_EVENT_ON_CONNECTED:
70 ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
72 case HTTP_EVENT_HEADER_SENT:
73 ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
75 case HTTP_EVENT_ON_HEADER:
76 ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
78 case HTTP_EVENT_ON_DATA:
79 ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
81 * Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
82 * However, event handler can also be used in case chunked encoding is used.
84 if (!esp_http_client_is_chunked_response(evt->client)) {
85 ESP_LOGD(TAG, "Non-Chunked Encoding");
88 ESP_LOGD(TAG, "Chunked Encoding");
93 // const int64_t buffer_len = esp_http_client_get_content_length(evt->client);
94 // if (buffer_len < hc->dataCap) {
95 // ESP_LOGE(TAG, "Output buffer too small: %" PRIu64 ", data_len: %d", buffer_len, evt->data_len);
98 copy_len = MIN(evt->data_len, (hc->dataCap - hc->dataLen));
100 memcpy(hc->data + hc->dataLen, evt->data, copy_len);
101 hc->data[hc->dataLen + copy_len] = '\0';
104 hc->dataLen += copy_len;
107 case HTTP_EVENT_ON_FINISH:
108 ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
110 case HTTP_EVENT_DISCONNECTED:
111 ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
113 esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
115 ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
116 ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
119 case HTTP_EVENT_REDIRECT:
120 ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
121 // esp_http_client_set_header(evt->client, "From", "user@example.com");
122 // esp_http_client_set_header(evt->client, "Accept", "text/html");
123 // esp_http_client_set_redirection(evt->client);
131 MatrixHttpConnection * hc)
133 esp_http_client_config_t config = {
136 .event_handler = _http_event_handler,
138 .disable_auto_redirect = true,
139 .crt_bundle_attach = esp_crt_bundle_attach,
142 hc->client = esp_http_client_init(&config);
144 esp_http_client_set_timeout_ms(hc->client, 10000);
148 MatrixHttpDisconnect(
149 MatrixHttpConnection * hc)
151 esp_http_client_cleanup(hc->client);
157 MatrixHttpConnection ** hc,
160 *hc = (MatrixHttpConnection *)calloc(1, sizeof(MatrixHttpConnection));
165 MatrixHttpConnect(*hc);
172 MatrixHttpConnection ** hc)
174 MatrixHttpDisconnect(*hc);
183 MatrixHttpSetAccessToken(
184 MatrixHttpConnection * hc,
185 const char * accessToken)
187 hc->accessToken = accessToken;
194 MatrixHttpConnection * hc,
196 char * outResponseBuffer, int outResponseCap,
199 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
201 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
202 "Bearer %s", hc->accessToken);
204 authorizationHeader[0] = '\0';
206 printf("GET %s%s\n", hc->host, url);
208 hc->data = outResponseBuffer;
209 hc->dataCap = outResponseCap;
212 static char hostAndUrl[MAX_URL_LEN];
213 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
215 esp_http_client_set_url(hc->client, hostAndUrl);
216 esp_http_client_set_method(hc->client, HTTP_METHOD_GET);
218 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
219 esp_err_t err = esp_http_client_perform(hc->client);
221 ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,
222 esp_http_client_get_status_code(hc->client),
223 esp_http_client_get_content_length(hc->client));
225 ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
227 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
234 MatrixHttpConnection * hc,
236 const char * requestBuffer,
237 char * outResponseBuffer, int outResponseCap,
240 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
242 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
243 "Bearer %s", hc->accessToken);
245 authorizationHeader[0] = '\0';
247 printf("POST %s%s\n%s\n", hc->host, url, requestBuffer);
249 hc->data = outResponseBuffer;
250 hc->dataCap = outResponseCap;
253 static char hostAndUrl[MAX_URL_LEN];
254 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
256 esp_http_client_set_url(hc->client, hostAndUrl);
257 esp_http_client_set_method(hc->client, HTTP_METHOD_POST);
259 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
260 esp_http_client_set_header(hc->client, "Content-Type", "application/json");
261 esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
262 esp_err_t err = esp_http_client_perform(hc->client);
264 ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
265 esp_http_client_get_status_code(hc->client),
266 esp_http_client_get_content_length(hc->client));
268 ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
270 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
277 MatrixHttpConnection * hc,
279 const char * requestBuffer,
280 char * outResponseBuffer, int outResponseCap,
283 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
285 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
286 "Bearer %s", hc->accessToken);
288 authorizationHeader[0] = '\0';
290 printf("PUT %s%s\n%s\n", hc->host, url, requestBuffer);
292 hc->data = outResponseBuffer;
293 hc->dataCap = outResponseCap;
296 static char hostAndUrl[MAX_URL_LEN];
297 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
299 esp_http_client_set_url(hc->client, hostAndUrl);
300 esp_http_client_set_method(hc->client, HTTP_METHOD_PUT);
302 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
303 esp_http_client_set_header(hc->client, "Content-Type", "application/json");
304 esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
305 esp_err_t err = esp_http_client_perform(hc->client);
307 ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRIu64,
308 esp_http_client_get_status_code(hc->client),
309 esp_http_client_get_content_length(hc->client));
311 ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
313 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);