1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _ESP_HTTP_CLIENT_H
8 #define _ESP_HTTP_CLIENT_H
9 
10 #include "freertos/FreeRTOS.h"
11 #include "http_parser.h"
12 #include "sdkconfig.h"
13 #include "esp_err.h"
14 #include <sys/socket.h>
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #define DEFAULT_HTTP_BUF_SIZE (512)
21 
22 typedef struct esp_http_client *esp_http_client_handle_t;
23 typedef struct esp_http_client_event *esp_http_client_event_handle_t;
24 
25 /**
26  * @brief   HTTP Client events id
27  */
28 typedef enum {
29     HTTP_EVENT_ERROR = 0,       /*!< This event occurs when there are any errors during execution */
30     HTTP_EVENT_ON_CONNECTED,    /*!< Once the HTTP has been connected to the server, no data exchange has been performed */
31     HTTP_EVENT_HEADERS_SENT,     /*!< After sending all the headers to the server */
32     HTTP_EVENT_HEADER_SENT = HTTP_EVENT_HEADERS_SENT, /*!< This header has been kept for backward compatability
33                                                            and will be deprecated in future versions esp-idf */
34     HTTP_EVENT_ON_HEADER,       /*!< Occurs when receiving each header sent from the server */
35     HTTP_EVENT_ON_DATA,         /*!< Occurs when receiving data from the server, possibly multiple portions of the packet */
36     HTTP_EVENT_ON_FINISH,       /*!< Occurs when finish a HTTP session */
37     HTTP_EVENT_DISCONNECTED,    /*!< The connection has been disconnected */
38 } esp_http_client_event_id_t;
39 
40 /**
41  * @brief      HTTP Client events data
42  */
43 typedef struct esp_http_client_event {
44     esp_http_client_event_id_t event_id;    /*!< event_id, to know the cause of the event */
45     esp_http_client_handle_t client;        /*!< esp_http_client_handle_t context */
46     void *data;                             /*!< data of the event */
47     int data_len;                           /*!< data length of data */
48     void *user_data;                        /*!< user_data context, from esp_http_client_config_t user_data */
49     char *header_key;                       /*!< For HTTP_EVENT_ON_HEADER event_id, it's store current http header key */
50     char *header_value;                     /*!< For HTTP_EVENT_ON_HEADER event_id, it's store current http header value */
51 } esp_http_client_event_t;
52 
53 
54 /**
55  * @brief      HTTP Client transport
56  */
57 typedef enum {
58     HTTP_TRANSPORT_UNKNOWN = 0x0,   /*!< Unknown */
59     HTTP_TRANSPORT_OVER_TCP,        /*!< Transport over tcp */
60     HTTP_TRANSPORT_OVER_SSL,        /*!< Transport over ssl */
61 } esp_http_client_transport_t;
62 
63 typedef esp_err_t (*http_event_handle_cb)(esp_http_client_event_t *evt);
64 
65 /**
66  * @brief HTTP method
67  */
68 typedef enum {
69     HTTP_METHOD_GET = 0,    /*!< HTTP GET Method */
70     HTTP_METHOD_POST,       /*!< HTTP POST Method */
71     HTTP_METHOD_PUT,        /*!< HTTP PUT Method */
72     HTTP_METHOD_PATCH,      /*!< HTTP PATCH Method */
73     HTTP_METHOD_DELETE,     /*!< HTTP DELETE Method */
74     HTTP_METHOD_HEAD,       /*!< HTTP HEAD Method */
75     HTTP_METHOD_NOTIFY,     /*!< HTTP NOTIFY Method */
76     HTTP_METHOD_SUBSCRIBE,  /*!< HTTP SUBSCRIBE Method */
77     HTTP_METHOD_UNSUBSCRIBE,/*!< HTTP UNSUBSCRIBE Method */
78     HTTP_METHOD_OPTIONS,    /*!< HTTP OPTIONS Method */
79     HTTP_METHOD_COPY,       /*!< HTTP COPY Method */
80     HTTP_METHOD_MOVE,       /*!< HTTP MOVE Method */
81     HTTP_METHOD_LOCK,       /*!< HTTP LOCK Method */
82     HTTP_METHOD_UNLOCK,     /*!< HTTP UNLOCK Method */
83     HTTP_METHOD_PROPFIND,   /*!< HTTP PROPFIND Method */
84     HTTP_METHOD_PROPPATCH,  /*!< HTTP PROPPATCH Method */
85     HTTP_METHOD_MKCOL,      /*!< HTTP MKCOL Method */
86     HTTP_METHOD_MAX,
87 } esp_http_client_method_t;
88 
89 /**
90  * @brief HTTP Authentication type
91  */
92 typedef enum {
93     HTTP_AUTH_TYPE_NONE = 0,    /*!< No authention */
94     HTTP_AUTH_TYPE_BASIC,       /*!< HTTP Basic authentication */
95     HTTP_AUTH_TYPE_DIGEST,      /*!< HTTP Disgest authentication */
96 } esp_http_client_auth_type_t;
97 
98 /**
99  * @brief HTTP configuration
100  */
101 typedef struct {
102     const char                  *url;                /*!< HTTP URL, the information on the URL is most important, it overrides the other fields below, if any */
103     const char                  *host;               /*!< Domain or IP as string */
104     int                         port;                /*!< Port to connect, default depend on esp_http_client_transport_t (80 or 443) */
105     const char                  *username;           /*!< Using for Http authentication */
106     const char                  *password;           /*!< Using for Http authentication */
107     esp_http_client_auth_type_t auth_type;           /*!< Http authentication type, see `esp_http_client_auth_type_t` */
108     const char                  *path;               /*!< HTTP Path, if not set, default is `/` */
109     const char                  *query;              /*!< HTTP query */
110     const char                  *cert_pem;           /*!< SSL server certification, PEM format as string, if the client requires to verify server */
111     size_t                      cert_len;            /*!< Length of the buffer pointed to by cert_pem. May be 0 for null-terminated pem */
112     const char                  *client_cert_pem;    /*!< SSL client certification, PEM format as string, if the server requires to verify client */
113     size_t                      client_cert_len;     /*!< Length of the buffer pointed to by client_cert_pem. May be 0 for null-terminated pem */
114     const char                  *client_key_pem;     /*!< SSL client key, PEM format as string, if the server requires to verify client */
115     size_t                      client_key_len;      /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */
116     const char                  *client_key_password;      /*!< Client key decryption password string */
117     size_t                      client_key_password_len;   /*!< String length of the password pointed to by client_key_password */
118     const char                  *user_agent;         /*!< The User Agent string to send with HTTP requests */
119     esp_http_client_method_t    method;                   /*!< HTTP Method */
120     int                         timeout_ms;               /*!< Network timeout in milliseconds */
121     bool                        disable_auto_redirect;    /*!< Disable HTTP automatic redirects */
122     int                         max_redirection_count;    /*!< Max number of redirections on receiving HTTP redirect status code, using default value if zero*/
123     int                         max_authorization_retries;    /*!< Max connection retries on receiving HTTP unauthorized status code, using default value if zero. Disables authorization retry if -1*/
124     http_event_handle_cb        event_handler;             /*!< HTTP Event Handle */
125     esp_http_client_transport_t transport_type;           /*!< HTTP transport type, see `esp_http_client_transport_t` */
126     int                         buffer_size;              /*!< HTTP receive buffer size */
127     int                         buffer_size_tx;           /*!< HTTP transmit buffer size */
128     void                        *user_data;               /*!< HTTP user_data context */
129     bool                        is_async;                 /*!< Set asynchronous mode, only supported with HTTPS for now */
130     bool                        use_global_ca_store;      /*!< Use a global ca_store for all the connections in which this bool is set. */
131     bool                        skip_cert_common_name_check;    /*!< Skip any validation of server certificate CN field */
132     esp_err_t (*crt_bundle_attach)(void *conf);      /*!< Function pointer to esp_crt_bundle_attach. Enables the use of certification
133                                                           bundle for server verification, must be enabled in menuconfig */
134     bool                        keep_alive_enable;   /*!< Enable keep-alive timeout */
135     int                         keep_alive_idle;     /*!< Keep-alive idle time. Default is 5 (second) */
136     int                         keep_alive_interval; /*!< Keep-alive interval time. Default is 5 (second) */
137     int                         keep_alive_count;    /*!< Keep-alive packet retry send count. Default is 3 counts */
138     struct ifreq                *if_name;            /*!< The name of interface for data to go through. Use the default interface without setting */
139 } esp_http_client_config_t;
140 
141 /**
142  * Enum for the HTTP status codes.
143  */
144 typedef enum {
145     /* 2xx - Success */
146     HttpStatus_Ok                = 200,
147 
148     /* 3xx - Redirection */
149     HttpStatus_MultipleChoices   = 300,
150     HttpStatus_MovedPermanently  = 301,
151     HttpStatus_Found             = 302,
152     HttpStatus_TemporaryRedirect = 307,
153 
154     /* 4xx - Client Error */
155     HttpStatus_BadRequest        = 400,
156     HttpStatus_Unauthorized      = 401,
157     HttpStatus_Forbidden         = 403,
158     HttpStatus_NotFound          = 404,
159 
160     /* 5xx - Server Error */
161     HttpStatus_InternalError     = 500
162 } HttpStatus_Code;
163 
164 #define ESP_ERR_HTTP_BASE               (0x7000)                    /*!< Starting number of HTTP error codes */
165 #define ESP_ERR_HTTP_MAX_REDIRECT       (ESP_ERR_HTTP_BASE + 1)     /*!< The error exceeds the number of HTTP redirects */
166 #define ESP_ERR_HTTP_CONNECT            (ESP_ERR_HTTP_BASE + 2)     /*!< Error open the HTTP connection */
167 #define ESP_ERR_HTTP_WRITE_DATA         (ESP_ERR_HTTP_BASE + 3)     /*!< Error write HTTP data */
168 #define ESP_ERR_HTTP_FETCH_HEADER       (ESP_ERR_HTTP_BASE + 4)     /*!< Error read HTTP header from server */
169 #define ESP_ERR_HTTP_INVALID_TRANSPORT  (ESP_ERR_HTTP_BASE + 5)     /*!< There are no transport support for the input scheme */
170 #define ESP_ERR_HTTP_CONNECTING         (ESP_ERR_HTTP_BASE + 6)     /*!< HTTP connection hasn't been established yet */
171 #define ESP_ERR_HTTP_EAGAIN             (ESP_ERR_HTTP_BASE + 7)     /*!< Mapping of errno EAGAIN to esp_err_t */
172 #define ESP_ERR_HTTP_CONNECTION_CLOSED  (ESP_ERR_HTTP_BASE + 8)     /*!< Read FIN from peer and the connection closed */
173 
174 /**
175  * @brief      Start a HTTP session
176  *             This function must be the first function to call,
177  *             and it returns a esp_http_client_handle_t that you must use as input to other functions in the interface.
178  *             This call MUST have a corresponding call to esp_http_client_cleanup when the operation is complete.
179  *
180  * @param[in]  config   The configurations, see `http_client_config_t`
181  *
182  * @return
183  *     - `esp_http_client_handle_t`
184  *     - NULL if any errors
185  */
186 esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config);
187 
188 /**
189  * @brief      Invoke this function after `esp_http_client_init` and all the options calls are made, and will perform the
190  *             transfer as described in the options. It must be called with the same esp_http_client_handle_t as input as the esp_http_client_init call returned.
191  *             esp_http_client_perform performs the entire request in either blocking or non-blocking manner. By default, the API performs request in a blocking manner and returns when done,
192  *             or if it failed, and in non-blocking manner, it returns if EAGAIN/EWOULDBLOCK or EINPROGRESS is encountered, or if it failed. And in case of non-blocking request,
193  *             the user may call this API multiple times unless request & response is complete or there is a failure. To enable non-blocking esp_http_client_perform(), `is_async` member of esp_http_client_config_t
194  *             must be set while making a call to esp_http_client_init() API.
195  *             You can do any amount of calls to esp_http_client_perform while using the same esp_http_client_handle_t. The underlying connection may be kept open if the server allows it.
196  *             If you intend to transfer more than one file, you are even encouraged to do so.
197  *             esp_http_client will then attempt to re-use the same connection for the following transfers, thus making the operations faster, less CPU intense and using less network resources.
198  *             Just note that you will have to use `esp_http_client_set_**` between the invokes to set options for the following esp_http_client_perform.
199  *
200  * @note       You must never call this function simultaneously from two places using the same client handle.
201  *             Let the function return first before invoking it another time.
202  *             If you want parallel transfers, you must use several esp_http_client_handle_t.
203  *             This function include `esp_http_client_open` -> `esp_http_client_write` -> `esp_http_client_fetch_headers` -> `esp_http_client_read` (and option) `esp_http_client_close`.
204  *
205  * @param      client  The esp_http_client handle
206  *
207  * @return
208  *  - ESP_OK on successful
209  *  - ESP_FAIL on error
210  */
211 esp_err_t esp_http_client_perform(esp_http_client_handle_t client);
212 
213 /**
214  * @brief      Set URL for client, when performing this behavior, the options in the URL will replace the old ones
215  *
216  * @param[in]  client  The esp_http_client handle
217  * @param[in]  url     The url
218  *
219  * @return
220  *  - ESP_OK
221  *  - ESP_FAIL
222  */
223 esp_err_t esp_http_client_set_url(esp_http_client_handle_t client, const char *url);
224 
225 /**
226  * @brief      Set post data, this function must be called before `esp_http_client_perform`.
227  *             Note: The data parameter passed to this function is a pointer and this function will not copy the data
228  *
229  * @param[in]  client  The esp_http_client handle
230  * @param[in]  data    post data pointer
231  * @param[in]  len     post length
232  *
233  * @return
234  *  - ESP_OK
235  *  - ESP_FAIL
236  */
237 esp_err_t esp_http_client_set_post_field(esp_http_client_handle_t client, const char *data, int len);
238 
239 /**
240  * @brief      Get current post field information
241  *
242  * @param[in]  client  The client
243  * @param[out] data    Point to post data pointer
244  *
245  * @return     Size of post data
246  */
247 int esp_http_client_get_post_field(esp_http_client_handle_t client, char **data);
248 
249 /**
250  * @brief      Set http request header, this function must be called after esp_http_client_init and before any
251  *             perform function
252  *
253  * @param[in]  client  The esp_http_client handle
254  * @param[in]  key     The header key
255  * @param[in]  value   The header value
256  *
257  * @return
258  *  - ESP_OK
259  *  - ESP_FAIL
260  */
261 esp_err_t esp_http_client_set_header(esp_http_client_handle_t client, const char *key, const char *value);
262 
263 /**
264  * @brief      Get http request header.
265  *             The value parameter will be set to NULL if there is no header which is same as
266  *             the key specified, otherwise the address of header value will be assigned to value parameter.
267  *             This function must be called after `esp_http_client_init`.
268  *
269  * @param[in]  client  The esp_http_client handle
270  * @param[in]  key     The header key
271  * @param[out] value   The header value
272  *
273  * @return
274  *     - ESP_OK
275  *     - ESP_FAIL
276  */
277 esp_err_t esp_http_client_get_header(esp_http_client_handle_t client, const char *key, char **value);
278 
279 /**
280  * @brief      Get http request username.
281  *             The address of username buffer will be assigned to value parameter.
282  *             This function must be called after `esp_http_client_init`.
283  *
284  * @param[in]  client  The esp_http_client handle
285  * @param[out] value   The username value
286  *
287  * @return
288  *     - ESP_OK
289  *     - ESP_ERR_INVALID_ARG
290  */
291 esp_err_t esp_http_client_get_username(esp_http_client_handle_t client, char **value);
292 
293 /**
294  * @brief      Set http request username.
295  *             The value of username parameter will be assigned to username buffer.
296  *             If the username parameter is NULL then username buffer will be freed.
297  *
298  * @param[in]  client    The esp_http_client handle
299  * @param[in]  username  The username value
300  *
301  * @return
302  *     - ESP_OK
303  *     - ESP_ERR_INVALID_ARG
304  */
305 esp_err_t esp_http_client_set_username(esp_http_client_handle_t client, const char *username);
306 
307 /**
308  * @brief      Get http request password.
309  *             The address of password buffer will be assigned to value parameter.
310  *             This function must be called after `esp_http_client_init`.
311  *
312  * @param[in]  client  The esp_http_client handle
313  * @param[out] value   The password value
314  *
315  * @return
316  *     - ESP_OK
317  *     - ESP_ERR_INVALID_ARG
318  */
319 esp_err_t esp_http_client_get_password(esp_http_client_handle_t client, char **value);
320 
321 /**
322  * @brief      Set http request password.
323  *             The value of password parameter will be assigned to password buffer.
324  *             If the password parameter is NULL then password buffer will be freed.
325  *
326  * @param[in]  client    The esp_http_client handle
327  * @param[in]  password  The password value
328  *
329  * @return
330  *     - ESP_OK
331  *     - ESP_ERR_INVALID_ARG
332  */
333 esp_err_t esp_http_client_set_password(esp_http_client_handle_t client, const char *password);
334 
335 /**
336  * @brief      Set http request auth_type.
337  *
338  * @param[in]  client    The esp_http_client handle
339  * @param[in]  auth_type The esp_http_client auth type
340  *
341  * @return
342  *     - ESP_OK
343  *     - ESP_ERR_INVALID_ARG
344  */
345 esp_err_t esp_http_client_set_authtype(esp_http_client_handle_t client, esp_http_client_auth_type_t auth_type);
346 
347 /**
348  * @brief      Get HTTP client session errno
349  *
350  * @param[in]  client  The esp_http_client handle
351  *
352  * @return
353  *         - (-1) if invalid argument
354  *         - errno
355  */
356 int esp_http_client_get_errno(esp_http_client_handle_t client);
357 
358 /**
359  * @brief      Set http request method
360  *
361  * @param[in]  client  The esp_http_client handle
362  * @param[in]  method  The method
363  *
364  * @return
365  *     - ESP_OK
366  *     - ESP_ERR_INVALID_ARG
367  */
368 esp_err_t esp_http_client_set_method(esp_http_client_handle_t client, esp_http_client_method_t method);
369 
370 /**
371  * @brief      Set http request timeout
372  *
373  * @param[in]  client      The esp_http_client handle
374  * @param[in]  timeout_ms  The timeout value
375  *
376  * @return
377  *     - ESP_OK
378  *     - ESP_ERR_INVALID_ARG
379  */
380 esp_err_t esp_http_client_set_timeout_ms(esp_http_client_handle_t client, int timeout_ms);
381 
382 /**
383  * @brief      Delete http request header
384  *
385  * @param[in]  client  The esp_http_client handle
386  * @param[in]  key     The key
387  *
388  * @return
389  *  - ESP_OK
390  *  - ESP_FAIL
391  */
392 esp_err_t esp_http_client_delete_header(esp_http_client_handle_t client, const char *key);
393 
394 /**
395  * @brief      This function will be open the connection, write all header strings and return
396  *
397  * @param[in]  client     The esp_http_client handle
398  * @param[in]  write_len  HTTP Content length need to write to the server
399  *
400  * @return
401  *  - ESP_OK
402  *  - ESP_FAIL
403  */
404 esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len);
405 
406 /**
407  * @brief     This function will write data to the HTTP connection previously opened by esp_http_client_open()
408  *
409  * @param[in]  client  The esp_http_client handle
410  * @param      buffer  The buffer
411  * @param[in]  len     This value must not be larger than the write_len parameter provided to esp_http_client_open()
412  *
413  * @return
414  *     - (-1) if any errors
415  *     - Length of data written
416  */
417 int esp_http_client_write(esp_http_client_handle_t client, const char *buffer, int len);
418 
419 /**
420  * @brief      This function need to call after esp_http_client_open, it will read from http stream, process all receive headers
421  *
422  * @param[in]  client  The esp_http_client handle
423  *
424  * @return
425  *     - (0) if stream doesn't contain content-length header, or chunked encoding (checked by `esp_http_client_is_chunked` response)
426  *     - (-1: ESP_FAIL) if any errors
427  *     - Download data length defined by content-length header
428  */
429 int esp_http_client_fetch_headers(esp_http_client_handle_t client);
430 
431 
432 /**
433  * @brief      Check response data is chunked
434  *
435  * @param[in]  client  The esp_http_client handle
436  *
437  * @return     true or false
438  */
439 bool esp_http_client_is_chunked_response(esp_http_client_handle_t client);
440 
441 /**
442  * @brief      Read data from http stream
443  *
444  * @param[in]  client  The esp_http_client handle
445  * @param      buffer  The buffer
446  * @param[in]  len     The length
447  *
448  * @return
449  *     - (-1) if any errors
450  *     - Length of data was read
451  */
452 int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len);
453 
454 
455 /**
456  * @brief      Get http response status code, the valid value if this function invoke after `esp_http_client_perform`
457  *
458  * @param[in]  client  The esp_http_client handle
459  *
460  * @return     Status code
461  */
462 int esp_http_client_get_status_code(esp_http_client_handle_t client);
463 
464 /**
465  * @brief      Get http response content length (from header Content-Length)
466  *             the valid value if this function invoke after `esp_http_client_perform`
467  *
468  * @param[in]  client  The esp_http_client handle
469  *
470  * @return
471  *     - (-1) Chunked transfer
472  *     - Content-Length value as bytes
473  */
474 int esp_http_client_get_content_length(esp_http_client_handle_t client);
475 
476 /**
477  * @brief      Close http connection, still kept all http request resources
478  *
479  * @param[in]  client  The esp_http_client handle
480  *
481  * @return
482  *     - ESP_OK
483  *     - ESP_FAIL
484  */
485 esp_err_t esp_http_client_close(esp_http_client_handle_t client);
486 
487 /**
488  * @brief      This function must be the last function to call for an session.
489  *             It is the opposite of the esp_http_client_init function and must be called with the same handle as input that a esp_http_client_init call returned.
490  *             This might close all connections this handle has used and possibly has kept open until now.
491  *             Don't call this function if you intend to transfer more files, re-using handles is a key to good performance with esp_http_client.
492  *
493  * @param[in]  client  The esp_http_client handle
494  *
495  * @return
496  *     - ESP_OK
497  *     - ESP_FAIL
498  */
499 esp_err_t esp_http_client_cleanup(esp_http_client_handle_t client);
500 
501 /**
502  * @brief      Get transport type
503  *
504  * @param[in]  client   The esp_http_client handle
505  *
506  * @return
507  *     - HTTP_TRANSPORT_UNKNOWN
508  *     - HTTP_TRANSPORT_OVER_TCP
509  *     - HTTP_TRANSPORT_OVER_SSL
510  */
511 esp_http_client_transport_t esp_http_client_get_transport_type(esp_http_client_handle_t client);
512 
513 /**
514  * @brief      Set redirection URL.
515  *             When received the 30x code from the server, the client stores the redirect URL provided by the server.
516  *             This function will set the current URL to redirect to enable client to execute the redirection request.
517  *
518  * @param[in]  client  The esp_http_client handle
519  *
520  * @return
521  *     - ESP_OK
522  *     - ESP_FAIL
523  */
524 esp_err_t esp_http_client_set_redirection(esp_http_client_handle_t client);
525 
526 /**
527  * @brief      On receiving HTTP Status code 401, this API can be invoked to add authorization
528  *             information.
529  *
530  * @note       There is a possibility of receiving body message with redirection status codes, thus make sure
531  *             to flush off body data after calling this API.
532  *
533  * @param[in]  client   The esp_http_client handle
534  */
535 void esp_http_client_add_auth(esp_http_client_handle_t client);
536 
537 /**
538  * @brief      Checks if entire data in the response has been read without any error.
539  *
540  * @param[in]  client   The esp_http_client handle
541  *
542  * @return
543  *     - true
544  *     - false
545  */
546 bool esp_http_client_is_complete_data_received(esp_http_client_handle_t client);
547 
548 /**
549  * @brief      Helper API to read larger data chunks
550  *             This is a helper API which internally calls `esp_http_client_read` multiple times till the end of data is reached or till the buffer gets full.
551  *
552  * @param[in]  client   The esp_http_client handle
553  * @param      buffer   The buffer
554  * @param[in]  len      The buffer length
555  *
556  * @return
557  *     - Length of data was read
558  */
559 
560 int esp_http_client_read_response(esp_http_client_handle_t client, char *buffer, int len);
561 
562 /**
563  * @brief       Process all remaining response data
564  *              This uses an internal buffer to repeatedly receive, parse, and discard response data until complete data is processed.
565  *              As no additional user-supplied buffer is required, this may be preferrable to `esp_http_client_read_response` in situations where the content of the response may be ignored.
566  *
567  * @param[in]  client  The esp_http_client handle
568  * @param      len     Length of data discarded
569  *
570  * @return
571  *     - ESP_OK                 If successful, len will have discarded length
572  *     - ESP_FAIL               If failed to read response
573  *     - ESP_ERR_INVALID_ARG    If the client is NULL
574  */
575 esp_err_t esp_http_client_flush_response(esp_http_client_handle_t client, int *len);
576 
577 /**
578  * @brief          Get URL from client
579  *
580  * @param[in]      client   The esp_http_client handle
581  * @param[inout]   url      The buffer to store URL
582  * @param[in]      len      The buffer length
583  *
584  * @return
585  *     - ESP_OK
586  *     - ESP_FAIL
587  */
588 
589 esp_err_t esp_http_client_get_url(esp_http_client_handle_t client, char *url, const int len);
590 
591 /**
592  * @brief          Get Chunk-Length from client
593  *
594  * @param[in]      client   The esp_http_client handle
595  * @param[out]     len      Variable to store length
596  *
597  * @return
598  *     - ESP_OK                 If successful, len will have length of current chunk
599  *     - ESP_FAIL               If the server is not a chunked server
600  *     - ESP_ERR_INVALID_ARG    If the client or len are NULL
601  */
602 esp_err_t esp_http_client_get_chunk_length(esp_http_client_handle_t client, int *len);
603 
604 #ifdef __cplusplus
605 }
606 #endif
607 
608 
609 #endif
610