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