2 #include <sys/param.h>
\r
6 #include "nvs_flash.h"
\r
7 #include "esp_event.h"
\r
8 #include "esp_netif.h"
\r
9 // #include "protocol_examples_common.h"
\r
10 // #include "protocol_examples_utils.h"
\r
11 #include "esp_tls.h"
\r
12 #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
\r
13 #include "esp_crt_bundle.h"
\r
16 #if !CONFIG_IDF_TARGET_LINUX
\r
17 #include "freertos/FreeRTOS.h"
\r
18 #include "freertos/task.h"
\r
19 #include "esp_system.h"
\r
22 #include "esp_http_client.h"
\r
24 /* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem
\r
26 The PEM file was extracted from the output of this command:
\r
27 openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null
\r
29 The CA root cert is the last cert given in the chain of certs.
\r
31 To embed it in the app binary, the PEM file is named
\r
32 in the component.mk COMPONENT_EMBED_TXTFILES variable.
\r
34 // extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");
\r
35 // extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com_root_cert_pem_end");
\r
37 // extern const char postman_root_cert_pem_start[] asm("_binary_postman_root_cert_pem_start");
\r
38 // extern const char postman_root_cert_pem_end[] asm("_binary_postman_root_cert_pem_end");
\r
42 #define HTTP_CONNECTION_DATA_SIZE 1024*64
\r
43 #define AUTHORIZATION_HEADER_LEN 64
\r
45 struct MatrixHttpConnection {
\r
46 esp_http_client_handle_t client;
\r
49 const char * accessToken;
\r
51 // char data[HTTP_CONNECTION_DATA_SIZE];
\r
58 static const char *TAG = "HTTP_CLIENT";
\r
60 esp_err_t _http_event_handler(esp_http_client_event_t *evt)
\r
62 vTaskDelay(10/portTICK_PERIOD_MS);
\r
64 MatrixHttpConnection * hc = (MatrixHttpConnection *)evt->user_data;
\r
65 switch(evt->event_id) {
\r
66 case HTTP_EVENT_ERROR:
\r
67 ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
\r
69 case HTTP_EVENT_ON_CONNECTED:
\r
70 ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
\r
72 case HTTP_EVENT_HEADER_SENT:
\r
73 ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
\r
75 case HTTP_EVENT_ON_HEADER:
\r
76 ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
\r
78 case HTTP_EVENT_ON_DATA:
\r
79 ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
\r
81 * Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
\r
82 * However, event handler can also be used in case chunked encoding is used.
\r
84 if (!esp_http_client_is_chunked_response(evt->client)) {
\r
85 ESP_LOGD(TAG, "Non-Chunked Encoding");
\r
88 ESP_LOGD(TAG, "Chunked Encoding");
\r
93 // const int64_t buffer_len = esp_http_client_get_content_length(evt->client);
\r
94 // if (buffer_len < hc->dataCap) {
\r
95 // ESP_LOGE(TAG, "Output buffer too small: %" PRIu64 ", data_len: %d", buffer_len, evt->data_len);
\r
98 copy_len = MIN(evt->data_len, (hc->dataCap - hc->dataLen));
\r
100 memcpy(hc->data + hc->dataLen, evt->data, copy_len);
\r
101 hc->data[hc->dataLen + copy_len] = '\0';
\r
104 hc->dataLen += copy_len;
\r
107 case HTTP_EVENT_ON_FINISH:
\r
108 ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
\r
110 case HTTP_EVENT_DISCONNECTED:
\r
111 ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
\r
112 int mbedtls_err = 0;
\r
113 esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
\r
115 ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
\r
116 ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
\r
119 case HTTP_EVENT_REDIRECT:
\r
120 ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
\r
121 // esp_http_client_set_header(evt->client, "From", "user@example.com");
\r
122 // esp_http_client_set_header(evt->client, "Accept", "text/html");
\r
123 // esp_http_client_set_redirection(evt->client);
\r
131 MatrixHttpConnection * hc)
\r
133 esp_http_client_config_t config = {
\r
136 .event_handler = _http_event_handler,
\r
138 .disable_auto_redirect = true,
\r
139 .crt_bundle_attach = esp_crt_bundle_attach,
\r
142 hc->client = esp_http_client_init(&config);
\r
144 esp_http_client_set_timeout_ms(hc->client, 20000);
\r
148 MatrixHttpDisconnect(
\r
149 MatrixHttpConnection * hc)
\r
151 esp_http_client_cleanup(hc->client);
\r
157 MatrixHttpConnection ** hc,
\r
160 *hc = (MatrixHttpConnection *)calloc(1, sizeof(MatrixHttpConnection));
\r
162 (*hc)->host = host;
\r
164 MatrixHttpConnect(*hc);
\r
171 MatrixHttpConnection ** hc)
\r
173 MatrixHttpDisconnect(*hc);
\r
182 MatrixHttpSetAccessToken(
\r
183 MatrixHttpConnection * hc,
\r
184 const char * accessToken)
\r
186 hc->accessToken = accessToken;
\r
193 MatrixHttpConnection * hc,
\r
195 char * outResponseBuffer, int outResponseCap,
\r
196 bool authenticated)
\r
198 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
\r
200 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
\r
201 "Bearer %s", hc->accessToken);
\r
203 authorizationHeader[0] = '\0';
\r
205 hc->data = outResponseBuffer;
\r
206 hc->dataCap = outResponseCap;
\r
209 static char hostAndUrl[MAX_URL_LEN];
\r
210 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
\r
212 esp_http_client_set_url(hc->client, hostAndUrl);
\r
213 esp_http_client_set_method(hc->client, HTTP_METHOD_GET);
\r
215 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
\r
216 esp_err_t err = esp_http_client_perform(hc->client);
\r
217 if (err == ESP_OK) {
\r
218 ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,
\r
219 esp_http_client_get_status_code(hc->client),
\r
220 esp_http_client_get_content_length(hc->client));
\r
222 ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
\r
224 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
\r
231 MatrixHttpConnection * hc,
\r
233 const char * requestBuffer,
\r
234 char * outResponseBuffer, int outResponseCap,
\r
235 bool authenticated)
\r
237 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
\r
239 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
\r
240 "Bearer %s", hc->accessToken);
\r
242 authorizationHeader[0] = '\0';
\r
244 hc->data = outResponseBuffer;
\r
245 hc->dataCap = outResponseCap;
\r
248 static char hostAndUrl[MAX_URL_LEN];
\r
249 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
\r
251 esp_http_client_set_url(hc->client, hostAndUrl);
\r
252 esp_http_client_set_method(hc->client, HTTP_METHOD_POST);
\r
254 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
\r
255 esp_http_client_set_header(hc->client, "Content-Type", "application/json");
\r
256 esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
\r
257 esp_err_t err = esp_http_client_perform(hc->client);
\r
258 if (err == ESP_OK) {
\r
259 ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
\r
260 esp_http_client_get_status_code(hc->client),
\r
261 esp_http_client_get_content_length(hc->client));
\r
263 ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
\r
265 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
\r
272 MatrixHttpConnection * hc,
\r
274 const char * requestBuffer,
\r
275 char * outResponseBuffer, int outResponseCap,
\r
276 bool authenticated)
\r
278 static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
\r
280 snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
\r
281 "Bearer %s", hc->accessToken);
\r
283 authorizationHeader[0] = '\0';
\r
285 hc->data = outResponseBuffer;
\r
286 hc->dataCap = outResponseCap;
\r
289 static char hostAndUrl[MAX_URL_LEN];
\r
290 snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
\r
292 esp_http_client_set_url(hc->client, hostAndUrl);
\r
293 esp_http_client_set_method(hc->client, HTTP_METHOD_PUT);
\r
295 esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
\r
296 esp_http_client_set_header(hc->client, "Content-Type", "application/json");
\r
297 esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
\r
298 esp_err_t err = esp_http_client_perform(hc->client);
\r
299 if (err == ESP_OK) {
\r
300 ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRIu64,
\r
301 esp_http_client_get_status_code(hc->client),
\r
302 esp_http_client_get_content_length(hc->client));
\r
304 ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
\r
306 // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
\r