]> granicus.if.org Git - esp-idf/blob - examples/protocols/esp_http_client/main/esp_http_client_example.c
esp32: Allow SPIRAM_MALLOC_RESERVE_INTERNAL to span multiple regions of memory
[esp-idf] / examples / protocols / esp_http_client / main / esp_http_client_example.c
1 /* ESP HTTP Client Example
2
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include "freertos/FreeRTOS.h"
13 #include "freertos/task.h"
14 #include "esp_log.h"
15 #include "esp_system.h"
16 #include "nvs_flash.h"
17 #include "app_wifi.h"
18
19 #include "esp_http_client.h"
20
21 #define MAX_HTTP_RECV_BUFFER 512
22 static const char *TAG = "HTTP_CLIENT";
23
24 /* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem
25
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
29    The CA root cert is the last cert given in the chain of certs.
30
31    To embed it in the app binary, the PEM file is named
32    in the component.mk COMPONENT_EMBED_TXTFILES variable.
33 */
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");
36
37 esp_err_t _http_event_handler(esp_http_client_event_t *evt)
38 {
39     switch(evt->event_id) {
40         case HTTP_EVENT_ERROR:
41             ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
42             break;
43         case HTTP_EVENT_ON_CONNECTED:
44             ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
45             break;
46         case HTTP_EVENT_HEADER_SENT:
47             ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
48             break;
49         case HTTP_EVENT_ON_HEADER:
50             ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
51             break;
52         case HTTP_EVENT_ON_DATA:
53             ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
54             if (!esp_http_client_is_chunked_response(evt->client)) {
55                 // Write out data
56                 // printf("%.*s", evt->data_len, (char*)evt->data);
57             }
58
59             break;
60         case HTTP_EVENT_ON_FINISH:
61             ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
62             break;
63         case HTTP_EVENT_DISCONNECTED:
64             ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
65             break;
66     }
67     return ESP_OK;
68 }
69
70 static void http_rest()
71 {
72     esp_http_client_config_t config = {
73         .url = "http://httpbin.org/get",
74         .event_handler = _http_event_handler,
75     };
76     esp_http_client_handle_t client = esp_http_client_init(&config);
77
78     // GET
79     esp_err_t err = esp_http_client_perform(client);
80     if (err == ESP_OK) {
81         ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",
82                 esp_http_client_get_status_code(client),
83                 esp_http_client_get_content_length(client));
84     } else {
85         ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
86     }
87
88     // POST
89     const char *post_data = "field1=value1&field2=value2";
90     esp_http_client_set_url(client, "http://httpbin.org/post");
91     esp_http_client_set_method(client, HTTP_METHOD_POST);
92     esp_http_client_set_post_field(client, post_data, strlen(post_data));
93     err = esp_http_client_perform(client);
94     if (err == ESP_OK) {
95         ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d",
96                 esp_http_client_get_status_code(client),
97                 esp_http_client_get_content_length(client));
98     } else {
99         ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
100     }
101
102     //PUT
103     esp_http_client_set_url(client, "http://httpbin.org/put");
104     esp_http_client_set_method(client, HTTP_METHOD_PUT);
105     err = esp_http_client_perform(client);
106     if (err == ESP_OK) {
107         ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %d",
108                 esp_http_client_get_status_code(client),
109                 esp_http_client_get_content_length(client));
110     } else {
111         ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
112     }
113
114     //PATCH
115     esp_http_client_set_url(client, "http://httpbin.org/patch");
116     esp_http_client_set_method(client, HTTP_METHOD_PATCH);
117     esp_http_client_set_post_field(client, NULL, 0);
118     err = esp_http_client_perform(client);
119     if (err == ESP_OK) {
120         ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %d",
121                 esp_http_client_get_status_code(client),
122                 esp_http_client_get_content_length(client));
123     } else {
124         ESP_LOGE(TAG, "HTTP PATCH request failed: %s", esp_err_to_name(err));
125     }
126
127     //DELETE
128     esp_http_client_set_url(client, "http://httpbin.org/delete");
129     esp_http_client_set_method(client, HTTP_METHOD_DELETE);
130     err = esp_http_client_perform(client);
131     if (err == ESP_OK) {
132         ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %d",
133                 esp_http_client_get_status_code(client),
134                 esp_http_client_get_content_length(client));
135     } else {
136         ESP_LOGE(TAG, "HTTP DELETE request failed: %s", esp_err_to_name(err));
137     }
138
139     esp_http_client_cleanup(client);
140 }
141
142 static void http_auth_basic()
143 {
144     esp_http_client_config_t config = {
145         .url = "http://user:passwd@httpbin.org/basic-auth/user/passwd",
146         .event_handler = _http_event_handler,
147         .auth_type = HTTP_AUTH_TYPE_BASIC,
148     };
149     esp_http_client_handle_t client = esp_http_client_init(&config);
150     esp_err_t err = esp_http_client_perform(client);
151
152     if (err == ESP_OK) {
153         ESP_LOGI(TAG, "HTTP Basic Auth Status = %d, content_length = %d",
154                 esp_http_client_get_status_code(client),
155                 esp_http_client_get_content_length(client));
156     } else {
157         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
158     }
159     esp_http_client_cleanup(client);
160 }
161
162 static void http_auth_basic_redirect()
163 {
164     esp_http_client_config_t config = {
165         .url = "http://user:passwd@httpbin.org/basic-auth/user/passwd",
166         .event_handler = _http_event_handler,
167     };
168     esp_http_client_handle_t client = esp_http_client_init(&config);
169     esp_err_t err = esp_http_client_perform(client);
170
171     if (err == ESP_OK) {
172         ESP_LOGI(TAG, "HTTP Basic Auth redirect Status = %d, content_length = %d",
173                 esp_http_client_get_status_code(client),
174                 esp_http_client_get_content_length(client));
175     } else {
176         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
177     }
178     esp_http_client_cleanup(client);
179 }
180
181 static void http_auth_digest()
182 {
183     esp_http_client_config_t config = {
184         .url = "http://user:passwd@httpbin.org/digest-auth/auth/user/passwd/MD5/never",
185         .event_handler = _http_event_handler,
186     };
187     esp_http_client_handle_t client = esp_http_client_init(&config);
188     esp_err_t err = esp_http_client_perform(client);
189
190     if (err == ESP_OK) {
191         ESP_LOGI(TAG, "HTTP Digest Auth Status = %d, content_length = %d",
192                 esp_http_client_get_status_code(client),
193                 esp_http_client_get_content_length(client));
194     } else {
195         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
196     }
197     esp_http_client_cleanup(client);
198 }
199
200 static void https()
201 {
202     esp_http_client_config_t config = {
203         .url = "https://www.howsmyssl.com",
204         .event_handler = _http_event_handler,
205         .cert_pem = howsmyssl_com_root_cert_pem_start,
206     };
207     esp_http_client_handle_t client = esp_http_client_init(&config);
208     esp_err_t err = esp_http_client_perform(client);
209
210     if (err == ESP_OK) {
211         ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %d",
212                 esp_http_client_get_status_code(client),
213                 esp_http_client_get_content_length(client));
214     } else {
215         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
216     }
217     esp_http_client_cleanup(client);
218 }
219
220 static void http_relative_redirect()
221 {
222     esp_http_client_config_t config = {
223         .url = "http://httpbin.org/relative-redirect/3",
224         .event_handler = _http_event_handler,
225     };
226     esp_http_client_handle_t client = esp_http_client_init(&config);
227     esp_err_t err = esp_http_client_perform(client);
228
229     if (err == ESP_OK) {
230         ESP_LOGI(TAG, "HTTP Relative path redirect Status = %d, content_length = %d",
231                 esp_http_client_get_status_code(client),
232                 esp_http_client_get_content_length(client));
233     } else {
234         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
235     }
236     esp_http_client_cleanup(client);
237 }
238
239 static void http_absolute_redirect()
240 {
241     esp_http_client_config_t config = {
242         .url = "http://httpbin.org/absolute-redirect/3",
243         .event_handler = _http_event_handler,
244     };
245     esp_http_client_handle_t client = esp_http_client_init(&config);
246     esp_err_t err = esp_http_client_perform(client);
247
248     if (err == ESP_OK) {
249         ESP_LOGI(TAG, "HTTP Absolute path redirect Status = %d, content_length = %d",
250                 esp_http_client_get_status_code(client),
251                 esp_http_client_get_content_length(client));
252     } else {
253         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
254     }
255     esp_http_client_cleanup(client);
256 }
257
258 static void http_redirect_to_https()
259 {
260     esp_http_client_config_t config = {
261         .url = "http://httpbin.org/redirect-to?url=https%3A%2F%2Fwww.howsmyssl.com",
262         .event_handler = _http_event_handler,
263     };
264     esp_http_client_handle_t client = esp_http_client_init(&config);
265     esp_err_t err = esp_http_client_perform(client);
266
267     if (err == ESP_OK) {
268         ESP_LOGI(TAG, "HTTP redirect to HTTPS Status = %d, content_length = %d",
269                 esp_http_client_get_status_code(client),
270                 esp_http_client_get_content_length(client));
271     } else {
272         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
273     }
274     esp_http_client_cleanup(client);
275 }
276
277
278 static void http_download_chunk()
279 {
280     esp_http_client_config_t config = {
281         .url = "http://httpbin.org/stream-bytes/8912",
282         .event_handler = _http_event_handler,
283     };
284     esp_http_client_handle_t client = esp_http_client_init(&config);
285     esp_err_t err = esp_http_client_perform(client);
286
287     if (err == ESP_OK) {
288         ESP_LOGI(TAG, "HTTP chunk encoding Status = %d, content_length = %d",
289                 esp_http_client_get_status_code(client),
290                 esp_http_client_get_content_length(client));
291     } else {
292         ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
293     }
294     esp_http_client_cleanup(client);
295 }
296
297 static void http_perform_as_stream_reader()
298 {
299     char *buffer = malloc(MAX_HTTP_RECV_BUFFER + 1);
300     if (buffer == NULL) {
301         ESP_LOGE(TAG, "Cannot malloc http receive buffer");
302         return;
303     }
304     esp_http_client_config_t config = {
305         .url = "http://httpbin.org/get",
306         .event_handler = _http_event_handler,
307     };
308     esp_http_client_handle_t client = esp_http_client_init(&config);
309     esp_err_t err;
310     if ((err = esp_http_client_open(client, 0)) != ESP_OK) {
311         ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
312         free(buffer);
313         return;
314     }
315     int content_length =  esp_http_client_fetch_headers(client);
316     int total_read_len = 0, read_len;
317     if (total_read_len < content_length && content_length <= MAX_HTTP_RECV_BUFFER) {
318         read_len = esp_http_client_read(client, buffer, content_length);
319         if (read_len <= 0) {
320             ESP_LOGE(TAG, "Error read data");
321         }
322         buffer[read_len] = 0;
323         ESP_LOGD(TAG, "read_len = %d", read_len);
324     }
325     ESP_LOGI(TAG, "HTTP Stream reader Status = %d, content_length = %d",
326                     esp_http_client_get_status_code(client),
327                     esp_http_client_get_content_length(client));
328     esp_http_client_close(client);
329     esp_http_client_cleanup(client);
330     free(buffer);
331 }
332
333 static void http_test_task(void *pvParameters)
334 {
335     app_wifi_wait_connected();
336     ESP_LOGI(TAG, "Connected to AP, begin http example");
337     http_rest();
338     http_auth_basic();
339     http_auth_basic_redirect();
340     http_auth_digest();
341     http_relative_redirect();
342     http_absolute_redirect();
343     https();
344     http_redirect_to_https();
345     http_download_chunk();
346     http_perform_as_stream_reader();
347     ESP_LOGI(TAG, "Finish http example");
348     vTaskDelete(NULL);
349 }
350
351 void app_main()
352 {
353     esp_err_t ret = nvs_flash_init();
354     if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
355       ESP_ERROR_CHECK(nvs_flash_erase());
356       ret = nvs_flash_init();
357     }
358     ESP_ERROR_CHECK(ret);
359     app_wifi_initialise();
360
361     xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL);
362 }