esp_http_server.h 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. // Copyright 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. #ifndef _ESP_HTTP_SERVER_H_
  15. #define _ESP_HTTP_SERVER_H_
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <freertos/FreeRTOS.h>
  19. #include <freertos/task.h>
  20. #include <http_parser.h>
  21. #include <sdkconfig.h>
  22. #include <esp_err.h>
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. /*
  27. note: esp_https_server.h includes a customized copy of this
  28. initializer that should be kept in sync
  29. */
  30. #define HTTPD_DEFAULT_CONFIG() { \
  31. .task_priority = tskIDLE_PRIORITY+5, \
  32. .stack_size = 4096, \
  33. .core_id = tskNO_AFFINITY, \
  34. .server_port = 80, \
  35. .ctrl_port = 32768, \
  36. .max_open_sockets = 7, \
  37. .max_uri_handlers = 8, \
  38. .max_resp_headers = 8, \
  39. .backlog_conn = 5, \
  40. .lru_purge_enable = false, \
  41. .recv_wait_timeout = 5, \
  42. .send_wait_timeout = 5, \
  43. .global_user_ctx = NULL, \
  44. .global_user_ctx_free_fn = NULL, \
  45. .global_transport_ctx = NULL, \
  46. .global_transport_ctx_free_fn = NULL, \
  47. .open_fn = NULL, \
  48. .close_fn = NULL, \
  49. .uri_match_fn = NULL \
  50. }
  51. #define ESP_ERR_HTTPD_BASE (0x8000) /*!< Starting number of HTTPD error codes */
  52. #define ESP_ERR_HTTPD_HANDLERS_FULL (ESP_ERR_HTTPD_BASE + 1) /*!< All slots for registering URI handlers have been consumed */
  53. #define ESP_ERR_HTTPD_HANDLER_EXISTS (ESP_ERR_HTTPD_BASE + 2) /*!< URI handler with same method and target URI already registered */
  54. #define ESP_ERR_HTTPD_INVALID_REQ (ESP_ERR_HTTPD_BASE + 3) /*!< Invalid request pointer */
  55. #define ESP_ERR_HTTPD_RESULT_TRUNC (ESP_ERR_HTTPD_BASE + 4) /*!< Result string truncated */
  56. #define ESP_ERR_HTTPD_RESP_HDR (ESP_ERR_HTTPD_BASE + 5) /*!< Response header field larger than supported */
  57. #define ESP_ERR_HTTPD_RESP_SEND (ESP_ERR_HTTPD_BASE + 6) /*!< Error occured while sending response packet */
  58. #define ESP_ERR_HTTPD_ALLOC_MEM (ESP_ERR_HTTPD_BASE + 7) /*!< Failed to dynamically allocate memory for resource */
  59. #define ESP_ERR_HTTPD_TASK (ESP_ERR_HTTPD_BASE + 8) /*!< Failed to launch server task/thread */
  60. /* Symbol to be used as length parameter in httpd_resp_send APIs
  61. * for setting buffer length to string length */
  62. #define HTTPD_RESP_USE_STRLEN -1
  63. /* ************** Group: Initialization ************** */
  64. /** @name Initialization
  65. * APIs related to the Initialization of the web server
  66. * @{
  67. */
  68. /**
  69. * @brief HTTP Server Instance Handle
  70. *
  71. * Every instance of the server will have a unique handle.
  72. */
  73. typedef void* httpd_handle_t;
  74. /**
  75. * @brief HTTP Method Type wrapper over "enum http_method"
  76. * available in "http_parser" library
  77. */
  78. typedef enum http_method httpd_method_t;
  79. /**
  80. * @brief Prototype for freeing context data (if any)
  81. * @param[in] ctx object to free
  82. */
  83. typedef void (*httpd_free_ctx_fn_t)(void *ctx);
  84. /**
  85. * @brief Function prototype for opening a session.
  86. *
  87. * Called immediately after the socket was opened to set up the send/recv functions and
  88. * other parameters of the socket.
  89. *
  90. * @param[in] hd server instance
  91. * @param[in] sockfd session socket file descriptor
  92. * @return status
  93. */
  94. typedef esp_err_t (*httpd_open_func_t)(httpd_handle_t hd, int sockfd);
  95. /**
  96. * @brief Function prototype for closing a session.
  97. *
  98. * @note It's possible that the socket descriptor is invalid at this point, the function
  99. * is called for all terminated sessions. Ensure proper handling of return codes.
  100. *
  101. * @param[in] hd server instance
  102. * @param[in] sockfd session socket file descriptor
  103. */
  104. typedef void (*httpd_close_func_t)(httpd_handle_t hd, int sockfd);
  105. /**
  106. * @brief Function prototype for URI matching.
  107. *
  108. * @param[in] reference_uri URI/template with respect to which the other URI is matched
  109. * @param[in] uri_to_match URI/template being matched to the reference URI/template
  110. * @param[in] match_upto For specifying the actual length of `uri_to_match` up to
  111. * which the matching algorithm is to be applied (The maximum
  112. * value is `strlen(uri_to_match)`, independent of the length
  113. * of `reference_uri`)
  114. * @return true on match
  115. */
  116. typedef bool (*httpd_uri_match_func_t)(const char *reference_uri,
  117. const char *uri_to_match,
  118. size_t match_upto);
  119. /**
  120. * @brief HTTP Server Configuration Structure
  121. *
  122. * @note Use HTTPD_DEFAULT_CONFIG() to initialize the configuration
  123. * to a default value and then modify only those fields that are
  124. * specifically determined by the use case.
  125. */
  126. typedef struct httpd_config {
  127. unsigned task_priority; /*!< Priority of FreeRTOS task which runs the server */
  128. size_t stack_size; /*!< The maximum stack size allowed for the server task */
  129. BaseType_t core_id; /*!< The core the HTTP server task will run on */
  130. /**
  131. * TCP Port number for receiving and transmitting HTTP traffic
  132. */
  133. uint16_t server_port;
  134. /**
  135. * UDP Port number for asynchronously exchanging control signals
  136. * between various components of the server
  137. */
  138. uint16_t ctrl_port;
  139. uint16_t max_open_sockets; /*!< Max number of sockets/clients connected at any time*/
  140. uint16_t max_uri_handlers; /*!< Maximum allowed uri handlers */
  141. uint16_t max_resp_headers; /*!< Maximum allowed additional headers in HTTP response */
  142. uint16_t backlog_conn; /*!< Number of backlog connections */
  143. bool lru_purge_enable; /*!< Purge "Least Recently Used" connection */
  144. uint16_t recv_wait_timeout; /*!< Timeout for recv function (in seconds)*/
  145. uint16_t send_wait_timeout; /*!< Timeout for send function (in seconds)*/
  146. /**
  147. * Global user context.
  148. *
  149. * This field can be used to store arbitrary user data within the server context.
  150. * The value can be retrieved using the server handle, available e.g. in the httpd_req_t struct.
  151. *
  152. * When shutting down, the server frees up the user context by
  153. * calling free() on the global_user_ctx field. If you wish to use a custom
  154. * function for freeing the global user context, please specify that here.
  155. */
  156. void * global_user_ctx;
  157. /**
  158. * Free function for global user context
  159. */
  160. httpd_free_ctx_fn_t global_user_ctx_free_fn;
  161. /**
  162. * Global transport context.
  163. *
  164. * Similar to global_user_ctx, but used for session encoding or encryption (e.g. to hold the SSL context).
  165. * It will be freed using free(), unless global_transport_ctx_free_fn is specified.
  166. */
  167. void * global_transport_ctx;
  168. /**
  169. * Free function for global transport context
  170. */
  171. httpd_free_ctx_fn_t global_transport_ctx_free_fn;
  172. /**
  173. * Custom session opening callback.
  174. *
  175. * Called on a new session socket just after accept(), but before reading any data.
  176. *
  177. * This is an opportunity to set up e.g. SSL encryption using global_transport_ctx
  178. * and the send/recv/pending session overrides.
  179. *
  180. * If a context needs to be maintained between these functions, store it in the session using
  181. * httpd_sess_set_transport_ctx() and retrieve it later with httpd_sess_get_transport_ctx()
  182. */
  183. httpd_open_func_t open_fn;
  184. /**
  185. * Custom session closing callback.
  186. *
  187. * Called when a session is deleted, before freeing user and transport contexts and before
  188. * closing the socket. This is a place for custom de-init code common to all sockets.
  189. *
  190. * Set the user or transport context to NULL if it was freed here, so the server does not
  191. * try to free it again.
  192. *
  193. * This function is run for all terminated sessions, including sessions where the socket
  194. * was closed by the network stack - that is, the file descriptor may not be valid anymore.
  195. */
  196. httpd_close_func_t close_fn;
  197. /**
  198. * URI matcher function.
  199. *
  200. * Called when searching for a matching URI:
  201. * 1) whose request handler is to be executed right
  202. * after an HTTP request is successfully parsed
  203. * 2) in order to prevent duplication while registering
  204. * a new URI handler using `httpd_register_uri_handler()`
  205. *
  206. * Available options are:
  207. * 1) NULL : Internally do basic matching using `strncmp()`
  208. * 2) `httpd_uri_match_wildcard()` : URI wildcard matcher
  209. *
  210. * Users can implement their own matching functions (See description
  211. * of the `httpd_uri_match_func_t` function prototype)
  212. */
  213. httpd_uri_match_func_t uri_match_fn;
  214. } httpd_config_t;
  215. /**
  216. * @brief Starts the web server
  217. *
  218. * Create an instance of HTTP server and allocate memory/resources for it
  219. * depending upon the specified configuration.
  220. *
  221. * Example usage:
  222. * @code{c}
  223. *
  224. * //Function for starting the webserver
  225. * httpd_handle_t start_webserver(void)
  226. * {
  227. * // Generate default configuration
  228. * httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  229. *
  230. * // Empty handle to http_server
  231. * httpd_handle_t server = NULL;
  232. *
  233. * // Start the httpd server
  234. * if (httpd_start(&server, &config) == ESP_OK) {
  235. * // Register URI handlers
  236. * httpd_register_uri_handler(server, &uri_get);
  237. * httpd_register_uri_handler(server, &uri_post);
  238. * }
  239. * // If server failed to start, handle will be NULL
  240. * return server;
  241. * }
  242. *
  243. * @endcode
  244. *
  245. * @param[in] config Configuration for new instance of the server
  246. * @param[out] handle Handle to newly created instance of the server. NULL on error
  247. * @return
  248. * - ESP_OK : Instance created successfully
  249. * - ESP_ERR_INVALID_ARG : Null argument(s)
  250. * - ESP_ERR_HTTPD_ALLOC_MEM : Failed to allocate memory for instance
  251. * - ESP_ERR_HTTPD_TASK : Failed to launch server task
  252. */
  253. esp_err_t httpd_start(httpd_handle_t *handle, const httpd_config_t *config);
  254. /**
  255. * @brief Stops the web server
  256. *
  257. * Deallocates memory/resources used by an HTTP server instance and
  258. * deletes it. Once deleted the handle can no longer be used for accessing
  259. * the instance.
  260. *
  261. * Example usage:
  262. * @code{c}
  263. *
  264. * // Function for stopping the webserver
  265. * void stop_webserver(httpd_handle_t server)
  266. * {
  267. * // Ensure handle is non NULL
  268. * if (server != NULL) {
  269. * // Stop the httpd server
  270. * httpd_stop(server);
  271. * }
  272. * }
  273. *
  274. * @endcode
  275. *
  276. * @param[in] handle Handle to server returned by httpd_start
  277. * @return
  278. * - ESP_OK : Server stopped successfully
  279. * - ESP_ERR_INVALID_ARG : Handle argument is Null
  280. */
  281. esp_err_t httpd_stop(httpd_handle_t handle);
  282. /** End of Group Initialization
  283. * @}
  284. */
  285. /* ************** Group: URI Handlers ************** */
  286. /** @name URI Handlers
  287. * APIs related to the URI handlers
  288. * @{
  289. */
  290. /* Max supported HTTP request header length */
  291. #define HTTPD_MAX_REQ_HDR_LEN CONFIG_HTTPD_MAX_REQ_HDR_LEN
  292. /* Max supported HTTP request URI length */
  293. #define HTTPD_MAX_URI_LEN CONFIG_HTTPD_MAX_URI_LEN
  294. /**
  295. * @brief HTTP Request Data Structure
  296. */
  297. typedef struct httpd_req {
  298. httpd_handle_t handle; /*!< Handle to server instance */
  299. int method; /*!< The type of HTTP request, -1 if unsupported method */
  300. const char uri[HTTPD_MAX_URI_LEN + 1]; /*!< The URI of this request (1 byte extra for null termination) */
  301. size_t content_len; /*!< Length of the request body */
  302. void *aux; /*!< Internally used members */
  303. /**
  304. * User context pointer passed during URI registration.
  305. */
  306. void *user_ctx;
  307. /**
  308. * Session Context Pointer
  309. *
  310. * A session context. Contexts are maintained across 'sessions' for a
  311. * given open TCP connection. One session could have multiple request
  312. * responses. The web server will ensure that the context persists
  313. * across all these request and responses.
  314. *
  315. * By default, this is NULL. URI Handlers can set this to any meaningful
  316. * value.
  317. *
  318. * If the underlying socket gets closed, and this pointer is non-NULL,
  319. * the web server will free up the context by calling free(), unless
  320. * free_ctx function is set.
  321. */
  322. void *sess_ctx;
  323. /**
  324. * Pointer to free context hook
  325. *
  326. * Function to free session context
  327. *
  328. * If the web server's socket closes, it frees up the session context by
  329. * calling free() on the sess_ctx member. If you wish to use a custom
  330. * function for freeing the session context, please specify that here.
  331. */
  332. httpd_free_ctx_fn_t free_ctx;
  333. /**
  334. * Flag indicating if Session Context changes should be ignored
  335. *
  336. * By default, if you change the sess_ctx in some URI handler, the http server
  337. * will internally free the earlier context (if non NULL), after the URI handler
  338. * returns. If you want to manage the allocation/reallocation/freeing of
  339. * sess_ctx yourself, set this flag to true, so that the server will not
  340. * perform any checks on it. The context will be cleared by the server
  341. * (by calling free_ctx or free()) only if the socket gets closed.
  342. */
  343. bool ignore_sess_ctx_changes;
  344. } httpd_req_t;
  345. /**
  346. * @brief Structure for URI handler
  347. */
  348. typedef struct httpd_uri {
  349. const char *uri; /*!< The URI to handle */
  350. httpd_method_t method; /*!< Method supported by the URI */
  351. /**
  352. * Handler to call for supported request method. This must
  353. * return ESP_OK, or else the underlying socket will be closed.
  354. */
  355. esp_err_t (*handler)(httpd_req_t *r);
  356. /**
  357. * Pointer to user context data which will be available to handler
  358. */
  359. void *user_ctx;
  360. } httpd_uri_t;
  361. /**
  362. * @brief Registers a URI handler
  363. *
  364. * @note URI handlers can be registered in real time as long as the
  365. * server handle is valid.
  366. *
  367. * Example usage:
  368. * @code{c}
  369. *
  370. * esp_err_t my_uri_handler(httpd_req_t* req)
  371. * {
  372. * // Recv , Process and Send
  373. * ....
  374. * ....
  375. * ....
  376. *
  377. * // Fail condition
  378. * if (....) {
  379. * // Return fail to close session //
  380. * return ESP_FAIL;
  381. * }
  382. *
  383. * // On success
  384. * return ESP_OK;
  385. * }
  386. *
  387. * // URI handler structure
  388. * httpd_uri_t my_uri {
  389. * .uri = "/my_uri/path/xyz",
  390. * .method = HTTPD_GET,
  391. * .handler = my_uri_handler,
  392. * .user_ctx = NULL
  393. * };
  394. *
  395. * // Register handler
  396. * if (httpd_register_uri_handler(server_handle, &my_uri) != ESP_OK) {
  397. * // If failed to register handler
  398. * ....
  399. * }
  400. *
  401. * @endcode
  402. *
  403. * @param[in] handle handle to HTTPD server instance
  404. * @param[in] uri_handler pointer to handler that needs to be registered
  405. *
  406. * @return
  407. * - ESP_OK : On successfully registering the handler
  408. * - ESP_ERR_INVALID_ARG : Null arguments
  409. * - ESP_ERR_HTTPD_HANDLERS_FULL : If no slots left for new handler
  410. * - ESP_ERR_HTTPD_HANDLER_EXISTS : If handler with same URI and
  411. * method is already registered
  412. */
  413. esp_err_t httpd_register_uri_handler(httpd_handle_t handle,
  414. const httpd_uri_t *uri_handler);
  415. /**
  416. * @brief Unregister a URI handler
  417. *
  418. * @param[in] handle handle to HTTPD server instance
  419. * @param[in] uri URI string
  420. * @param[in] method HTTP method
  421. *
  422. * @return
  423. * - ESP_OK : On successfully deregistering the handler
  424. * - ESP_ERR_INVALID_ARG : Null arguments
  425. * - ESP_ERR_NOT_FOUND : Handler with specified URI and method not found
  426. */
  427. esp_err_t httpd_unregister_uri_handler(httpd_handle_t handle,
  428. const char *uri, httpd_method_t method);
  429. /**
  430. * @brief Unregister all URI handlers with the specified uri string
  431. *
  432. * @param[in] handle handle to HTTPD server instance
  433. * @param[in] uri uri string specifying all handlers that need
  434. * to be deregisterd
  435. *
  436. * @return
  437. * - ESP_OK : On successfully deregistering all such handlers
  438. * - ESP_ERR_INVALID_ARG : Null arguments
  439. * - ESP_ERR_NOT_FOUND : No handler registered with specified uri string
  440. */
  441. esp_err_t httpd_unregister_uri(httpd_handle_t handle, const char* uri);
  442. /** End of URI Handlers
  443. * @}
  444. */
  445. /* ************** Group: HTTP Error ************** */
  446. /** @name HTTP Error
  447. * Prototype for HTTP errors and error handling functions
  448. * @{
  449. */
  450. /**
  451. * @brief Error codes sent as HTTP response in case of errors
  452. * encountered during processing of an HTTP request
  453. */
  454. typedef enum {
  455. /* For any unexpected errors during parsing, like unexpected
  456. * state transitions, or unhandled errors.
  457. */
  458. HTTPD_500_INTERNAL_SERVER_ERROR = 0,
  459. /* For methods not supported by http_parser. Presently
  460. * http_parser halts parsing when such methods are
  461. * encountered and so the server responds with 400 Bad
  462. * Request error instead.
  463. */
  464. HTTPD_501_METHOD_NOT_IMPLEMENTED,
  465. /* When HTTP version is not 1.1 */
  466. HTTPD_505_VERSION_NOT_SUPPORTED,
  467. /* Returned when http_parser halts parsing due to incorrect
  468. * syntax of request, unsupported method in request URI or
  469. * due to chunked encoding / upgrade field present in headers
  470. */
  471. HTTPD_400_BAD_REQUEST,
  472. /* When requested URI is not found */
  473. HTTPD_404_NOT_FOUND,
  474. /* When URI found, but method has no handler registered */
  475. HTTPD_405_METHOD_NOT_ALLOWED,
  476. /* Intended for recv timeout. Presently it's being sent
  477. * for other recv errors as well. Client should expect the
  478. * server to immediately close the connection after
  479. * responding with this.
  480. */
  481. HTTPD_408_REQ_TIMEOUT,
  482. /* Intended for responding to chunked encoding, which is
  483. * not supported currently. Though unhandled http_parser
  484. * callback for chunked request returns "400 Bad Request"
  485. */
  486. HTTPD_411_LENGTH_REQUIRED,
  487. /* URI length greater than CONFIG_HTTPD_MAX_URI_LEN */
  488. HTTPD_414_URI_TOO_LONG,
  489. /* Headers section larger than CONFIG_HTTPD_MAX_REQ_HDR_LEN */
  490. HTTPD_431_REQ_HDR_FIELDS_TOO_LARGE,
  491. /* Used internally for retrieving the total count of errors */
  492. HTTPD_ERR_CODE_MAX
  493. } httpd_err_code_t;
  494. /**
  495. * @brief Function prototype for HTTP error handling.
  496. *
  497. * This function is executed upon HTTP errors generated during
  498. * internal processing of an HTTP request. This is used to override
  499. * the default behavior on error, which is to send HTTP error response
  500. * and close the underlying socket.
  501. *
  502. * @note
  503. * - If implemented, the server will not automatically send out HTTP
  504. * error response codes, therefore, httpd_resp_send_err() must be
  505. * invoked inside this function if user wishes to generate HTTP
  506. * error responses.
  507. * - When invoked, the validity of `uri`, `method`, `content_len`
  508. * and `user_ctx` fields of the httpd_req_t parameter is not
  509. * guaranteed as the HTTP request may be partially received/parsed.
  510. * - The function must return ESP_OK if underlying socket needs to
  511. * be kept open. Any other value will ensure that the socket is
  512. * closed. The return value is ignored when error is of type
  513. * `HTTPD_500_INTERNAL_SERVER_ERROR` and the socket closed anyway.
  514. *
  515. * @param[in] req HTTP request for which the error needs to be handled
  516. * @param[in] error Error type
  517. *
  518. * @return
  519. * - ESP_OK : error handled successful
  520. * - ESP_FAIL : failure indicates that the underlying socket needs to be closed
  521. */
  522. typedef esp_err_t (*httpd_err_handler_func_t)(httpd_req_t *req,
  523. httpd_err_code_t error);
  524. /**
  525. * @brief Function for registering HTTP error handlers
  526. *
  527. * This function maps a handler function to any supported error code
  528. * given by `httpd_err_code_t`. See prototype `httpd_err_handler_func_t`
  529. * above for details.
  530. *
  531. * @param[in] handle HTTP server handle
  532. * @param[in] error Error type
  533. * @param[in] handler_fn User implemented handler function
  534. * (Pass NULL to unset any previously set handler)
  535. *
  536. * @return
  537. * - ESP_OK : handler registered successfully
  538. * - ESP_ERR_INVALID_ARG : invalid error code or server handle
  539. */
  540. esp_err_t httpd_register_err_handler(httpd_handle_t handle,
  541. httpd_err_code_t error,
  542. httpd_err_handler_func_t handler_fn);
  543. /** End of HTTP Error
  544. * @}
  545. */
  546. /* ************** Group: TX/RX ************** */
  547. /** @name TX / RX
  548. * Prototype for HTTPDs low-level send/recv functions
  549. * @{
  550. */
  551. #define HTTPD_SOCK_ERR_FAIL -1
  552. #define HTTPD_SOCK_ERR_INVALID -2
  553. #define HTTPD_SOCK_ERR_TIMEOUT -3
  554. /**
  555. * @brief Prototype for HTTPDs low-level send function
  556. *
  557. * @note User specified send function must handle errors internally,
  558. * depending upon the set value of errno, and return specific
  559. * HTTPD_SOCK_ERR_ codes, which will eventually be conveyed as
  560. * return value of httpd_send() function
  561. *
  562. * @param[in] hd server instance
  563. * @param[in] sockfd session socket file descriptor
  564. * @param[in] buf buffer with bytes to send
  565. * @param[in] buf_len data size
  566. * @param[in] flags flags for the send() function
  567. * @return
  568. * - Bytes : The number of bytes sent successfully
  569. * - HTTPD_SOCK_ERR_INVALID : Invalid arguments
  570. * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket send()
  571. * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket send()
  572. */
  573. typedef int (*httpd_send_func_t)(httpd_handle_t hd, int sockfd, const char *buf, size_t buf_len, int flags);
  574. /**
  575. * @brief Prototype for HTTPDs low-level recv function
  576. *
  577. * @note User specified recv function must handle errors internally,
  578. * depending upon the set value of errno, and return specific
  579. * HTTPD_SOCK_ERR_ codes, which will eventually be conveyed as
  580. * return value of httpd_req_recv() function
  581. *
  582. * @param[in] hd server instance
  583. * @param[in] sockfd session socket file descriptor
  584. * @param[in] buf buffer with bytes to send
  585. * @param[in] buf_len data size
  586. * @param[in] flags flags for the send() function
  587. * @return
  588. * - Bytes : The number of bytes received successfully
  589. * - 0 : Buffer length parameter is zero / connection closed by peer
  590. * - HTTPD_SOCK_ERR_INVALID : Invalid arguments
  591. * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket recv()
  592. * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket recv()
  593. */
  594. typedef int (*httpd_recv_func_t)(httpd_handle_t hd, int sockfd, char *buf, size_t buf_len, int flags);
  595. /**
  596. * @brief Prototype for HTTPDs low-level "get pending bytes" function
  597. *
  598. * @note User specified pending function must handle errors internally,
  599. * depending upon the set value of errno, and return specific
  600. * HTTPD_SOCK_ERR_ codes, which will be handled accordingly in
  601. * the server task.
  602. *
  603. * @param[in] hd server instance
  604. * @param[in] sockfd session socket file descriptor
  605. * @return
  606. * - Bytes : The number of bytes waiting to be received
  607. * - HTTPD_SOCK_ERR_INVALID : Invalid arguments
  608. * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket pending()
  609. * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket pending()
  610. */
  611. typedef int (*httpd_pending_func_t)(httpd_handle_t hd, int sockfd);
  612. /** End of TX / RX
  613. * @}
  614. */
  615. /* ************** Group: Request/Response ************** */
  616. /** @name Request / Response
  617. * APIs related to the data send/receive by URI handlers.
  618. * These APIs are supposed to be called only from the context of
  619. * a URI handler where httpd_req_t* request pointer is valid.
  620. * @{
  621. */
  622. /**
  623. * @brief Override web server's receive function (by session FD)
  624. *
  625. * This function overrides the web server's receive function. This same function is
  626. * used to read HTTP request packets.
  627. *
  628. * @note This API is supposed to be called either from the context of
  629. * - an http session APIs where sockfd is a valid parameter
  630. * - a URI handler where sockfd is obtained using httpd_req_to_sockfd()
  631. *
  632. * @param[in] hd HTTPD instance handle
  633. * @param[in] sockfd Session socket FD
  634. * @param[in] recv_func The receive function to be set for this session
  635. *
  636. * @return
  637. * - ESP_OK : On successfully registering override
  638. * - ESP_ERR_INVALID_ARG : Null arguments
  639. */
  640. esp_err_t httpd_sess_set_recv_override(httpd_handle_t hd, int sockfd, httpd_recv_func_t recv_func);
  641. /**
  642. * @brief Override web server's send function (by session FD)
  643. *
  644. * This function overrides the web server's send function. This same function is
  645. * used to send out any response to any HTTP request.
  646. *
  647. * @note This API is supposed to be called either from the context of
  648. * - an http session APIs where sockfd is a valid parameter
  649. * - a URI handler where sockfd is obtained using httpd_req_to_sockfd()
  650. *
  651. * @param[in] hd HTTPD instance handle
  652. * @param[in] sockfd Session socket FD
  653. * @param[in] send_func The send function to be set for this session
  654. *
  655. * @return
  656. * - ESP_OK : On successfully registering override
  657. * - ESP_ERR_INVALID_ARG : Null arguments
  658. */
  659. esp_err_t httpd_sess_set_send_override(httpd_handle_t hd, int sockfd, httpd_send_func_t send_func);
  660. /**
  661. * @brief Override web server's pending function (by session FD)
  662. *
  663. * This function overrides the web server's pending function. This function is
  664. * used to test for pending bytes in a socket.
  665. *
  666. * @note This API is supposed to be called either from the context of
  667. * - an http session APIs where sockfd is a valid parameter
  668. * - a URI handler where sockfd is obtained using httpd_req_to_sockfd()
  669. *
  670. * @param[in] hd HTTPD instance handle
  671. * @param[in] sockfd Session socket FD
  672. * @param[in] pending_func The receive function to be set for this session
  673. *
  674. * @return
  675. * - ESP_OK : On successfully registering override
  676. * - ESP_ERR_INVALID_ARG : Null arguments
  677. */
  678. esp_err_t httpd_sess_set_pending_override(httpd_handle_t hd, int sockfd, httpd_pending_func_t pending_func);
  679. /**
  680. * @brief Get the Socket Descriptor from the HTTP request
  681. *
  682. * This API will return the socket descriptor of the session for
  683. * which URI handler was executed on reception of HTTP request.
  684. * This is useful when user wants to call functions that require
  685. * session socket fd, from within a URI handler, ie. :
  686. * httpd_sess_get_ctx(),
  687. * httpd_sess_trigger_close(),
  688. * httpd_sess_update_lru_counter().
  689. *
  690. * @note This API is supposed to be called only from the context of
  691. * a URI handler where httpd_req_t* request pointer is valid.
  692. *
  693. * @param[in] r The request whose socket descriptor should be found
  694. *
  695. * @return
  696. * - Socket descriptor : The socket descriptor for this request
  697. * - -1 : Invalid/NULL request pointer
  698. */
  699. int httpd_req_to_sockfd(httpd_req_t *r);
  700. /**
  701. * @brief API to read content data from the HTTP request
  702. *
  703. * This API will read HTTP content data from the HTTP request into
  704. * provided buffer. Use content_len provided in httpd_req_t structure
  705. * to know the length of data to be fetched. If content_len is too
  706. * large for the buffer then user may have to make multiple calls to
  707. * this function, each time fetching 'buf_len' number of bytes,
  708. * while the pointer to content data is incremented internally by
  709. * the same number.
  710. *
  711. * @note
  712. * - This API is supposed to be called only from the context of
  713. * a URI handler where httpd_req_t* request pointer is valid.
  714. * - If an error is returned, the URI handler must further return an error.
  715. * This will ensure that the erroneous socket is closed and cleaned up by
  716. * the web server.
  717. * - Presently Chunked Encoding is not supported
  718. *
  719. * @param[in] r The request being responded to
  720. * @param[in] buf Pointer to a buffer that the data will be read into
  721. * @param[in] buf_len Length of the buffer
  722. *
  723. * @return
  724. * - Bytes : Number of bytes read into the buffer successfully
  725. * - 0 : Buffer length parameter is zero / connection closed by peer
  726. * - HTTPD_SOCK_ERR_INVALID : Invalid arguments
  727. * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket recv()
  728. * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket recv()
  729. */
  730. int httpd_req_recv(httpd_req_t *r, char *buf, size_t buf_len);
  731. /**
  732. * @brief Search for a field in request headers and
  733. * return the string length of it's value
  734. *
  735. * @note
  736. * - This API is supposed to be called only from the context of
  737. * a URI handler where httpd_req_t* request pointer is valid.
  738. * - Once httpd_resp_send() API is called all request headers
  739. * are purged, so request headers need be copied into separate
  740. * buffers if they are required later.
  741. *
  742. * @param[in] r The request being responded to
  743. * @param[in] field The header field to be searched in the request
  744. *
  745. * @return
  746. * - Length : If field is found in the request URL
  747. * - Zero : Field not found / Invalid request / Null arguments
  748. */
  749. size_t httpd_req_get_hdr_value_len(httpd_req_t *r, const char *field);
  750. /**
  751. * @brief Get the value string of a field from the request headers
  752. *
  753. * @note
  754. * - This API is supposed to be called only from the context of
  755. * a URI handler where httpd_req_t* request pointer is valid.
  756. * - Once httpd_resp_send() API is called all request headers
  757. * are purged, so request headers need be copied into separate
  758. * buffers if they are required later.
  759. * - If output size is greater than input, then the value is truncated,
  760. * accompanied by truncation error as return value.
  761. * - Use httpd_req_get_hdr_value_len() to know the right buffer length
  762. *
  763. * @param[in] r The request being responded to
  764. * @param[in] field The field to be searched in the header
  765. * @param[out] val Pointer to the buffer into which the value will be copied if the field is found
  766. * @param[in] val_size Size of the user buffer "val"
  767. *
  768. * @return
  769. * - ESP_OK : Field found in the request header and value string copied
  770. * - ESP_ERR_NOT_FOUND : Key not found
  771. * - ESP_ERR_INVALID_ARG : Null arguments
  772. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid HTTP request pointer
  773. * - ESP_ERR_HTTPD_RESULT_TRUNC : Value string truncated
  774. */
  775. esp_err_t httpd_req_get_hdr_value_str(httpd_req_t *r, const char *field, char *val, size_t val_size);
  776. /**
  777. * @brief Get Query string length from the request URL
  778. *
  779. * @note This API is supposed to be called only from the context of
  780. * a URI handler where httpd_req_t* request pointer is valid
  781. *
  782. * @param[in] r The request being responded to
  783. *
  784. * @return
  785. * - Length : Query is found in the request URL
  786. * - Zero : Query not found / Null arguments / Invalid request
  787. */
  788. size_t httpd_req_get_url_query_len(httpd_req_t *r);
  789. /**
  790. * @brief Get Query string from the request URL
  791. *
  792. * @note
  793. * - Presently, the user can fetch the full URL query string, but decoding
  794. * will have to be performed by the user. Request headers can be read using
  795. * httpd_req_get_hdr_value_str() to know the 'Content-Type' (eg. Content-Type:
  796. * application/x-www-form-urlencoded) and then the appropriate decoding
  797. * algorithm needs to be applied.
  798. * - This API is supposed to be called only from the context of
  799. * a URI handler where httpd_req_t* request pointer is valid
  800. * - If output size is greater than input, then the value is truncated,
  801. * accompanied by truncation error as return value
  802. * - Use httpd_req_get_url_query_len() to know the right buffer length
  803. *
  804. * @param[in] r The request being responded to
  805. * @param[out] buf Pointer to the buffer into which the query string will be copied (if found)
  806. * @param[in] buf_len Length of output buffer
  807. *
  808. * @return
  809. * - ESP_OK : Query is found in the request URL and copied to buffer
  810. * - ESP_ERR_NOT_FOUND : Query not found
  811. * - ESP_ERR_INVALID_ARG : Null arguments
  812. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid HTTP request pointer
  813. * - ESP_ERR_HTTPD_RESULT_TRUNC : Query string truncated
  814. */
  815. esp_err_t httpd_req_get_url_query_str(httpd_req_t *r, char *buf, size_t buf_len);
  816. /**
  817. * @brief Helper function to get a URL query tag from a query
  818. * string of the type param1=val1&param2=val2
  819. *
  820. * @note
  821. * - The components of URL query string (keys and values) are not URLdecoded.
  822. * The user must check for 'Content-Type' field in the request headers and
  823. * then depending upon the specified encoding (URLencoded or otherwise) apply
  824. * the appropriate decoding algorithm.
  825. * - If actual value size is greater than val_size, then the value is truncated,
  826. * accompanied by truncation error as return value.
  827. *
  828. * @param[in] qry Pointer to query string
  829. * @param[in] key The key to be searched in the query string
  830. * @param[out] val Pointer to the buffer into which the value will be copied if the key is found
  831. * @param[in] val_size Size of the user buffer "val"
  832. *
  833. * @return
  834. * - ESP_OK : Key is found in the URL query string and copied to buffer
  835. * - ESP_ERR_NOT_FOUND : Key not found
  836. * - ESP_ERR_INVALID_ARG : Null arguments
  837. * - ESP_ERR_HTTPD_RESULT_TRUNC : Value string truncated
  838. */
  839. esp_err_t httpd_query_key_value(const char *qry, const char *key, char *val, size_t val_size);
  840. /**
  841. * @brief Test if a URI matches the given wildcard template.
  842. *
  843. * Template may end with "?" to make the previous character optional (typically a slash),
  844. * "*" for a wildcard match, and "?*" to make the previous character optional, and if present,
  845. * allow anything to follow.
  846. *
  847. * Example:
  848. * - * matches everything
  849. * - /foo/? matches /foo and /foo/
  850. * - /foo/\* (sans the backslash) matches /foo/ and /foo/bar, but not /foo or /fo
  851. * - /foo/?* or /foo/\*? (sans the backslash) matches /foo/, /foo/bar, and also /foo, but not /foox or /fo
  852. *
  853. * The special characters "?" and "*" anywhere else in the template will be taken literally.
  854. *
  855. * @param[in] uri_template URI template (pattern)
  856. * @param[in] uri_to_match URI to be matched
  857. * @param[in] match_upto how many characters of the URI buffer to test
  858. * (there may be trailing query string etc.)
  859. *
  860. * @return true if a match was found
  861. */
  862. bool httpd_uri_match_wildcard(const char *uri_template, const char *uri_to_match, size_t match_upto);
  863. /**
  864. * @brief API to send a complete HTTP response.
  865. *
  866. * This API will send the data as an HTTP response to the request.
  867. * This assumes that you have the entire response ready in a single
  868. * buffer. If you wish to send response in incremental chunks use
  869. * httpd_resp_send_chunk() instead.
  870. *
  871. * If no status code and content-type were set, by default this
  872. * will send 200 OK status code and content type as text/html.
  873. * You may call the following functions before this API to configure
  874. * the response headers :
  875. * httpd_resp_set_status() - for setting the HTTP status string,
  876. * httpd_resp_set_type() - for setting the Content Type,
  877. * httpd_resp_set_hdr() - for appending any additional field
  878. * value entries in the response header
  879. *
  880. * @note
  881. * - This API is supposed to be called only from the context of
  882. * a URI handler where httpd_req_t* request pointer is valid.
  883. * - Once this API is called, the request has been responded to.
  884. * - No additional data can then be sent for the request.
  885. * - Once this API is called, all request headers are purged, so
  886. * request headers need be copied into separate buffers if
  887. * they are required later.
  888. *
  889. * @param[in] r The request being responded to
  890. * @param[in] buf Buffer from where the content is to be fetched
  891. * @param[in] buf_len Length of the buffer, HTTPD_RESP_USE_STRLEN to use strlen()
  892. *
  893. * @return
  894. * - ESP_OK : On successfully sending the response packet
  895. * - ESP_ERR_INVALID_ARG : Null request pointer
  896. * - ESP_ERR_HTTPD_RESP_HDR : Essential headers are too large for internal buffer
  897. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  898. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request
  899. */
  900. esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, ssize_t buf_len);
  901. /**
  902. * @brief API to send one HTTP chunk
  903. *
  904. * This API will send the data as an HTTP response to the
  905. * request. This API will use chunked-encoding and send the response
  906. * in the form of chunks. If you have the entire response contained in
  907. * a single buffer, please use httpd_resp_send() instead.
  908. *
  909. * If no status code and content-type were set, by default this will
  910. * send 200 OK status code and content type as text/html. You may
  911. * call the following functions before this API to configure the
  912. * response headers
  913. * httpd_resp_set_status() - for setting the HTTP status string,
  914. * httpd_resp_set_type() - for setting the Content Type,
  915. * httpd_resp_set_hdr() - for appending any additional field
  916. * value entries in the response header
  917. *
  918. * @note
  919. * - This API is supposed to be called only from the context of
  920. * a URI handler where httpd_req_t* request pointer is valid.
  921. * - When you are finished sending all your chunks, you must call
  922. * this function with buf_len as 0.
  923. * - Once this API is called, all request headers are purged, so
  924. * request headers need be copied into separate buffers if they
  925. * are required later.
  926. *
  927. * @param[in] r The request being responded to
  928. * @param[in] buf Pointer to a buffer that stores the data
  929. * @param[in] buf_len Length of the buffer, HTTPD_RESP_USE_STRLEN to use strlen()
  930. *
  931. * @return
  932. * - ESP_OK : On successfully sending the response packet chunk
  933. * - ESP_ERR_INVALID_ARG : Null request pointer
  934. * - ESP_ERR_HTTPD_RESP_HDR : Essential headers are too large for internal buffer
  935. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  936. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  937. */
  938. esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, ssize_t buf_len);
  939. /**
  940. * @brief API to send a complete string as HTTP response.
  941. *
  942. * This API simply calls http_resp_send with buffer length
  943. * set to string length assuming the buffer contains a null
  944. * terminated string
  945. *
  946. * @param[in] r The request being responded to
  947. * @param[in] str String to be sent as response body
  948. *
  949. * @return
  950. * - ESP_OK : On successfully sending the response packet
  951. * - ESP_ERR_INVALID_ARG : Null request pointer
  952. * - ESP_ERR_HTTPD_RESP_HDR : Essential headers are too large for internal buffer
  953. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  954. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request
  955. */
  956. static inline esp_err_t httpd_resp_sendstr(httpd_req_t *r, const char *str) {
  957. return httpd_resp_send(r, str, (str == NULL) ? 0 : strlen(str));
  958. }
  959. /**
  960. * @brief API to send a string as an HTTP response chunk.
  961. *
  962. * This API simply calls http_resp_send_chunk with buffer length
  963. * set to string length assuming the buffer contains a null
  964. * terminated string
  965. *
  966. * @param[in] r The request being responded to
  967. * @param[in] str String to be sent as response body (NULL to finish response packet)
  968. *
  969. * @return
  970. * - ESP_OK : On successfully sending the response packet
  971. * - ESP_ERR_INVALID_ARG : Null request pointer
  972. * - ESP_ERR_HTTPD_RESP_HDR : Essential headers are too large for internal buffer
  973. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  974. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request
  975. */
  976. static inline esp_err_t httpd_resp_sendstr_chunk(httpd_req_t *r, const char *str) {
  977. return httpd_resp_send_chunk(r, str, (str == NULL) ? 0 : strlen(str));
  978. }
  979. /* Some commonly used status codes */
  980. #define HTTPD_200 "200 OK" /*!< HTTP Response 200 */
  981. #define HTTPD_204 "204 No Content" /*!< HTTP Response 204 */
  982. #define HTTPD_207 "207 Multi-Status" /*!< HTTP Response 207 */
  983. #define HTTPD_400 "400 Bad Request" /*!< HTTP Response 400 */
  984. #define HTTPD_404 "404 Not Found" /*!< HTTP Response 404 */
  985. #define HTTPD_408 "408 Request Timeout" /*!< HTTP Response 408 */
  986. #define HTTPD_500 "500 Internal Server Error" /*!< HTTP Response 500 */
  987. /**
  988. * @brief API to set the HTTP status code
  989. *
  990. * This API sets the status of the HTTP response to the value specified.
  991. * By default, the '200 OK' response is sent as the response.
  992. *
  993. * @note
  994. * - This API is supposed to be called only from the context of
  995. * a URI handler where httpd_req_t* request pointer is valid.
  996. * - This API only sets the status to this value. The status isn't
  997. * sent out until any of the send APIs is executed.
  998. * - Make sure that the lifetime of the status string is valid till
  999. * send function is called.
  1000. *
  1001. * @param[in] r The request being responded to
  1002. * @param[in] status The HTTP status code of this response
  1003. *
  1004. * @return
  1005. * - ESP_OK : On success
  1006. * - ESP_ERR_INVALID_ARG : Null arguments
  1007. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  1008. */
  1009. esp_err_t httpd_resp_set_status(httpd_req_t *r, const char *status);
  1010. /* Some commonly used content types */
  1011. #define HTTPD_TYPE_JSON "application/json" /*!< HTTP Content type JSON */
  1012. #define HTTPD_TYPE_TEXT "text/html" /*!< HTTP Content type text/HTML */
  1013. #define HTTPD_TYPE_OCTET "application/octet-stream" /*!< HTTP Content type octext-stream */
  1014. /**
  1015. * @brief API to set the HTTP content type
  1016. *
  1017. * This API sets the 'Content Type' field of the response.
  1018. * The default content type is 'text/html'.
  1019. *
  1020. * @note
  1021. * - This API is supposed to be called only from the context of
  1022. * a URI handler where httpd_req_t* request pointer is valid.
  1023. * - This API only sets the content type to this value. The type
  1024. * isn't sent out until any of the send APIs is executed.
  1025. * - Make sure that the lifetime of the type string is valid till
  1026. * send function is called.
  1027. *
  1028. * @param[in] r The request being responded to
  1029. * @param[in] type The Content Type of the response
  1030. *
  1031. * @return
  1032. * - ESP_OK : On success
  1033. * - ESP_ERR_INVALID_ARG : Null arguments
  1034. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  1035. */
  1036. esp_err_t httpd_resp_set_type(httpd_req_t *r, const char *type);
  1037. /**
  1038. * @brief API to append any additional headers
  1039. *
  1040. * This API sets any additional header fields that need to be sent in the response.
  1041. *
  1042. * @note
  1043. * - This API is supposed to be called only from the context of
  1044. * a URI handler where httpd_req_t* request pointer is valid.
  1045. * - The header isn't sent out until any of the send APIs is executed.
  1046. * - The maximum allowed number of additional headers is limited to
  1047. * value of max_resp_headers in config structure.
  1048. * - Make sure that the lifetime of the field value strings are valid till
  1049. * send function is called.
  1050. *
  1051. * @param[in] r The request being responded to
  1052. * @param[in] field The field name of the HTTP header
  1053. * @param[in] value The value of this HTTP header
  1054. *
  1055. * @return
  1056. * - ESP_OK : On successfully appending new header
  1057. * - ESP_ERR_INVALID_ARG : Null arguments
  1058. * - ESP_ERR_HTTPD_RESP_HDR : Total additional headers exceed max allowed
  1059. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  1060. */
  1061. esp_err_t httpd_resp_set_hdr(httpd_req_t *r, const char *field, const char *value);
  1062. /**
  1063. * @brief For sending out error code in response to HTTP request.
  1064. *
  1065. * @note
  1066. * - This API is supposed to be called only from the context of
  1067. * a URI handler where httpd_req_t* request pointer is valid.
  1068. * - Once this API is called, all request headers are purged, so
  1069. * request headers need be copied into separate buffers if
  1070. * they are required later.
  1071. * - If you wish to send additional data in the body of the
  1072. * response, please use the lower-level functions directly.
  1073. *
  1074. * @param[in] req Pointer to the HTTP request for which the response needs to be sent
  1075. * @param[in] error Error type to send
  1076. * @param[in] msg Error message string (pass NULL for default message)
  1077. *
  1078. * @return
  1079. * - ESP_OK : On successfully sending the response packet
  1080. * - ESP_ERR_INVALID_ARG : Null arguments
  1081. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  1082. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  1083. */
  1084. esp_err_t httpd_resp_send_err(httpd_req_t *req, httpd_err_code_t error, const char *msg);
  1085. /**
  1086. * @brief Helper function for HTTP 404
  1087. *
  1088. * Send HTTP 404 message. If you wish to send additional data in the body of the
  1089. * response, please use the lower-level functions directly.
  1090. *
  1091. * @note
  1092. * - This API is supposed to be called only from the context of
  1093. * a URI handler where httpd_req_t* request pointer is valid.
  1094. * - Once this API is called, all request headers are purged, so
  1095. * request headers need be copied into separate buffers if
  1096. * they are required later.
  1097. *
  1098. * @param[in] r The request being responded to
  1099. *
  1100. * @return
  1101. * - ESP_OK : On successfully sending the response packet
  1102. * - ESP_ERR_INVALID_ARG : Null arguments
  1103. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  1104. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  1105. */
  1106. static inline esp_err_t httpd_resp_send_404(httpd_req_t *r) {
  1107. return httpd_resp_send_err(r, HTTPD_404_NOT_FOUND, NULL);
  1108. }
  1109. /**
  1110. * @brief Helper function for HTTP 408
  1111. *
  1112. * Send HTTP 408 message. If you wish to send additional data in the body of the
  1113. * response, please use the lower-level functions directly.
  1114. *
  1115. * @note
  1116. * - This API is supposed to be called only from the context of
  1117. * a URI handler where httpd_req_t* request pointer is valid.
  1118. * - Once this API is called, all request headers are purged, so
  1119. * request headers need be copied into separate buffers if
  1120. * they are required later.
  1121. *
  1122. * @param[in] r The request being responded to
  1123. *
  1124. * @return
  1125. * - ESP_OK : On successfully sending the response packet
  1126. * - ESP_ERR_INVALID_ARG : Null arguments
  1127. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  1128. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  1129. */
  1130. static inline esp_err_t httpd_resp_send_408(httpd_req_t *r) {
  1131. return httpd_resp_send_err(r, HTTPD_408_REQ_TIMEOUT, NULL);
  1132. }
  1133. /**
  1134. * @brief Helper function for HTTP 500
  1135. *
  1136. * Send HTTP 500 message. If you wish to send additional data in the body of the
  1137. * response, please use the lower-level functions directly.
  1138. *
  1139. * @note
  1140. * - This API is supposed to be called only from the context of
  1141. * a URI handler where httpd_req_t* request pointer is valid.
  1142. * - Once this API is called, all request headers are purged, so
  1143. * request headers need be copied into separate buffers if
  1144. * they are required later.
  1145. *
  1146. * @param[in] r The request being responded to
  1147. *
  1148. * @return
  1149. * - ESP_OK : On successfully sending the response packet
  1150. * - ESP_ERR_INVALID_ARG : Null arguments
  1151. * - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
  1152. * - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
  1153. */
  1154. static inline esp_err_t httpd_resp_send_500(httpd_req_t *r) {
  1155. return httpd_resp_send_err(r, HTTPD_500_INTERNAL_SERVER_ERROR, NULL);
  1156. }
  1157. /**
  1158. * @brief Raw HTTP send
  1159. *
  1160. * Call this API if you wish to construct your custom response packet.
  1161. * When using this, all essential header, eg. HTTP version, Status Code,
  1162. * Content Type and Length, Encoding, etc. will have to be constructed
  1163. * manually, and HTTP delimeters (CRLF) will need to be placed correctly
  1164. * for separating sub-sections of the HTTP response packet.
  1165. *
  1166. * If the send override function is set, this API will end up
  1167. * calling that function eventually to send data out.
  1168. *
  1169. * @note
  1170. * - This API is supposed to be called only from the context of
  1171. * a URI handler where httpd_req_t* request pointer is valid.
  1172. * - Unless the response has the correct HTTP structure (which the
  1173. * user must now ensure) it is not guaranteed that it will be
  1174. * recognized by the client. For most cases, you wouldn't have
  1175. * to call this API, but you would rather use either of :
  1176. * httpd_resp_send(),
  1177. * httpd_resp_send_chunk()
  1178. *
  1179. * @param[in] r The request being responded to
  1180. * @param[in] buf Buffer from where the fully constructed packet is to be read
  1181. * @param[in] buf_len Length of the buffer
  1182. *
  1183. * @return
  1184. * - Bytes : Number of bytes that were sent successfully
  1185. * - HTTPD_SOCK_ERR_INVALID : Invalid arguments
  1186. * - HTTPD_SOCK_ERR_TIMEOUT : Timeout/interrupted while calling socket send()
  1187. * - HTTPD_SOCK_ERR_FAIL : Unrecoverable error while calling socket send()
  1188. */
  1189. int httpd_send(httpd_req_t *r, const char *buf, size_t buf_len);
  1190. /** End of Request / Response
  1191. * @}
  1192. */
  1193. /* ************** Group: Session ************** */
  1194. /** @name Session
  1195. * Functions for controlling sessions and accessing context data
  1196. * @{
  1197. */
  1198. /**
  1199. * @brief Get session context from socket descriptor
  1200. *
  1201. * Typically if a session context is created, it is available to URI handlers
  1202. * through the httpd_req_t structure. But, there are cases where the web
  1203. * server's send/receive functions may require the context (for example, for
  1204. * accessing keying information etc). Since the send/receive function only have
  1205. * the socket descriptor at their disposal, this API provides them with a way to
  1206. * retrieve the session context.
  1207. *
  1208. * @param[in] handle Handle to server returned by httpd_start
  1209. * @param[in] sockfd The socket descriptor for which the context should be extracted.
  1210. *
  1211. * @return
  1212. * - void* : Pointer to the context associated with this session
  1213. * - NULL : Empty context / Invalid handle / Invalid socket fd
  1214. */
  1215. void *httpd_sess_get_ctx(httpd_handle_t handle, int sockfd);
  1216. /**
  1217. * @brief Set session context by socket descriptor
  1218. *
  1219. * @param[in] handle Handle to server returned by httpd_start
  1220. * @param[in] sockfd The socket descriptor for which the context should be extracted.
  1221. * @param[in] ctx Context object to assign to the session
  1222. * @param[in] free_fn Function that should be called to free the context
  1223. */
  1224. void httpd_sess_set_ctx(httpd_handle_t handle, int sockfd, void *ctx, httpd_free_ctx_fn_t free_fn);
  1225. /**
  1226. * @brief Get session 'transport' context by socket descriptor
  1227. * @see httpd_sess_get_ctx()
  1228. *
  1229. * This context is used by the send/receive functions, for example to manage SSL context.
  1230. *
  1231. * @param[in] handle Handle to server returned by httpd_start
  1232. * @param[in] sockfd The socket descriptor for which the context should be extracted.
  1233. * @return
  1234. * - void* : Pointer to the transport context associated with this session
  1235. * - NULL : Empty context / Invalid handle / Invalid socket fd
  1236. */
  1237. void *httpd_sess_get_transport_ctx(httpd_handle_t handle, int sockfd);
  1238. /**
  1239. * @brief Set session 'transport' context by socket descriptor
  1240. * @see httpd_sess_set_ctx()
  1241. *
  1242. * @param[in] handle Handle to server returned by httpd_start
  1243. * @param[in] sockfd The socket descriptor for which the context should be extracted.
  1244. * @param[in] ctx Transport context object to assign to the session
  1245. * @param[in] free_fn Function that should be called to free the transport context
  1246. */
  1247. void httpd_sess_set_transport_ctx(httpd_handle_t handle, int sockfd, void *ctx, httpd_free_ctx_fn_t free_fn);
  1248. /**
  1249. * @brief Get HTTPD global user context (it was set in the server config struct)
  1250. *
  1251. * @param[in] handle Handle to server returned by httpd_start
  1252. * @return global user context
  1253. */
  1254. void *httpd_get_global_user_ctx(httpd_handle_t handle);
  1255. /**
  1256. * @brief Get HTTPD global transport context (it was set in the server config struct)
  1257. *
  1258. * @param[in] handle Handle to server returned by httpd_start
  1259. * @return global transport context
  1260. */
  1261. void *httpd_get_global_transport_ctx(httpd_handle_t handle);
  1262. /**
  1263. * @brief Trigger an httpd session close externally
  1264. *
  1265. * @note Calling this API is only required in special circumstances wherein
  1266. * some application requires to close an httpd client session asynchronously.
  1267. *
  1268. * @param[in] handle Handle to server returned by httpd_start
  1269. * @param[in] sockfd The socket descriptor of the session to be closed
  1270. *
  1271. * @return
  1272. * - ESP_OK : On successfully initiating closure
  1273. * - ESP_FAIL : Failure to queue work
  1274. * - ESP_ERR_NOT_FOUND : Socket fd not found
  1275. * - ESP_ERR_INVALID_ARG : Null arguments
  1276. */
  1277. esp_err_t httpd_sess_trigger_close(httpd_handle_t handle, int sockfd);
  1278. /**
  1279. * @brief Update LRU counter for a given socket
  1280. *
  1281. * LRU Counters are internally associated with each session to monitor
  1282. * how recently a session exchanged traffic. When LRU purge is enabled,
  1283. * if a client is requesting for connection but maximum number of
  1284. * sockets/sessions is reached, then the session having the earliest
  1285. * LRU counter is closed automatically.
  1286. *
  1287. * Updating the LRU counter manually prevents the socket from being purged
  1288. * due to the Least Recently Used (LRU) logic, even though it might not
  1289. * have received traffic for some time. This is useful when all open
  1290. * sockets/session are frequently exchanging traffic but the user specifically
  1291. * wants one of the sessions to be kept open, irrespective of when it last
  1292. * exchanged a packet.
  1293. *
  1294. * @note Calling this API is only necessary if the LRU Purge Enable option
  1295. * is enabled.
  1296. *
  1297. * @param[in] handle Handle to server returned by httpd_start
  1298. * @param[in] sockfd The socket descriptor of the session for which LRU counter
  1299. * is to be updated
  1300. *
  1301. * @return
  1302. * - ESP_OK : Socket found and LRU counter updated
  1303. * - ESP_ERR_NOT_FOUND : Socket not found
  1304. * - ESP_ERR_INVALID_ARG : Null arguments
  1305. */
  1306. esp_err_t httpd_sess_update_lru_counter(httpd_handle_t handle, int sockfd);
  1307. /** End of Session
  1308. * @}
  1309. */
  1310. /* ************** Group: Work Queue ************** */
  1311. /** @name Work Queue
  1312. * APIs related to the HTTPD Work Queue
  1313. * @{
  1314. */
  1315. /**
  1316. * @brief Prototype of the HTTPD work function
  1317. * Please refer to httpd_queue_work() for more details.
  1318. * @param[in] arg The arguments for this work function
  1319. */
  1320. typedef void (*httpd_work_fn_t)(void *arg);
  1321. /**
  1322. * @brief Queue execution of a function in HTTPD's context
  1323. *
  1324. * This API queues a work function for asynchronous execution
  1325. *
  1326. * @note Some protocols require that the web server generate some asynchronous data
  1327. * and send it to the persistently opened connection. This facility is for use
  1328. * by such protocols.
  1329. *
  1330. * @param[in] handle Handle to server returned by httpd_start
  1331. * @param[in] work Pointer to the function to be executed in the HTTPD's context
  1332. * @param[in] arg Pointer to the arguments that should be passed to this function
  1333. *
  1334. * @return
  1335. * - ESP_OK : On successfully queueing the work
  1336. * - ESP_FAIL : Failure in ctrl socket
  1337. * - ESP_ERR_INVALID_ARG : Null arguments
  1338. */
  1339. esp_err_t httpd_queue_work(httpd_handle_t handle, httpd_work_fn_t work, void *arg);
  1340. /** End of Group Work Queue
  1341. * @}
  1342. */
  1343. #ifdef __cplusplus
  1344. }
  1345. #endif
  1346. #endif /* ! _ESP_HTTP_SERVER_H_ */