esp_http_client_example.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. /* ESP HTTP Client Example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "esp_log.h"
  12. #include "esp_system.h"
  13. #include "nvs_flash.h"
  14. #include "esp_event.h"
  15. #include "esp_netif.h"
  16. #include "protocol_examples_common.h"
  17. #include "esp_tls.h"
  18. #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
  19. #include "esp_crt_bundle.h"
  20. #endif
  21. #include "esp_http_client.h"
  22. #define MAX_HTTP_RECV_BUFFER 512
  23. #define MAX_HTTP_OUTPUT_BUFFER 2048
  24. static const char *TAG = "HTTP_CLIENT";
  25. /* 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
  28. The CA root cert is the last cert given in the chain of certs.
  29. To embed it in the app binary, the PEM file is named
  30. in the component.mk COMPONENT_EMBED_TXTFILES variable.
  31. */
  32. extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");
  33. extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com_root_cert_pem_end");
  34. extern const char postman_root_cert_pem_start[] asm("_binary_postman_root_cert_pem_start");
  35. extern const char postman_root_cert_pem_end[] asm("_binary_postman_root_cert_pem_end");
  36. esp_err_t _http_event_handler(esp_http_client_event_t *evt)
  37. {
  38. static char *output_buffer; // Buffer to store response of http request from event handler
  39. static int output_len; // Stores number of bytes read
  40. switch(evt->event_id) {
  41. case HTTP_EVENT_ERROR:
  42. ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
  43. break;
  44. case HTTP_EVENT_ON_CONNECTED:
  45. ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
  46. break;
  47. case HTTP_EVENT_HEADER_SENT:
  48. ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
  49. break;
  50. case HTTP_EVENT_ON_HEADER:
  51. ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
  52. break;
  53. case HTTP_EVENT_ON_DATA:
  54. ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
  55. /*
  56. * Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
  57. * However, event handler can also be used in case chunked encoding is used.
  58. */
  59. if (!esp_http_client_is_chunked_response(evt->client)) {
  60. // If user_data buffer is configured, copy the response into the buffer
  61. if (evt->user_data) {
  62. memcpy(evt->user_data + output_len, evt->data, evt->data_len);
  63. } else {
  64. if (output_buffer == NULL) {
  65. output_buffer = (char *) malloc(esp_http_client_get_content_length(evt->client));
  66. output_len = 0;
  67. if (output_buffer == NULL) {
  68. ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
  69. return ESP_FAIL;
  70. }
  71. }
  72. memcpy(output_buffer + output_len, evt->data, evt->data_len);
  73. }
  74. output_len += evt->data_len;
  75. }
  76. break;
  77. case HTTP_EVENT_ON_FINISH:
  78. ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
  79. if (output_buffer != NULL) {
  80. // Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
  81. // ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
  82. free(output_buffer);
  83. output_buffer = NULL;
  84. }
  85. output_len = 0;
  86. break;
  87. case HTTP_EVENT_DISCONNECTED:
  88. ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
  89. int mbedtls_err = 0;
  90. esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
  91. if (err != 0) {
  92. ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
  93. ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
  94. }
  95. if (output_buffer != NULL) {
  96. free(output_buffer);
  97. output_buffer = NULL;
  98. }
  99. output_len = 0;
  100. break;
  101. case HTTP_EVENT_REDIRECT:
  102. ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
  103. esp_http_client_set_header(evt->client, "From", "user@example.com");
  104. esp_http_client_set_header(evt->client, "Accept", "text/html");
  105. break;
  106. }
  107. return ESP_OK;
  108. }
  109. static void http_rest_with_url(void)
  110. {
  111. char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
  112. /**
  113. * NOTE: All the configuration parameters for http_client must be spefied either in URL or as host and path parameters.
  114. * If host and path parameters are not set, query parameter will be ignored. In such cases,
  115. * query parameter should be specified in URL.
  116. *
  117. * If URL as well as host and path parameters are specified, values of host and path will be considered.
  118. */
  119. esp_http_client_config_t config = {
  120. .host = "httpbin.org",
  121. .path = "/get",
  122. .query = "esp",
  123. .event_handler = _http_event_handler,
  124. .user_data = local_response_buffer, // Pass address of local buffer to get response
  125. .disable_auto_redirect = true,
  126. };
  127. esp_http_client_handle_t client = esp_http_client_init(&config);
  128. // GET
  129. esp_err_t err = esp_http_client_perform(client);
  130. if (err == ESP_OK) {
  131. ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld",
  132. esp_http_client_get_status_code(client),
  133. esp_http_client_get_content_length(client));
  134. } else {
  135. ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
  136. }
  137. ESP_LOG_BUFFER_HEX(TAG, local_response_buffer, strlen(local_response_buffer));
  138. // POST
  139. const char *post_data = "{\"field1\":\"value1\"}";
  140. esp_http_client_set_url(client, "http://httpbin.org/post");
  141. esp_http_client_set_method(client, HTTP_METHOD_POST);
  142. esp_http_client_set_header(client, "Content-Type", "application/json");
  143. esp_http_client_set_post_field(client, post_data, strlen(post_data));
  144. err = esp_http_client_perform(client);
  145. if (err == ESP_OK) {
  146. ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %lld",
  147. esp_http_client_get_status_code(client),
  148. esp_http_client_get_content_length(client));
  149. } else {
  150. ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
  151. }
  152. //PUT
  153. esp_http_client_set_url(client, "http://httpbin.org/put");
  154. esp_http_client_set_method(client, HTTP_METHOD_PUT);
  155. err = esp_http_client_perform(client);
  156. if (err == ESP_OK) {
  157. ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %lld",
  158. esp_http_client_get_status_code(client),
  159. esp_http_client_get_content_length(client));
  160. } else {
  161. ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
  162. }
  163. //PATCH
  164. esp_http_client_set_url(client, "http://httpbin.org/patch");
  165. esp_http_client_set_method(client, HTTP_METHOD_PATCH);
  166. esp_http_client_set_post_field(client, NULL, 0);
  167. err = esp_http_client_perform(client);
  168. if (err == ESP_OK) {
  169. ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %lld",
  170. esp_http_client_get_status_code(client),
  171. esp_http_client_get_content_length(client));
  172. } else {
  173. ESP_LOGE(TAG, "HTTP PATCH request failed: %s", esp_err_to_name(err));
  174. }
  175. //DELETE
  176. esp_http_client_set_url(client, "http://httpbin.org/delete");
  177. esp_http_client_set_method(client, HTTP_METHOD_DELETE);
  178. err = esp_http_client_perform(client);
  179. if (err == ESP_OK) {
  180. ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %lld",
  181. esp_http_client_get_status_code(client),
  182. esp_http_client_get_content_length(client));
  183. } else {
  184. ESP_LOGE(TAG, "HTTP DELETE request failed: %s", esp_err_to_name(err));
  185. }
  186. //HEAD
  187. esp_http_client_set_url(client, "http://httpbin.org/get");
  188. esp_http_client_set_method(client, HTTP_METHOD_HEAD);
  189. err = esp_http_client_perform(client);
  190. if (err == ESP_OK) {
  191. ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %lld",
  192. esp_http_client_get_status_code(client),
  193. esp_http_client_get_content_length(client));
  194. } else {
  195. ESP_LOGE(TAG, "HTTP HEAD request failed: %s", esp_err_to_name(err));
  196. }
  197. esp_http_client_cleanup(client);
  198. }
  199. static void http_rest_with_hostname_path(void)
  200. {
  201. esp_http_client_config_t config = {
  202. .host = "httpbin.org",
  203. .path = "/get",
  204. .transport_type = HTTP_TRANSPORT_OVER_TCP,
  205. .event_handler = _http_event_handler,
  206. };
  207. esp_http_client_handle_t client = esp_http_client_init(&config);
  208. // GET
  209. esp_err_t err = esp_http_client_perform(client);
  210. if (err == ESP_OK) {
  211. ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld",
  212. esp_http_client_get_status_code(client),
  213. esp_http_client_get_content_length(client));
  214. } else {
  215. ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
  216. }
  217. // POST
  218. const char *post_data = "field1=value1&field2=value2";
  219. esp_http_client_set_url(client, "/post");
  220. esp_http_client_set_method(client, HTTP_METHOD_POST);
  221. esp_http_client_set_post_field(client, post_data, strlen(post_data));
  222. err = esp_http_client_perform(client);
  223. if (err == ESP_OK) {
  224. ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %lld",
  225. esp_http_client_get_status_code(client),
  226. esp_http_client_get_content_length(client));
  227. } else {
  228. ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
  229. }
  230. //PUT
  231. esp_http_client_set_url(client, "/put");
  232. esp_http_client_set_method(client, HTTP_METHOD_PUT);
  233. err = esp_http_client_perform(client);
  234. if (err == ESP_OK) {
  235. ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %lld",
  236. esp_http_client_get_status_code(client),
  237. esp_http_client_get_content_length(client));
  238. } else {
  239. ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
  240. }
  241. //PATCH
  242. esp_http_client_set_url(client, "/patch");
  243. esp_http_client_set_method(client, HTTP_METHOD_PATCH);
  244. esp_http_client_set_post_field(client, NULL, 0);
  245. err = esp_http_client_perform(client);
  246. if (err == ESP_OK) {
  247. ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %lld",
  248. esp_http_client_get_status_code(client),
  249. esp_http_client_get_content_length(client));
  250. } else {
  251. ESP_LOGE(TAG, "HTTP PATCH request failed: %s", esp_err_to_name(err));
  252. }
  253. //DELETE
  254. esp_http_client_set_url(client, "/delete");
  255. esp_http_client_set_method(client, HTTP_METHOD_DELETE);
  256. err = esp_http_client_perform(client);
  257. if (err == ESP_OK) {
  258. ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %lld",
  259. esp_http_client_get_status_code(client),
  260. esp_http_client_get_content_length(client));
  261. } else {
  262. ESP_LOGE(TAG, "HTTP DELETE request failed: %s", esp_err_to_name(err));
  263. }
  264. //HEAD
  265. esp_http_client_set_url(client, "/get");
  266. esp_http_client_set_method(client, HTTP_METHOD_HEAD);
  267. err = esp_http_client_perform(client);
  268. if (err == ESP_OK) {
  269. ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %lld",
  270. esp_http_client_get_status_code(client),
  271. esp_http_client_get_content_length(client));
  272. } else {
  273. ESP_LOGE(TAG, "HTTP HEAD request failed: %s", esp_err_to_name(err));
  274. }
  275. esp_http_client_cleanup(client);
  276. }
  277. #if CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH
  278. static void http_auth_basic(void)
  279. {
  280. /**
  281. * Note: `max_authorization_retries` in esp_http_client_config_t
  282. * can be used to configure number of retry attempts to be performed
  283. * in case unauthorized status code is received.
  284. *
  285. * To disable authorization retries, set max_authorization_retries to -1.
  286. */
  287. esp_http_client_config_t config = {
  288. .url = "http://user:passwd@httpbin.org/basic-auth/user/passwd",
  289. .event_handler = _http_event_handler,
  290. .auth_type = HTTP_AUTH_TYPE_BASIC,
  291. .max_authorization_retries = -1,
  292. };
  293. esp_http_client_handle_t client = esp_http_client_init(&config);
  294. esp_err_t err = esp_http_client_perform(client);
  295. if (err == ESP_OK) {
  296. ESP_LOGI(TAG, "HTTP Basic Auth Status = %d, content_length = %lld",
  297. esp_http_client_get_status_code(client),
  298. esp_http_client_get_content_length(client));
  299. } else {
  300. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  301. }
  302. esp_http_client_cleanup(client);
  303. }
  304. static void http_auth_basic_redirect(void)
  305. {
  306. esp_http_client_config_t config = {
  307. .url = "http://user:passwd@httpbin.org/basic-auth/user/passwd",
  308. .event_handler = _http_event_handler,
  309. };
  310. esp_http_client_handle_t client = esp_http_client_init(&config);
  311. esp_err_t err = esp_http_client_perform(client);
  312. if (err == ESP_OK) {
  313. ESP_LOGI(TAG, "HTTP Basic Auth redirect Status = %d, content_length = %lld",
  314. esp_http_client_get_status_code(client),
  315. esp_http_client_get_content_length(client));
  316. } else {
  317. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  318. }
  319. esp_http_client_cleanup(client);
  320. }
  321. #endif
  322. #if CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH
  323. static void http_auth_digest(void)
  324. {
  325. esp_http_client_config_t config = {
  326. .url = "http://user:passwd@httpbin.org/digest-auth/auth/user/passwd/MD5/never",
  327. .event_handler = _http_event_handler,
  328. };
  329. esp_http_client_handle_t client = esp_http_client_init(&config);
  330. esp_err_t err = esp_http_client_perform(client);
  331. if (err == ESP_OK) {
  332. ESP_LOGI(TAG, "HTTP Digest Auth Status = %d, content_length = %lld",
  333. esp_http_client_get_status_code(client),
  334. esp_http_client_get_content_length(client));
  335. } else {
  336. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  337. }
  338. esp_http_client_cleanup(client);
  339. }
  340. #endif
  341. #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
  342. static void https_with_url(void)
  343. {
  344. esp_http_client_config_t config = {
  345. .url = "https://www.howsmyssl.com",
  346. .event_handler = _http_event_handler,
  347. .crt_bundle_attach = esp_crt_bundle_attach,
  348. };
  349. esp_http_client_handle_t client = esp_http_client_init(&config);
  350. esp_err_t err = esp_http_client_perform(client);
  351. if (err == ESP_OK) {
  352. ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
  353. esp_http_client_get_status_code(client),
  354. esp_http_client_get_content_length(client));
  355. } else {
  356. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  357. }
  358. esp_http_client_cleanup(client);
  359. }
  360. #endif // CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
  361. static void https_with_hostname_path(void)
  362. {
  363. esp_http_client_config_t config = {
  364. .host = "www.howsmyssl.com",
  365. .path = "/",
  366. .transport_type = HTTP_TRANSPORT_OVER_SSL,
  367. .event_handler = _http_event_handler,
  368. .cert_pem = howsmyssl_com_root_cert_pem_start,
  369. };
  370. esp_http_client_handle_t client = esp_http_client_init(&config);
  371. esp_err_t err = esp_http_client_perform(client);
  372. if (err == ESP_OK) {
  373. ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
  374. esp_http_client_get_status_code(client),
  375. esp_http_client_get_content_length(client));
  376. } else {
  377. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  378. }
  379. esp_http_client_cleanup(client);
  380. }
  381. static void http_relative_redirect(void)
  382. {
  383. esp_http_client_config_t config = {
  384. .url = "http://httpbin.org/relative-redirect/3",
  385. .event_handler = _http_event_handler,
  386. };
  387. esp_http_client_handle_t client = esp_http_client_init(&config);
  388. esp_err_t err = esp_http_client_perform(client);
  389. if (err == ESP_OK) {
  390. ESP_LOGI(TAG, "HTTP Relative path redirect Status = %d, content_length = %lld",
  391. esp_http_client_get_status_code(client),
  392. esp_http_client_get_content_length(client));
  393. } else {
  394. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  395. }
  396. esp_http_client_cleanup(client);
  397. }
  398. static void http_absolute_redirect(void)
  399. {
  400. esp_http_client_config_t config = {
  401. .url = "http://httpbin.org/absolute-redirect/3",
  402. .event_handler = _http_event_handler,
  403. };
  404. esp_http_client_handle_t client = esp_http_client_init(&config);
  405. esp_err_t err = esp_http_client_perform(client);
  406. if (err == ESP_OK) {
  407. ESP_LOGI(TAG, "HTTP Absolute path redirect Status = %d, content_length = %lld",
  408. esp_http_client_get_status_code(client),
  409. esp_http_client_get_content_length(client));
  410. } else {
  411. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  412. }
  413. esp_http_client_cleanup(client);
  414. }
  415. static void http_absolute_redirect_manual(void)
  416. {
  417. esp_http_client_config_t config = {
  418. .url = "http://httpbin.org/absolute-redirect/3",
  419. .event_handler = _http_event_handler,
  420. .disable_auto_redirect = true,
  421. };
  422. esp_http_client_handle_t client = esp_http_client_init(&config);
  423. esp_err_t err = esp_http_client_perform(client);
  424. if (err == ESP_OK) {
  425. ESP_LOGI(TAG, "HTTP Absolute path redirect (manual) Status = %d, content_length = %lld",
  426. esp_http_client_get_status_code(client),
  427. esp_http_client_get_content_length(client));
  428. } else {
  429. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  430. }
  431. esp_http_client_cleanup(client);
  432. }
  433. static void http_redirect_to_https(void)
  434. {
  435. esp_http_client_config_t config = {
  436. .url = "http://httpbin.org/redirect-to?url=https%3A%2F%2Fwww.howsmyssl.com",
  437. .event_handler = _http_event_handler,
  438. .cert_pem = howsmyssl_com_root_cert_pem_start,
  439. };
  440. esp_http_client_handle_t client = esp_http_client_init(&config);
  441. esp_err_t err = esp_http_client_perform(client);
  442. if (err == ESP_OK) {
  443. ESP_LOGI(TAG, "HTTP redirect to HTTPS Status = %d, content_length = %lld",
  444. esp_http_client_get_status_code(client),
  445. esp_http_client_get_content_length(client));
  446. } else {
  447. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  448. }
  449. esp_http_client_cleanup(client);
  450. }
  451. static void http_download_chunk(void)
  452. {
  453. esp_http_client_config_t config = {
  454. .url = "http://httpbin.org/stream-bytes/8912",
  455. .event_handler = _http_event_handler,
  456. };
  457. esp_http_client_handle_t client = esp_http_client_init(&config);
  458. esp_err_t err = esp_http_client_perform(client);
  459. if (err == ESP_OK) {
  460. ESP_LOGI(TAG, "HTTP chunk encoding Status = %d, content_length = %lld",
  461. esp_http_client_get_status_code(client),
  462. esp_http_client_get_content_length(client));
  463. } else {
  464. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  465. }
  466. esp_http_client_cleanup(client);
  467. }
  468. static void http_perform_as_stream_reader(void)
  469. {
  470. char *buffer = malloc(MAX_HTTP_RECV_BUFFER + 1);
  471. if (buffer == NULL) {
  472. ESP_LOGE(TAG, "Cannot malloc http receive buffer");
  473. return;
  474. }
  475. esp_http_client_config_t config = {
  476. .url = "http://httpbin.org/get",
  477. };
  478. esp_http_client_handle_t client = esp_http_client_init(&config);
  479. esp_err_t err;
  480. if ((err = esp_http_client_open(client, 0)) != ESP_OK) {
  481. ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
  482. free(buffer);
  483. return;
  484. }
  485. int content_length = esp_http_client_fetch_headers(client);
  486. int total_read_len = 0, read_len;
  487. if (total_read_len < content_length && content_length <= MAX_HTTP_RECV_BUFFER) {
  488. read_len = esp_http_client_read(client, buffer, content_length);
  489. if (read_len <= 0) {
  490. ESP_LOGE(TAG, "Error read data");
  491. }
  492. buffer[read_len] = 0;
  493. ESP_LOGD(TAG, "read_len = %d", read_len);
  494. }
  495. ESP_LOGI(TAG, "HTTP Stream reader Status = %d, content_length = %lld",
  496. esp_http_client_get_status_code(client),
  497. esp_http_client_get_content_length(client));
  498. esp_http_client_close(client);
  499. esp_http_client_cleanup(client);
  500. free(buffer);
  501. }
  502. static void https_async(void)
  503. {
  504. esp_http_client_config_t config = {
  505. .url = "https://postman-echo.com/post",
  506. .event_handler = _http_event_handler,
  507. .cert_pem = postman_root_cert_pem_start,
  508. .is_async = true,
  509. .timeout_ms = 5000,
  510. };
  511. esp_http_client_handle_t client = esp_http_client_init(&config);
  512. esp_err_t err;
  513. const char *post_data = "Using a Palantír requires a person with great strength of will and wisdom. The Palantíri were meant to "
  514. "be used by the Dúnedain to communicate throughout the Realms in Exile. During the War of the Ring, "
  515. "the Palantíri were used by many individuals. Sauron used the Ithil-stone to take advantage of the users "
  516. "of the other two stones, the Orthanc-stone and Anor-stone, but was also susceptible to deception himself.";
  517. esp_http_client_set_method(client, HTTP_METHOD_POST);
  518. esp_http_client_set_post_field(client, post_data, strlen(post_data));
  519. while (1) {
  520. err = esp_http_client_perform(client);
  521. if (err != ESP_ERR_HTTP_EAGAIN) {
  522. break;
  523. }
  524. }
  525. if (err == ESP_OK) {
  526. ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
  527. esp_http_client_get_status_code(client),
  528. esp_http_client_get_content_length(client));
  529. } else {
  530. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  531. }
  532. esp_http_client_cleanup(client);
  533. }
  534. static void https_with_invalid_url(void)
  535. {
  536. esp_http_client_config_t config = {
  537. .url = "https://not.existent.url",
  538. .event_handler = _http_event_handler,
  539. };
  540. esp_http_client_handle_t client = esp_http_client_init(&config);
  541. esp_err_t err = esp_http_client_perform(client);
  542. if (err == ESP_OK) {
  543. ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld",
  544. esp_http_client_get_status_code(client),
  545. esp_http_client_get_content_length(client));
  546. } else {
  547. ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
  548. }
  549. esp_http_client_cleanup(client);
  550. }
  551. /*
  552. * http_native_request() demonstrates use of low level APIs to connect to a server,
  553. * make a http request and read response. Event handler is not used in this case.
  554. * Note: This approach should only be used in case use of low level APIs is required.
  555. * The easiest way is to use esp_http_perform()
  556. */
  557. static void http_native_request(void)
  558. {
  559. char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0}; // Buffer to store response of http request
  560. int content_length = 0;
  561. esp_http_client_config_t config = {
  562. .url = "http://httpbin.org/get",
  563. };
  564. esp_http_client_handle_t client = esp_http_client_init(&config);
  565. // GET Request
  566. esp_http_client_set_method(client, HTTP_METHOD_GET);
  567. esp_err_t err = esp_http_client_open(client, 0);
  568. if (err != ESP_OK) {
  569. ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
  570. } else {
  571. content_length = esp_http_client_fetch_headers(client);
  572. if (content_length < 0) {
  573. ESP_LOGE(TAG, "HTTP client fetch headers failed");
  574. } else {
  575. int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
  576. if (data_read >= 0) {
  577. ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld",
  578. esp_http_client_get_status_code(client),
  579. esp_http_client_get_content_length(client));
  580. ESP_LOG_BUFFER_HEX(TAG, output_buffer, data_read);
  581. } else {
  582. ESP_LOGE(TAG, "Failed to read response");
  583. }
  584. }
  585. }
  586. esp_http_client_close(client);
  587. // POST Request
  588. const char *post_data = "{\"field1\":\"value1\"}";
  589. esp_http_client_set_url(client, "http://httpbin.org/post");
  590. esp_http_client_set_method(client, HTTP_METHOD_POST);
  591. esp_http_client_set_header(client, "Content-Type", "application/json");
  592. err = esp_http_client_open(client, strlen(post_data));
  593. if (err != ESP_OK) {
  594. ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
  595. } else {
  596. int wlen = esp_http_client_write(client, post_data, strlen(post_data));
  597. if (wlen < 0) {
  598. ESP_LOGE(TAG, "Write failed");
  599. }
  600. content_length = esp_http_client_fetch_headers(client);
  601. if (content_length < 0) {
  602. ESP_LOGE(TAG, "HTTP client fetch headers failed");
  603. } else {
  604. int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
  605. if (data_read >= 0) {
  606. ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %lld",
  607. esp_http_client_get_status_code(client),
  608. esp_http_client_get_content_length(client));
  609. ESP_LOG_BUFFER_HEX(TAG, output_buffer, strlen(output_buffer));
  610. } else {
  611. ESP_LOGE(TAG, "Failed to read response");
  612. }
  613. }
  614. }
  615. esp_http_client_cleanup(client);
  616. }
  617. #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
  618. static void http_partial_download(void)
  619. {
  620. esp_http_client_config_t config = {
  621. .url = "https://dl.espressif.com/dl/esp-idf/ci/esp_http_client_demo.txt",
  622. .event_handler = _http_event_handler,
  623. .crt_bundle_attach = esp_crt_bundle_attach,
  624. };
  625. esp_http_client_handle_t client = esp_http_client_init(&config);
  626. // Download a file excluding first 10 bytes
  627. esp_http_client_set_header(client, "Range", "bytes=10-");
  628. esp_err_t err = esp_http_client_perform(client);
  629. if (err == ESP_OK) {
  630. ESP_LOGI(TAG, "HTTP Status = %d, content_length = %lld",
  631. esp_http_client_get_status_code(client),
  632. esp_http_client_get_content_length(client));
  633. } else {
  634. ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err));
  635. }
  636. // Download last 10 bytes of a file
  637. esp_http_client_set_header(client, "Range", "bytes=-10");
  638. err = esp_http_client_perform(client);
  639. if (err == ESP_OK) {
  640. ESP_LOGI(TAG, "HTTP Status = %d, content_length = %lld",
  641. esp_http_client_get_status_code(client),
  642. esp_http_client_get_content_length(client));
  643. } else {
  644. ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err));
  645. }
  646. // Download 10 bytes from 11 to 20
  647. esp_http_client_set_header(client, "Range", "bytes=11-20");
  648. err = esp_http_client_perform(client);
  649. if (err == ESP_OK) {
  650. ESP_LOGI(TAG, "HTTP Status = %d, content_length = %lld",
  651. esp_http_client_get_status_code(client),
  652. esp_http_client_get_content_length(client));
  653. } else {
  654. ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err));
  655. }
  656. esp_http_client_cleanup(client);
  657. }
  658. #endif // CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
  659. static void http_test_task(void *pvParameters)
  660. {
  661. http_rest_with_url();
  662. http_rest_with_hostname_path();
  663. #if CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH
  664. http_auth_basic();
  665. http_auth_basic_redirect();
  666. #endif
  667. #if CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH
  668. http_auth_digest();
  669. #endif
  670. http_relative_redirect();
  671. http_absolute_redirect();
  672. http_absolute_redirect_manual();
  673. #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
  674. https_with_url();
  675. #endif
  676. https_with_hostname_path();
  677. http_redirect_to_https();
  678. http_download_chunk();
  679. http_perform_as_stream_reader();
  680. https_async();
  681. https_with_invalid_url();
  682. http_native_request();
  683. #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
  684. http_partial_download();
  685. #endif
  686. ESP_LOGI(TAG, "Finish http example");
  687. vTaskDelete(NULL);
  688. }
  689. void app_main(void)
  690. {
  691. esp_err_t ret = nvs_flash_init();
  692. if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  693. ESP_ERROR_CHECK(nvs_flash_erase());
  694. ret = nvs_flash_init();
  695. }
  696. ESP_ERROR_CHECK(ret);
  697. ESP_ERROR_CHECK(esp_netif_init());
  698. ESP_ERROR_CHECK(esp_event_loop_create_default());
  699. /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
  700. * Read "Establishing Wi-Fi or Ethernet Connection" section in
  701. * examples/protocols/README.md for more information about this function.
  702. */
  703. ESP_ERROR_CHECK(example_connect());
  704. ESP_LOGI(TAG, "Connected to AP, begin http example");
  705. xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL);
  706. }