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);
103 hc->dataLen += copy_len;
106 case HTTP_EVENT_ON_FINISH:
107 ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
109 case HTTP_EVENT_DISCONNECTED:
110 ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
112 esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
114 ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
115 ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
118 case HTTP_EVENT_REDIRECT:
119 ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
120 // esp_http_client_set_header(evt->client, "From", "user@example.com");
121 // esp_http_client_set_header(evt->client, "Accept", "text/html");
122 // esp_http_client_set_redirection(evt->client);
130 MatrixHttpConnection * hc)
132 esp_http_client_config_t config = {
135 .event_handler = _http_event_handler,
137 .disable_auto_redirect = true,
138 .crt_bundle_attach = esp_crt_bundle_attach,
141 hc->client = esp_http_client_init(&config);
143 esp_http_client_set_timeout_ms(hc->client, 10000);
147 MatrixHttpDisconnect(
148 MatrixHttpConnection * hc)
150 esp_http_client_cleanup(hc->client);
156 MatrixHttpConnection ** hc,
159 *hc = (MatrixHttpConnection *)calloc(1, sizeof(MatrixHttpConnection));
164 MatrixHttpConnect(*hc);
171 MatrixHttpConnection ** hc)
173 MatrixHttpDisconnect(*hc);
182 MatrixHttpSetAccessToken(
183 MatrixHttpConnection * hc,
184 const char * accessToken)
186 hc->accessToken = accessToken;
193 MatrixHttpConnection * hc,
195 char * outResponseBuffer, int outResponseCap,
198 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
200 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
201 "Bearer %s", hc->accessToken);
203 authorizationHeader[0] = '\0';
205 printf("GET %s%s\n", hc->host, url);
207 hc->data = outResponseBuffer;
208 hc->dataCap = outResponseCap;
211 static char hostAndUrl[MAX_URL_LEN];
212 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
214 esp_http_client_set_url(hc->client, hostAndUrl);
215 esp_http_client_set_method(hc->client, HTTP_METHOD_GET);
217 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
218 esp_err_t err = esp_http_client_perform(hc->client);
220 ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,
221 esp_http_client_get_status_code(hc->client),
222 esp_http_client_get_content_length(hc->client));
224 ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
226 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
233 MatrixHttpConnection * hc,
235 const char * requestBuffer,
236 char * outResponseBuffer, int outResponseCap,
239 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
241 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
242 "Bearer %s", hc->accessToken);
244 authorizationHeader[0] = '\0';
246 printf("POST %s%s\n%s\n", hc->host, url, requestBuffer);
248 hc->data = outResponseBuffer;
249 hc->dataCap = outResponseCap;
252 static char hostAndUrl[MAX_URL_LEN];
253 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
255 esp_http_client_set_url(hc->client, hostAndUrl);
256 esp_http_client_set_method(hc->client, HTTP_METHOD_POST);
258 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
259 esp_http_client_set_header(hc->client, "Content-Type", "application/json");
260 esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
261 esp_err_t err = esp_http_client_perform(hc->client);
263 ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
264 esp_http_client_get_status_code(hc->client),
265 esp_http_client_get_content_length(hc->client));
267 ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
269 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
276 MatrixHttpConnection * hc,
278 const char * requestBuffer,
279 char * outResponseBuffer, int outResponseCap,
282 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
284 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
285 "Bearer %s", hc->accessToken);
287 authorizationHeader[0] = '\0';
289 printf("PUT %s%s\n%s\n", hc->host, url, requestBuffer);
291 hc->data = outResponseBuffer;
292 hc->dataCap = outResponseCap;
295 static char hostAndUrl[MAX_URL_LEN];
296 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
298 esp_http_client_set_url(hc->client, hostAndUrl);
299 esp_http_client_set_method(hc->client, HTTP_METHOD_PUT);
301 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
302 esp_http_client_set_header(hc->client, "Content-Type", "application/json");
303 esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
304 esp_err_t err = esp_http_client_perform(hc->client);
306 ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRIu64,
307 esp_http_client_get_status_code(hc->client),
308 esp_http_client_get_content_length(hc->client));
310 ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
312 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);