microhttpd2_main.h.in (227722B)
1 /** 2 * Create parameter for #MHD_daemon_set_options() for work mode with 3 * no internal threads. 4 * The application periodically calls #MHD_daemon_process_blocking(), where 5 * MHD internally checks all sockets automatically. 6 * This is the default mode. 7 * @return the object of struct MHD_DaemonOptionAndValue with requested values 8 */ 9 #define MHD_D_OPTION_WM_EXTERNAL_PERIODIC() \ 10 MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_EXTERNAL_PERIODIC ()) 11 12 /** 13 * Create parameter for #MHD_daemon_set_options() for work mode with 14 * an external event loop with level triggers. 15 * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered 16 * sockets polling (like select() or poll()) and #MHD_daemon_event_update(). 17 * @param cb_val the callback for sockets registration 18 * @param cb_cls_val the closure for the @a cv_val callback 19 * @return the object of struct MHD_DaemonOptionAndValue with requested values 20 */ 21 #define MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL(cb_val,cb_cls_val) \ 22 MHD_D_OPTION_WORK_MODE ( \ 23 MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL ((cb_val),(cb_cls_val))) 24 25 /** 26 * Create parameter for #MHD_daemon_set_options() for work mode with 27 * an external event loop with edge triggers. 28 * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered 29 * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update(). 30 * @param cb_val the callback for sockets registration 31 * @param cb_cls_val the closure for the @a cv_val callback 32 * @return the object of struct MHD_DaemonOptionAndValue with requested values 33 */ 34 #define MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE(cb_val,cb_cls_val) \ 35 MHD_D_OPTION_WORK_MODE ( \ 36 MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE ((cb_val),(cb_cls_val))) 37 38 /** 39 * Create parameter for #MHD_daemon_set_options() for work mode with 40 * no internal threads and aggregate watch FD. 41 * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD 42 * that gets triggered by any MHD event. 43 * This FD can be watched as an aggregate indicator for all MHD events. 44 * This mode is available only on selected platforms (currently 45 * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD. 46 * When the FD is triggered, #MHD_daemon_process_nonblocking() should 47 * be called. 48 * @return the object of struct MHD_DaemonOptionAndValue with requested values 49 */ 50 #define MHD_D_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH() \ 51 MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH ()) 52 53 /** 54 * Create parameter for #MHD_daemon_set_options() for work mode with 55 * one or more worker threads. 56 * If number of threads is one, then daemon starts with single worker thread 57 * that handles all connections. 58 * If number of threads is larger than one, then that number of worker threads, 59 * and handling of connection is distributed among the workers. 60 * @param num_workers the number of worker threads, zero is treated as one 61 * @return the object of struct MHD_DaemonOptionAndValue with requested values 62 */ 63 #define MHD_D_OPTION_WM_WORKER_THREADS(num_workers) \ 64 MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_WORKER_THREADS (num_workers)) 65 66 /** 67 * Create parameter for #MHD_daemon_set_options() for work mode with 68 * one internal thread for listening and additional threads per every 69 * connection. Use this if handling requests is CPU-intensive or blocking, 70 * your application is thread-safe and you have plenty of memory (per 71 * connection). 72 * @return the object of struct MHD_DaemonOptionAndValue with requested values 73 */ 74 #define MHD_D_OPTION_WM_THREAD_PER_CONNECTION() \ 75 MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_THREAD_PER_CONNECTION ()) 76 77 /** 78 * Set the requested options for the daemon. 79 * 80 * If any option fail other options may be or may be not applied. 81 * @param daemon the daemon to set the options 82 * @param[in] options the pointer to the array with the options; 83 * the array processing stops at the first ::MHD_D_O_END 84 * option, but not later than after processing 85 * @a options_max_num entries 86 * @param options_max_num the maximum number of entries in the @a options, 87 * use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing 88 * must stop only at zero-termination option 89 * @return ::MHD_SC_OK on success, 90 * error code otherwise 91 */ 92 MHD_EXTERN_ enum MHD_StatusCode 93 MHD_daemon_set_options ( 94 struct MHD_Daemon *MHD_RESTRICT daemon, 95 const struct MHD_DaemonOptionAndValue *MHD_RESTRICT options, 96 size_t options_max_num) 97 MHD_FN_PAR_NONNULL_ALL_; 98 99 100 /** 101 * Set the requested single option for the daemon. 102 * 103 * @param daemon the daemon to set the option 104 * @param[in] option_ptr the pointer to the option 105 * @return ::MHD_SC_OK on success, 106 * error code otherwise 107 */ 108 #define MHD_daemon_set_option(daemon, option_ptr) \ 109 MHD_daemon_set_options (daemon, option_ptr, 1) 110 111 112 /* *INDENT-OFF* */ 113 #ifdef MHD_USE_VARARG_MACROS 114 MHD_NOWARN_VARIADIC_MACROS_ 115 # if defined(MHD_USE_COMPOUND_LITERALS) && \ 116 defined(MHD_USE_COMP_LIT_FUNC_PARAMS) 117 /** 118 * Set the requested options for the daemon. 119 * 120 * If any option fail other options may be or may be not applied. 121 * 122 * It should be used with helpers that creates required options, for example: 123 * 124 * MHD_DAEMON_SET_OPTIONS(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES), 125 * MHD_D_OPTION_SOCK_ADDR(sa_len, sa)) 126 * 127 * @param daemon the daemon to set the options 128 * @param ... the list of the options, each option must be created 129 * by helpers MHD_D_OPTION_NameOfOption(option_value) 130 * @return ::MHD_SC_OK on success, 131 * error code otherwise 132 */ 133 # define MHD_DAEMON_SET_OPTIONS(daemon,...) \ 134 MHD_NOWARN_COMPOUND_LITERALS_ \ 135 MHD_NOWARN_AGGR_DYN_INIT_ \ 136 MHD_daemon_set_options ( \ 137 daemon, \ 138 ((const struct MHD_DaemonOptionAndValue[]) \ 139 {__VA_ARGS__, MHD_D_OPTION_TERMINATE ()}), \ 140 MHD_OPTIONS_ARRAY_MAX_SIZE) \ 141 MHD_RESTORE_WARN_AGGR_DYN_INIT_ \ 142 MHD_RESTORE_WARN_COMPOUND_LITERALS_ 143 # elif defined(MHD_USE_CPP_INIT_LIST) 144 MHD_C_DECLRATIONS_FINISH_HERE_ 145 # include <vector> 146 MHD_C_DECLRATIONS_START_HERE_ 147 /** 148 * Set the requested options for the daemon. 149 * 150 * If any option fail other options may be or may be not applied. 151 * 152 * It should be used with helpers that creates required options, for example: 153 * 154 * MHD_DAEMON_SET_OPTIONS(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES), 155 * MHD_D_OPTION_SOCK_ADDR(sa_len, sa)) 156 * 157 * @param daemon the daemon to set the options 158 * @param ... the list of the options, each option must be created 159 * by helpers MHD_D_OPTION_NameOfOption(option_value) 160 * @return ::MHD_SC_OK on success, 161 * error code otherwise 162 */ 163 # define MHD_DAEMON_SET_OPTIONS(daemon,...) \ 164 MHD_NOWARN_CPP_INIT_LIST_ \ 165 MHD_daemon_set_options ( \ 166 daemon, \ 167 (std::vector<struct MHD_DaemonOptionAndValue> \ 168 {__VA_ARGS__,MHD_D_OPTION_TERMINATE ()}).data (), \ 169 MHD_OPTIONS_ARRAY_MAX_SIZE) \ 170 MHD_RESTORE_WARN_CPP_INIT_LIST_ 171 # endif 172 MHD_RESTORE_WARN_VARIADIC_MACROS_ 173 #endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */ 174 /* *INDENT-ON* */ 175 176 177 /* ******************* Event loop ************************ */ 178 179 180 /** 181 * Run websever operation with possible blocking. 182 * 183 * Supported only in #MHD_WM_EXTERNAL_PERIODIC and 184 * #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes. 185 * 186 * This function does the following: waits for any network event not more than 187 * specified number of microseconds, processes all incoming and outgoing data, 188 * processes new connections, processes any timed-out connection, and does 189 * other things required to run webserver. 190 * Once all connections are processed, function returns. 191 * 192 * This function is useful for quick and simple (lazy) webserver implementation 193 * if application needs to run a single thread only and does not have any other 194 * network activity. 195 * 196 * In #MHD_WM_EXTERNAL_PERIODIC mode if @a microsec parameter is not zero 197 * this function determines the internal daemon timeout and use returned value 198 * as maximum wait time if it less than value of @a microsec parameter. 199 * 200 * @param daemon the daemon to run 201 * @param microsec the maximum time in microseconds to wait for network and 202 * other events. Note: there is no guarantee that function 203 * blocks for the specified amount of time. The real processing 204 * time can be shorter (if some data or connection timeout 205 * comes earlier) or longer (if data processing requires more 206 * time, especially in user callbacks). 207 * If set to '0' then function does not block and processes 208 * only already available data (if any). Zero value is 209 * recommended when used in #MHD_WM_EXTERNAL_SINGLE_FD_WATCH 210 * and the watched FD has been triggered. 211 * If set to #MHD_WAIT_INDEFINITELY then function waits 212 * for events indefinitely (blocks until next network activity 213 * or connection timeout). 214 * Always used as zero value in 215 * #MHD_WM_EXTERNAL_SINGLE_FD_WATCH mode. 216 * @return #MHD_SC_OK on success, otherwise 217 * an error code 218 * @ingroup event 219 */ 220 MHD_EXTERN_ enum MHD_StatusCode 221 MHD_daemon_process_blocking (struct MHD_Daemon *daemon, 222 uint_fast64_t microsec) 223 MHD_FN_PAR_NONNULL_ (1); 224 225 /** 226 * Run webserver operations (without blocking unless in client 227 * callbacks). 228 * 229 * Supported only in #MHD_WM_EXTERNAL_SINGLE_FD_WATCH mode. 230 * 231 * This function does the following: processes all incoming and outgoing data, 232 * processes new connections, processes any timed-out connection, and does 233 * other things required to run webserver. 234 * Once all connections are processed, function returns. 235 * 236 * @param daemon the daemon to run 237 * @return #MHD_SC_OK on success, otherwise 238 * an error code 239 * @ingroup event 240 */ 241 #define MHD_daemon_process_nonblocking(daemon) \ 242 MHD_daemon_process_blocking (daemon, 0) 243 244 245 /** 246 * Add another client connection to the set of connections managed by 247 * MHD. This API is usually not needed (since MHD will accept inbound 248 * connections on the server socket). Use this API in special cases, 249 * for example if your HTTP server is behind NAT and needs to connect 250 * out to the HTTP client, or if you are building a proxy. 251 * 252 * The given client socket will be managed (and closed!) by MHD after 253 * this call and must no longer be used directly by the application 254 * afterwards. 255 * The client socket will be closed by MHD even if error returned. 256 * 257 * @param daemon daemon that manages the connection 258 * @param client_socket socket to manage (MHD will expect 259 * to receive an HTTP request from this socket next). 260 * @param[in] addr IP address of the client 261 * @param addrlen number of bytes in @a addr 262 * @param connection_cntx meta data the application wants to 263 * associate with the new connection object 264 * @return #MHD_SC_OK on success, 265 * error on failure (the @a client_socket is closed) 266 * @ingroup specialized 267 */ 268 MHD_EXTERN_ enum MHD_StatusCode 269 MHD_daemon_add_connection (struct MHD_Daemon *MHD_RESTRICT daemon, 270 MHD_Socket client_socket, 271 size_t addrlen, 272 const struct sockaddr *MHD_RESTRICT addr, 273 void *connection_cntx) 274 MHD_FN_PAR_NONNULL_ (1) 275 MHD_FN_PAR_IN_ (4); 276 277 278 /* ********************* connection options ************** */ 279 280 enum MHD_FIXED_ENUM_APP_SET_ MHD_ConnectionOption 281 { 282 /** 283 * Not a real option. 284 * Should not be used directly. 285 * This value indicates the end of the list of the options. 286 */ 287 MHD_C_O_END = 0 288 , 289 /** 290 * Set custom timeout for the given connection. 291 * Specified as the number of seconds. Use zero for no timeout. 292 * Setting this option resets connection timeout timer. 293 */ 294 MHD_C_O_TIMEOUT = 1 295 , 296 297 298 /* * Sentinel * */ 299 /** 300 * The sentinel value. 301 * This value enforces specific underlying integer type for the enum. 302 * Do not use. 303 */ 304 MHD_C_O_SENTINEL = 65535 305 }; 306 307 308 /** 309 * Dummy-struct for space allocation. 310 * Do not use in application logic. 311 */ 312 struct MHD_ReservedStruct 313 { 314 uint_fast64_t reserved1; 315 void *reserved2; 316 }; 317 318 319 /** 320 * Parameters for MHD connection options 321 */ 322 union MHD_ConnectionOptionValue 323 { 324 /** 325 * Value for #MHD_C_O_TIMEOUT 326 */ 327 unsigned int v_timeout; 328 /** 329 * Reserved member. Do not use. 330 */ 331 struct MHD_ReservedStruct reserved; 332 }; 333 334 /** 335 * Combination of MHD connection option with parameters values 336 */ 337 struct MHD_ConnectionOptionAndValue 338 { 339 /** 340 * The connection configuration option 341 */ 342 enum MHD_ConnectionOption opt; 343 /** 344 * The value for the @a opt option 345 */ 346 union MHD_ConnectionOptionValue val; 347 }; 348 349 #if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT) 350 /** 351 * Set custom timeout for the given connection. 352 * Specified as the number of seconds. Use zero for no timeout. 353 * Setting this option resets connection timeout timer. 354 * @param timeout the in seconds, zero for no timeout 355 * @return the object of struct MHD_ConnectionOptionAndValue with the requested 356 * values 357 */ 358 # define MHD_C_OPTION_TIMEOUT(timeout) \ 359 MHD_NOWARN_COMPOUND_LITERALS_ \ 360 (const struct MHD_ConnectionOptionAndValue) \ 361 { \ 362 .opt = (MHD_C_O_TIMEOUT), \ 363 .val.v_timeout = (timeout) \ 364 } \ 365 MHD_RESTORE_WARN_COMPOUND_LITERALS_ 366 367 /** 368 * Terminate the list of the options 369 * @return the terminating object of struct MHD_ConnectionOptionAndValue 370 */ 371 # define MHD_C_OPTION_TERMINATE() \ 372 MHD_NOWARN_COMPOUND_LITERALS_ \ 373 (const struct MHD_ConnectionOptionAndValue) \ 374 { \ 375 .opt = (MHD_C_O_END) \ 376 } \ 377 MHD_RESTORE_WARN_COMPOUND_LITERALS_ 378 379 #else /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */ 380 MHD_NOWARN_UNUSED_FUNC_ 381 382 /** 383 * Set custom timeout for the given connection. 384 * Specified as the number of seconds. Use zero for no timeout. 385 * Setting this option resets connection timeout timer. 386 * @param timeout the in seconds, zero for no timeout 387 * @return the object of struct MHD_ConnectionOptionAndValue with the requested 388 * values 389 */ 390 static MHD_INLINE struct MHD_ConnectionOptionAndValue 391 MHD_C_OPTION_TIMEOUT (unsigned int timeout) 392 { 393 struct MHD_ConnectionOptionAndValue opt_val; 394 395 opt_val.opt = MHD_C_O_TIMEOUT; 396 opt_val.val.v_timeout = timeout; 397 398 return opt_val; 399 } 400 401 402 /** 403 * Terminate the list of the options 404 * @return the terminating object of struct MHD_ConnectionOptionAndValue 405 */ 406 static MHD_INLINE struct MHD_ConnectionOptionAndValue 407 MHD_C_OPTION_TERMINATE (void) 408 { 409 struct MHD_ConnectionOptionAndValue opt_val; 410 411 opt_val.opt = MHD_C_O_END; 412 413 return opt_val; 414 } 415 416 417 MHD_RESTORE_WARN_UNUSED_FUNC_ 418 #endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */ 419 420 /** 421 * Set the requested options for the connection. 422 * 423 * If any option fail other options may be or may be not applied. 424 * @param connection the connection to set the options 425 * @param[in] options the pointer to the array with the options; 426 * the array processing stops at the first ::MHD_D_O_END 427 * option, but not later than after processing 428 * @a options_max_num entries 429 * @param options_max_num the maximum number of entries in the @a options, 430 * use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing 431 * must stop only at zero-termination option 432 * @return ::MHD_SC_OK on success, 433 * error code otherwise 434 */ 435 MHD_EXTERN_ enum MHD_StatusCode 436 MHD_connection_set_options ( 437 struct MHD_Connection *MHD_RESTRICT connection, 438 const struct MHD_ConnectionOptionAndValue *MHD_RESTRICT options, 439 size_t options_max_num) 440 MHD_FN_PAR_NONNULL_ALL_; 441 442 443 /** 444 * Set the requested single option for the connection. 445 * 446 * @param connection the connection to set the options 447 * @param[in] option_ptr the pointer to the option 448 * @return ::MHD_SC_OK on success, 449 * error code otherwise 450 */ 451 #define MHD_connection_set_option(connection, option_ptr) \ 452 MHD_connection_set_options (connection, options_ptr, 1) 453 454 455 /* *INDENT-OFF* */ 456 #ifdef MHD_USE_VARARG_MACROS 457 MHD_NOWARN_VARIADIC_MACROS_ 458 # if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_COMP_LIT_FUNC_PARAMS \ 459 ) 460 /** 461 * Set the requested options for the connection. 462 * 463 * If any option fail other options may be or may be not applied. 464 * 465 * It should be used with helpers that creates required options, for example: 466 * 467 * MHD_CONNECTION_SET_OPTIONS(d, MHD_C_OPTION_TIMEOUT(30)) 468 * 469 * @param connection the connection to set the options 470 * @param ... the list of the options, each option must be created 471 * by helpers MHD_C_OPTION_NameOfOption(option_value) 472 * @return ::MHD_SC_OK on success, 473 * error code otherwise 474 */ 475 # define MHD_CONNECTION_SET_OPTIONS(connection,...) \ 476 MHD_NOWARN_COMPOUND_LITERALS_ \ 477 MHD_connection_set_options ( \ 478 daemon, \ 479 ((const struct MHD_ConnectionOptionAndValue []) \ 480 {__VA_ARGS__, MHD_C_OPTION_TERMINATE ()}), \ 481 MHD_OPTIONS_ARRAY_MAX_SIZE) \ 482 MHD_RESTORE_WARN_COMPOUND_LITERALS_ 483 # elif defined(MHD_USE_CPP_INIT_LIST) 484 MHD_C_DECLRATIONS_FINISH_HERE_ 485 # include <vector> 486 MHD_C_DECLRATIONS_START_HERE_ 487 /** 488 * Set the requested options for the connection. 489 * 490 * If any option fail other options may be or may be not applied. 491 * 492 * It should be used with helpers that creates required options, for example: 493 * 494 * MHD_CONNECTION_SET_OPTIONS(d, MHD_C_OPTION_TIMEOUT(30)) 495 * 496 * @param connection the connection to set the options 497 * @param ... the list of the options, each option must be created 498 * by helpers MHD_C_OPTION_NameOfOption(option_value) 499 * @return ::MHD_SC_OK on success, 500 * error code otherwise 501 */ 502 # define MHD_CONNECTION_SET_OPTIONS(daemon,...) \ 503 MHD_NOWARN_CPP_INIT_LIST_ \ 504 MHD_daemon_set_options ( \ 505 daemon, \ 506 (std::vector<struct MHD_ConnectionOptionAndValue> \ 507 {__VA_ARGS__,MHD_C_OPTION_TERMINATE ()}).data (), \ 508 MHD_OPTIONS_ARRAY_MAX_SIZE) \ 509 MHD_RESTORE_WARN_CPP_INIT_LIST_ 510 # endif 511 MHD_RESTORE_WARN_VARIADIC_MACROS_ 512 #endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */ 513 /* *INDENT-ON* */ 514 515 516 /* **************** Request handling functions ***************** */ 517 518 519 /** 520 * The `enum MHD_ValueKind` specifies the source of 521 * the name-value pairs in the HTTP protocol. 522 */ 523 enum MHD_FLAGS_ENUM_ MHD_ValueKind 524 { 525 526 /** 527 * HTTP header. 528 * The 'value' for this kind is mandatory. 529 */ 530 MHD_VK_HEADER = (1u << 0) 531 , 532 /** 533 * Cookies. Note that the original HTTP header containing 534 * the cookie(s) will still be available and intact. 535 * The 'value' for this kind is optional. 536 */ 537 MHD_VK_COOKIE = (1u << 1) 538 , 539 /** 540 * URI query parameter. 541 * The 'value' for this kind is optional. 542 */ 543 MHD_VK_URI_QUERY_PARAM = (1u << 2) 544 , 545 /** 546 * POST data. 547 * This is available only if #MHD_action_parse_post() action is used, 548 * a content encoding is supported by MHD, and only if the posted content 549 * fits within the specified memory buffers. 550 * 551 * @warning The encoding "multipart/form-data" has more fields than just 552 * "name" and "value". See #MHD_request_get_post_data_cb() and 553 * #MHD_request_get_post_data_list(). In particular it could be important 554 * to check used "Transfer-Encoding". While it is deprecated and not used 555 * by modern clients, formally it can be used. 556 */ 557 MHD_VK_POSTDATA = (1u << 3) 558 , 559 /** 560 * HTTP trailer (only for HTTP 1.1 chunked encodings, "footer"). 561 * The 'value' for this kind is mandatory. 562 */ 563 MHD_VK_TRAILER = (1u << 4) 564 , 565 /** 566 * Header and trailer values. 567 */ 568 MHD_VK_HEADER_TRAILER = MHD_VK_HEADER | MHD_VK_TRAILER 569 , 570 /** 571 * Values from URI query parameters or post data. 572 */ 573 MHD_VK_URI_QUERY_POST = MHD_VK_POSTDATA | MHD_VK_URI_QUERY_PARAM 574 }; 575 576 /** 577 * Name with value pair 578 */ 579 struct MHD_NameAndValue 580 { 581 /** 582 * The name (key) of the field. 583 * The pointer to the C string must never be NULL. 584 * Some types (kinds) allow empty strings. 585 */ 586 struct MHD_String name; 587 /** 588 * The value of the field. 589 * Some types (kinds) allow absence of the value. The absence is indicated 590 * by NULL pointer to the C string. 591 */ 592 struct MHD_StringNullable value; 593 }; 594 595 /** 596 * Name, value and kind (type) of data 597 */ 598 struct MHD_NameValueKind 599 { 600 /** 601 * The name and the value of the field 602 */ 603 struct MHD_NameAndValue nv; 604 /** 605 * The kind (type) of the field 606 */ 607 enum MHD_ValueKind kind; 608 }; 609 610 /** 611 * Iterator over name-value pairs. This iterator can be used to 612 * iterate over all of the cookies, headers, footers or POST-data fields 613 * of a request. 614 * 615 * The @a nv pointer is valid only until return from this function. 616 * 617 * The strings in @a nv are valid until any MHD_Action or MHD_UploadAction 618 * is provided. 619 * If the data is needed beyond this point, it should be copied. 620 * 621 * @param cls closure 622 * @param nv the name and the value of the element, the pointer is valid only until 623 * return from this function 624 * @param kind the type (kind) of the element 625 * @return #MHD_YES to continue iterating, 626 * #MHD_NO to abort the iteration 627 * @ingroup request 628 */ 629 typedef enum MHD_Bool 630 (MHD_FN_PAR_NONNULL_ (3) 631 *MHD_NameValueIterator)(void *cls, 632 enum MHD_ValueKind kind, 633 const struct MHD_NameAndValue *nv); 634 635 636 /** 637 * Get all of the headers (or other kind of request data) via callback. 638 * 639 * @param[in,out] request request to get values from 640 * @param kind types of values to iterate over, can be a bitmask 641 * @param iterator callback to call on each header; 642 * maybe NULL (then just count headers) 643 * @param iterator_cls extra argument to @a iterator 644 * @return number of entries iterated over 645 * @ingroup request 646 */ 647 MHD_EXTERN_ size_t 648 MHD_request_get_values_cb (struct MHD_Request *request, 649 enum MHD_ValueKind kind, 650 MHD_NameValueIterator iterator, 651 void *iterator_cls) 652 MHD_FN_PAR_NONNULL_ (1); 653 654 655 /** 656 * Get all of the headers (or other kind of request data) from the request. 657 * 658 * The pointers to the strings in @a elements are valid until any 659 * MHD_Action or MHD_UploadAction is provided. If the data is needed beyond 660 * this point, it should be copied. 661 * 662 * @param[in] request request to get values from 663 * @param kind the types of values to get, can be a bitmask 664 * @param num_elements the number of elements in @a elements array 665 * @param[out] elements the array of @a num_elements strings to be filled with 666 * the key-value pairs; if @a request has more elements 667 * than @a num_elements than any @a num_elements are 668 * stored 669 * @return the number of elements stored in @a elements, the 670 * number cannot be larger then @a num_elements, 671 * zero if there is no such values or any error occurs 672 */ 673 MHD_EXTERN_ size_t 674 MHD_request_get_values_list ( 675 struct MHD_Request *request, 676 enum MHD_ValueKind kind, 677 size_t num_elements, 678 struct MHD_NameValueKind elements[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)]) 679 MHD_FN_PAR_NONNULL_ (1) 680 MHD_FN_PAR_NONNULL_ (4) MHD_FN_PAR_OUT_SIZE_ (4,3); 681 682 683 /** 684 * Get a particular header (or other kind of request data) value. 685 * If multiple values match the kind, return any one of them. 686 * 687 * The data in the @a value_out is valid until any MHD_Action or 688 * MHD_UploadAction is provided. If the data is needed beyond this point, 689 * it should be copied. 690 * 691 * @param request request to get values from 692 * @param kind what kind of value are we looking for 693 * @param key the name of the value looking for (used for case-insensetive 694 * match), empty to lookup 'trailing' value without a key 695 * @param[out] value_out set to the value of the header if succeed, 696 * the @a cstr pointer could be NULL even if succeed 697 * if the requested item found, but has no value 698 * @return #MHD_YES if succeed, the @a value_out is set; 699 * #MHD_NO if no such item was found, the @a value_out string pointer 700 * set to NULL 701 * @ingroup request 702 */ 703 MHD_EXTERN_ enum MHD_Bool 704 MHD_request_get_value (struct MHD_Request *MHD_RESTRICT request, 705 enum MHD_ValueKind kind, 706 const char *MHD_RESTRICT key, 707 struct MHD_StringNullable *MHD_RESTRICT value_out) 708 MHD_FN_PAR_NONNULL_ (1) 709 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3) 710 MHD_FN_PAR_OUT_ (4); 711 712 713 /** 714 * @brief Status codes defined for HTTP responses. 715 * 716 * @defgroup httpcode HTTP response codes 717 * @{ 718 */ 719 /* Registry export date: 2023-09-29 */ 720 /* See http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */ 721 enum MHD_FIXED_ENUM_APP_SET_ MHD_HTTP_StatusCode 722 { 723 /* 100 "Continue". RFC9110, Section 15.2.1. */ 724 MHD_HTTP_STATUS_CONTINUE = 100 725 , 726 /* 101 "Switching Protocols". RFC9110, Section 15.2.2. */ 727 MHD_HTTP_STATUS_SWITCHING_PROTOCOLS = 101 728 , 729 /* 102 "Processing". RFC2518. */ 730 MHD_HTTP_STATUS_PROCESSING = 102 731 , 732 /* 103 "Early Hints". RFC8297. */ 733 MHD_HTTP_STATUS_EARLY_HINTS = 103 734 , 735 736 /* 200 "OK". RFC9110, Section 15.3.1. */ 737 MHD_HTTP_STATUS_OK = 200 738 , 739 /* 201 "Created". RFC9110, Section 15.3.2. */ 740 MHD_HTTP_STATUS_CREATED = 201 741 , 742 /* 202 "Accepted". RFC9110, Section 15.3.3. */ 743 MHD_HTTP_STATUS_ACCEPTED = 202 744 , 745 /* 203 "Non-Authoritative Information". RFC9110, Section 15.3.4. */ 746 MHD_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203 747 , 748 /* 204 "No Content". RFC9110, Section 15.3.5. */ 749 MHD_HTTP_STATUS_NO_CONTENT = 204 750 , 751 /* 205 "Reset Content". RFC9110, Section 15.3.6. */ 752 MHD_HTTP_STATUS_RESET_CONTENT = 205 753 , 754 /* 206 "Partial Content". RFC9110, Section 15.3.7. */ 755 MHD_HTTP_STATUS_PARTIAL_CONTENT = 206 756 , 757 /* 207 "Multi-Status". RFC4918. */ 758 MHD_HTTP_STATUS_MULTI_STATUS = 207 759 , 760 /* 208 "Already Reported". RFC5842. */ 761 MHD_HTTP_STATUS_ALREADY_REPORTED = 208 762 , 763 764 /* 226 "IM Used". RFC3229. */ 765 MHD_HTTP_STATUS_IM_USED = 226 766 , 767 768 /* 300 "Multiple Choices". RFC9110, Section 15.4.1. */ 769 MHD_HTTP_STATUS_MULTIPLE_CHOICES = 300 770 , 771 /* 301 "Moved Permanently". RFC9110, Section 15.4.2. */ 772 MHD_HTTP_STATUS_MOVED_PERMANENTLY = 301 773 , 774 /* 302 "Found". RFC9110, Section 15.4.3. */ 775 MHD_HTTP_STATUS_FOUND = 302 776 , 777 /* 303 "See Other". RFC9110, Section 15.4.4. */ 778 MHD_HTTP_STATUS_SEE_OTHER = 303 779 , 780 /* 304 "Not Modified". RFC9110, Section 15.4.5. */ 781 MHD_HTTP_STATUS_NOT_MODIFIED = 304 782 , 783 /* 305 "Use Proxy". RFC9110, Section 15.4.6. */ 784 MHD_HTTP_STATUS_USE_PROXY = 305 785 , 786 /* 306 "Switch Proxy". Not used! RFC9110, Section 15.4.7. */ 787 MHD_HTTP_STATUS_SWITCH_PROXY = 306 788 , 789 /* 307 "Temporary Redirect". RFC9110, Section 15.4.8. */ 790 MHD_HTTP_STATUS_TEMPORARY_REDIRECT = 307 791 , 792 /* 308 "Permanent Redirect". RFC9110, Section 15.4.9. */ 793 MHD_HTTP_STATUS_PERMANENT_REDIRECT = 308 794 , 795 796 /* 400 "Bad Request". RFC9110, Section 15.5.1. */ 797 MHD_HTTP_STATUS_BAD_REQUEST = 400 798 , 799 /* 401 "Unauthorized". RFC9110, Section 15.5.2. */ 800 MHD_HTTP_STATUS_UNAUTHORIZED = 401 801 , 802 /* 402 "Payment Required". RFC9110, Section 15.5.3. */ 803 MHD_HTTP_STATUS_PAYMENT_REQUIRED = 402 804 , 805 /* 403 "Forbidden". RFC9110, Section 15.5.4. */ 806 MHD_HTTP_STATUS_FORBIDDEN = 403 807 , 808 /* 404 "Not Found". RFC9110, Section 15.5.5. */ 809 MHD_HTTP_STATUS_NOT_FOUND = 404 810 , 811 /* 405 "Method Not Allowed". RFC9110, Section 15.5.6. */ 812 MHD_HTTP_STATUS_METHOD_NOT_ALLOWED = 405 813 , 814 /* 406 "Not Acceptable". RFC9110, Section 15.5.7. */ 815 MHD_HTTP_STATUS_NOT_ACCEPTABLE = 406 816 , 817 /* 407 "Proxy Authentication Required". RFC9110, Section 15.5.8. */ 818 MHD_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407 819 , 820 /* 408 "Request Timeout". RFC9110, Section 15.5.9. */ 821 MHD_HTTP_STATUS_REQUEST_TIMEOUT = 408 822 , 823 /* 409 "Conflict". RFC9110, Section 15.5.10. */ 824 MHD_HTTP_STATUS_CONFLICT = 409 825 , 826 /* 410 "Gone". RFC9110, Section 15.5.11. */ 827 MHD_HTTP_STATUS_GONE = 410 828 , 829 /* 411 "Length Required". RFC9110, Section 15.5.12. */ 830 MHD_HTTP_STATUS_LENGTH_REQUIRED = 411 831 , 832 /* 412 "Precondition Failed". RFC9110, Section 15.5.13. */ 833 MHD_HTTP_STATUS_PRECONDITION_FAILED = 412 834 , 835 /* 413 "Content Too Large". RFC9110, Section 15.5.14. */ 836 MHD_HTTP_STATUS_CONTENT_TOO_LARGE = 413 837 , 838 /* 414 "URI Too Long". RFC9110, Section 15.5.15. */ 839 MHD_HTTP_STATUS_URI_TOO_LONG = 414 840 , 841 /* 415 "Unsupported Media Type". RFC9110, Section 15.5.16. */ 842 MHD_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415 843 , 844 /* 416 "Range Not Satisfiable". RFC9110, Section 15.5.17. */ 845 MHD_HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416 846 , 847 /* 417 "Expectation Failed". RFC9110, Section 15.5.18. */ 848 MHD_HTTP_STATUS_EXPECTATION_FAILED = 417 849 , 850 851 852 /* 421 "Misdirected Request". RFC9110, Section 15.5.20. */ 853 MHD_HTTP_STATUS_MISDIRECTED_REQUEST = 421 854 , 855 /* 422 "Unprocessable Content". RFC9110, Section 15.5.21. */ 856 MHD_HTTP_STATUS_UNPROCESSABLE_CONTENT = 422 857 , 858 /* 423 "Locked". RFC4918. */ 859 MHD_HTTP_STATUS_LOCKED = 423 860 , 861 /* 424 "Failed Dependency". RFC4918. */ 862 MHD_HTTP_STATUS_FAILED_DEPENDENCY = 424 863 , 864 /* 425 "Too Early". RFC8470. */ 865 MHD_HTTP_STATUS_TOO_EARLY = 425 866 , 867 /* 426 "Upgrade Required". RFC9110, Section 15.5.22. */ 868 MHD_HTTP_STATUS_UPGRADE_REQUIRED = 426 869 , 870 871 /* 428 "Precondition Required". RFC6585. */ 872 MHD_HTTP_STATUS_PRECONDITION_REQUIRED = 428 873 , 874 /* 429 "Too Many Requests". RFC6585. */ 875 MHD_HTTP_STATUS_TOO_MANY_REQUESTS = 429 876 , 877 878 /* 431 "Request Header Fields Too Large". RFC6585. */ 879 MHD_HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 880 , 881 882 /* 451 "Unavailable For Legal Reasons". RFC7725. */ 883 MHD_HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451 884 , 885 886 /* 500 "Internal Server Error". RFC9110, Section 15.6.1. */ 887 MHD_HTTP_STATUS_INTERNAL_SERVER_ERROR = 500 888 , 889 /* 501 "Not Implemented". RFC9110, Section 15.6.2. */ 890 MHD_HTTP_STATUS_NOT_IMPLEMENTED = 501 891 , 892 /* 502 "Bad Gateway". RFC9110, Section 15.6.3. */ 893 MHD_HTTP_STATUS_BAD_GATEWAY = 502 894 , 895 /* 503 "Service Unavailable". RFC9110, Section 15.6.4. */ 896 MHD_HTTP_STATUS_SERVICE_UNAVAILABLE = 503 897 , 898 /* 504 "Gateway Timeout". RFC9110, Section 15.6.5. */ 899 MHD_HTTP_STATUS_GATEWAY_TIMEOUT = 504 900 , 901 /* 505 "HTTP Version Not Supported". RFC9110, Section 15.6.6. */ 902 MHD_HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505 903 , 904 /* 506 "Variant Also Negotiates". RFC2295. */ 905 MHD_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES = 506 906 , 907 /* 507 "Insufficient Storage". RFC4918. */ 908 MHD_HTTP_STATUS_INSUFFICIENT_STORAGE = 507 909 , 910 /* 508 "Loop Detected". RFC5842. */ 911 MHD_HTTP_STATUS_LOOP_DETECTED = 508 912 , 913 914 /* 510 "Not Extended". (OBSOLETED) RFC2774; status-change-http-experiments-to-historic. */ 915 MHD_HTTP_STATUS_NOT_EXTENDED = 510 916 , 917 /* 511 "Network Authentication Required". RFC6585. */ 918 MHD_HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511 919 , 920 921 922 /* Not registered non-standard codes */ 923 /* 449 "Reply With". MS IIS extension. */ 924 MHD_HTTP_STATUS_RETRY_WITH = 449 925 , 926 927 /* 450 "Blocked by Windows Parental Controls". MS extension. */ 928 MHD_HTTP_STATUS_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450 929 , 930 931 /* 509 "Bandwidth Limit Exceeded". Apache extension. */ 932 MHD_HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509 933 }; 934 935 936 /** 937 * Returns the string status for a response code. 938 * 939 * This function works for @b HTTP status code, not for @b MHD error codes/ 940 * @param code the HTTP code to get text representation for 941 * @return the pointer to the text representation, 942 * NULL if HTTP status code in not known. 943 */ 944 MHD_EXTERN_ const struct MHD_String * 945 MHD_HTTP_status_code_to_string (enum MHD_HTTP_StatusCode code) 946 MHD_FN_CONST_; 947 948 /** 949 * Get the pointer to the C string for the HTTP response code, never NULL. 950 */ 951 #define MHD_HTTP_status_code_to_string_lazy(code) \ 952 (MHD_HTTP_status_code_to_string ((code)) ? \ 953 ((MHD_HTTP_status_code_to_string (code))->cstr) : ("[No status]") ) 954 955 956 /** @} */ /* end of group httpcode */ 957 958 #ifndef MHD_HTTP_PROTOCOL_VER_DEFINED 959 960 /** 961 * @brief HTTP protocol versions 962 * @defgroup versions HTTP versions 963 * @{ 964 */ 965 enum MHD_FIXED_ENUM_MHD_SET_ MHD_HTTP_ProtocolVersion 966 { 967 MHD_HTTP_VERSION_INVALID = 0 968 , 969 MHD_HTTP_VERSION_1_0 = 1 970 , 971 MHD_HTTP_VERSION_1_1 = 2 972 , 973 MHD_HTTP_VERSION_2 = 3 974 , 975 MHD_HTTP_VERSION_3 = 4 976 , 977 MHD_HTTP_VERSION_FUTURE = 255 978 }; 979 980 #define MHD_HTTP_PROTOCOL_VER_DEFINED 1 981 #endif /* ! MHD_HTTP_PROTOCOL_VER_DEFINED */ 982 983 /** 984 * Return the string representation of the requested HTTP version. 985 * Note: this is suitable mainly for logging and similar proposes as 986 * HTTP/2 (and later) is not used inside the HTTP protocol. 987 * @param pv the protocol version 988 * @return the string representation of the protocol version, 989 * NULL for invalid values 990 */ 991 MHD_EXTERN_ const struct MHD_String * 992 MHD_protocol_version_to_string (enum MHD_HTTP_ProtocolVersion pv) 993 MHD_FN_CONST_; 994 995 /** 996 * HTTP/1.0 identification string 997 */ 998 #define MHD_HTTP_VERSION_1_0_STR "HTTP/1.0" 999 /** 1000 * HTTP/1.1 identification string 1001 */ 1002 #define MHD_HTTP_VERSION_1_1_STR "HTTP/1.1" 1003 /** 1004 * HTTP/2 identification string. 1005 * Not used by the HTTP protocol (except non-TLS handshake), useful for logs and 1006 * similar proposes. 1007 */ 1008 #define MHD_HTTP_VERSION_2_STR "HTTP/2" 1009 /** 1010 * HTTP/3 identification string. 1011 * Not used by the HTTP protocol, useful for logs and similar proposes. 1012 */ 1013 #define MHD_HTTP_VERSION_3_STR "HTTP/3" 1014 1015 /** @} */ /* end of group versions */ 1016 1017 1018 /** 1019 * Resume handling of network data for suspended request. 1020 * It is safe to resume a suspended request at any time. 1021 * Calling this function on a request that was not previously suspended will 1022 * result in undefined behaviour. 1023 * 1024 * @param[in,out] request the request to resume 1025 */ 1026 MHD_EXTERN_ void 1027 MHD_request_resume (struct MHD_Request *request) 1028 MHD_FN_PAR_NONNULL_ALL_; 1029 1030 1031 /* ************** Action and Response manipulation functions **************** */ 1032 1033 /** 1034 * @defgroup response Response objects control 1035 */ 1036 1037 1038 /** 1039 * Name with value pair as C strings 1040 */ 1041 struct MHD_NameValueCStr 1042 { 1043 /** 1044 * The name (key) of the field. 1045 * Must never be NULL. 1046 * Some types (kinds) allow empty strings. 1047 */ 1048 const char *name; 1049 /** 1050 * The value of the field. 1051 * Some types (kinds) allow absence of the value. The absence is indicated 1052 * by NULL pointer. 1053 */ 1054 const char *value; 1055 }; 1056 1057 /** 1058 * Data transmitted in response to an HTTP request. 1059 * Usually the final action taken in response to 1060 * receiving a request. 1061 */ 1062 struct MHD_Response; 1063 1064 1065 /** 1066 * Suspend handling of network data for a given request. This can 1067 * be used to dequeue a request from MHD's event loop for a while. 1068 * 1069 * Suspended requests continue to count against the total number of 1070 * requests allowed (per daemon, as well as per IP, if such limits 1071 * are set). Suspended requests will NOT time out; timeouts will 1072 * restart when the request handling is resumed. While a 1073 * request is suspended, MHD may not detect disconnects by the 1074 * client. 1075 * 1076 * At most one action can be created for any request. 1077 * 1078 * @param[in,out] request the request for which the action is generated 1079 * @return action to cause a request to be suspended, 1080 * NULL if any action has been already created for the @a request 1081 * @ingroup action 1082 */ 1083 MHD_EXTERN_ const struct MHD_Action * 1084 MHD_action_suspend (struct MHD_Request *request) 1085 MHD_FN_PAR_NONNULL_ALL_; 1086 1087 1088 /** 1089 * Converts a @a response to an action. If #MHD_R_O_REUSABLE 1090 * is not set, the reference to the @a response is consumed 1091 * by the conversion. If #MHD_R_O_REUSABLE is #MHD_YES, 1092 * then the @a response can be used again to create actions in 1093 * the future. 1094 * However, the @a response is frozen by this step and 1095 * must no longer be modified (i.e. by setting headers). 1096 * 1097 * At most one action can be created for any request. 1098 * 1099 * @param request the request to create the action for 1100 * @param[in] response the response to convert, 1101 * if NULL then this function is equivalent to 1102 * #MHD_action_abort_connection() call 1103 * @return pointer to the action, the action must be consumed 1104 * otherwise response object may leak; 1105 * NULL if failed (no memory) or if any action has been already 1106 * created for the @a request; 1107 * when failed the response object is consumed and need not 1108 * to be "destroyed" 1109 * @ingroup action 1110 */ 1111 MHD_EXTERN_ const struct MHD_Action * 1112 MHD_action_from_response (struct MHD_Request *MHD_RESTRICT request, 1113 struct MHD_Response *MHD_RESTRICT response) 1114 MHD_FN_PAR_NONNULL_ (1); 1115 1116 1117 /** 1118 * Action telling MHD to close the connection hard 1119 * (kind-of breaking HTTP specification). 1120 * 1121 * @param req the request to make an action 1122 * @return action operation, always NULL 1123 * @ingroup action 1124 */ 1125 #define MHD_action_abort_request(req) \ 1126 MHD_STATIC_CAST_ (const struct MHD_Action *, NULL) 1127 1128 1129 /** 1130 * Set the requested options for the response. 1131 * 1132 * If any option fail other options may be or may be not applied. 1133 * @param response the response to set the options 1134 * @param[in] options the pointer to the array with the options; 1135 * the array processing stops at the first ::MHD_D_O_END 1136 * option, but not later than after processing 1137 * @a options_max_num entries 1138 * @param options_max_num the maximum number of entries in the @a options, 1139 * use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing 1140 * must stop only at zero-termination option 1141 * @return ::MHD_SC_OK on success, 1142 * error code otherwise 1143 */ 1144 MHD_EXTERN_ enum MHD_StatusCode 1145 MHD_response_set_options ( 1146 struct MHD_Response *MHD_RESTRICT response, 1147 const struct MHD_ResponseOptionAndValue *MHD_RESTRICT options, 1148 size_t options_max_num) 1149 MHD_FN_PAR_NONNULL_ALL_; 1150 1151 1152 /** 1153 * Set the requested single option for the response. 1154 * 1155 * @param response the response to set the option 1156 * @param[in] option_ptr the pointer to the option 1157 * @return ::MHD_SC_OK on success, 1158 * error code otherwise 1159 * @ingroup response 1160 */ 1161 #define MHD_response_set_option(response,option_ptr) \ 1162 MHD_response_set_options (response,option_ptr,1) 1163 1164 1165 /* *INDENT-OFF* */ 1166 #ifdef MHD_USE_VARARG_MACROS 1167 MHD_NOWARN_VARIADIC_MACROS_ 1168 # if defined(MHD_USE_COMPOUND_LITERALS) && \ 1169 defined(MHD_USE_COMP_LIT_FUNC_PARAMS) 1170 /** 1171 * Set the requested options for the response. 1172 * 1173 * If any option fail other options may be or may be not applied. 1174 * 1175 * It should be used with helpers that creates required options, for example: 1176 * 1177 * MHD_RESPONE_SET_OPTIONS(d, MHD_R_OPTION_REUSABLE(MHD_YES), 1178 * MHD_R_OPTION_TERMINATION_CALLBACK(func, cls)) 1179 * 1180 * @param response the response to set the option 1181 * @param ... the list of the options, each option must be created 1182 * by helpers MHD_RESPONSE_OPTION_NameOfOption(option_value) 1183 * @return ::MHD_SC_OK on success, 1184 * error code otherwise 1185 */ 1186 # define MHD_RESPONSE_SET_OPTIONS(response,...) \ 1187 MHD_NOWARN_COMPOUND_LITERALS_ \ 1188 MHD_response_set_options ( \ 1189 response, \ 1190 ((const struct MHD_ResponseOptionAndValue[]) \ 1191 {__VA_ARGS__, MHD_R_OPTION_TERMINATE ()}), \ 1192 MHD_OPTIONS_ARRAY_MAX_SIZE) \ 1193 MHD_RESTORE_WARN_COMPOUND_LITERALS_ 1194 # elif defined(MHD_USE_CPP_INIT_LIST) 1195 MHD_C_DECLRATIONS_FINISH_HERE_ 1196 # include <vector> 1197 MHD_C_DECLRATIONS_START_HERE_ 1198 /** 1199 * Set the requested options for the response. 1200 * 1201 * If any option fail other options may be or may be not applied. 1202 * 1203 * It should be used with helpers that creates required options, for example: 1204 * 1205 * MHD_RESPONE_SET_OPTIONS(d, MHD_R_OPTION_REUSABLE(MHD_YES), 1206 * MHD_R_OPTION_TERMINATION_CALLBACK(func, cls)) 1207 * 1208 * @param response the response to set the option 1209 * @param ... the list of the options, each option must be created 1210 * by helpers MHD_RESPONSE_OPTION_NameOfOption(option_value) 1211 * @return ::MHD_SC_OK on success, 1212 * error code otherwise 1213 */ 1214 # define MHD_RESPONSE_SET_OPTIONS(response,...) \ 1215 MHD_NOWARN_CPP_INIT_LIST_ \ 1216 MHD_response_set_options ( \ 1217 response, \ 1218 (std::vector<struct MHD_ResponseOptionAndValue> \ 1219 {__VA_ARGS__,MHD_R_OPTION_TERMINATE ()}).data (), \ 1220 MHD_OPTIONS_ARRAY_MAX_SIZE) \ 1221 MHD_RESTORE_WARN_CPP_INIT_LIST_ 1222 # endif 1223 MHD_RESTORE_WARN_VARIADIC_MACROS_ 1224 #endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */ 1225 /* *INDENT-ON* */ 1226 1227 #ifndef MHD_FREECALLBACK_DEFINED 1228 1229 /** 1230 * This method is called by libmicrohttpd when response with dynamic content 1231 * is being destroyed. It should be used to free resources associated 1232 * with the dynamic content. 1233 * 1234 * @param[in] free_cls closure 1235 * @ingroup response 1236 */ 1237 typedef void 1238 (*MHD_FreeCallback) (void *free_cls); 1239 1240 #define MHD_FREECALLBACK_DEFINED 1 1241 #endif /* ! MHD_FREECALLBACK_DEFINED */ 1242 #ifndef MHD_DYNCONTENTZCIOVEC_DEFINED 1243 1244 1245 /** 1246 * Structure for iov type of the response. 1247 * Used for zero-copy response content data. 1248 */ 1249 struct MHD_DynContentZCIoVec 1250 { 1251 /** 1252 * The number of elements in @a iov 1253 */ 1254 unsigned int iov_count; 1255 /** 1256 * The pointer to the array with @a iov_count elements. 1257 */ 1258 const struct MHD_IoVec *iov; 1259 /** 1260 * The callback to free resources. 1261 * It is called once the full array of iov elements is sent. 1262 * No callback is called if NULL. 1263 */ 1264 MHD_FreeCallback iov_fcb; 1265 /** 1266 * The parameter for @a iov_fcb 1267 */ 1268 void *iov_fcb_cls; 1269 }; 1270 1271 #define MHD_DYNCONTENTZCIOVEC_DEFINED 1 1272 #endif /* ! MHD_DYNCONTENTZCIOVEC_DEFINED */ 1273 1274 /** 1275 * The action type returned by Dynamic Content Creator callback 1276 */ 1277 struct MHD_DynamicContentCreatorAction; 1278 1279 /** 1280 * The context used for Dynamic Content Creator callback 1281 */ 1282 struct MHD_DynamicContentCreatorContext; 1283 1284 1285 /** 1286 * Create "continue processing" action with optional chunk-extension. 1287 * The data is provided in the buffer and/or in the zero-copy @a iov_data. 1288 * 1289 * If data is provided both in the buffer and @a ivo_data then 1290 * data in the buffer sent first, following the iov data. 1291 * The total size of the data in the buffer and in @a iov_data must 1292 * be non-zero. 1293 * If response content size is known and total size of content provided earlier 1294 * for this request combined with the size provided by this action is larger 1295 * then known response content size, then NULL is returned. 1296 * 1297 * At most one DCC action can be created for one content callback. 1298 * 1299 * @param[in,out] ctx the pointer the context as provided to the callback 1300 * @param data_size the amount of the data placed to the provided buffer, 1301 * cannot be larger than provided buffer size, 1302 * must be non-zero if @a iov_data is NULL or has no data, 1303 * @param iov_data the optional pointer to the iov data, 1304 * must not be NULL and have non-zero size data if @a data_size 1305 * is zero, 1306 * @param chunk_ext the optional pointer to chunk extension string, 1307 * can be NULL to not use chunk extension, 1308 * ignored if chunked encoding is not used 1309 * @return the pointer to the action if succeed, 1310 * NULL (equivalent of MHD_DCC_action_abort())in case of any error 1311 */ 1312 MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction * 1313 MHD_DCC_action_continue_zc ( 1314 struct MHD_DynamicContentCreatorContext *ctx, 1315 size_t data_size, 1316 const struct MHD_DynContentZCIoVec *iov_data, 1317 const char *MHD_RESTRICT chunk_ext) 1318 MHD_FN_PAR_NONNULL_ (1) 1319 MHD_FN_PAR_CSTR_ (4); 1320 1321 1322 /** 1323 * Create "continue processing" action with optional chunk-extension. 1324 * The data is provided in the buffer. 1325 * 1326 * At most one DCC action can be created for one content callback. 1327 * 1328 * @param[in,out] ctx the pointer the context as provided to the callback 1329 * @param data_size the amount of the data placed to the provided buffer (not @a iov_data), 1330 * cannot be larger than provided buffer size, 1331 * must be non-zero. 1332 * @param chunk_ext the optional pointer to chunk extension string, 1333 * can be NULL to not use chunk extension, 1334 * ignored if chunked encoding is not used 1335 * @return the pointer to the action if succeed, 1336 * NULL (equivalent of MHD_DCC_action_abort())in case of any error 1337 */ 1338 #define MHD_DCC_action_continue_ce(ctx,data_size,chunk_ext) \ 1339 MHD_DCC_action_continue_zc ((ctx), (data_size), NULL, (chunk_ext)) 1340 1341 1342 /** 1343 * Create "continue processing" action, the data is provided in the buffer. 1344 * 1345 * At most one DCC action can be created for one content callback. 1346 * 1347 * @param[in,out] ctx the pointer the context as provided to the callback 1348 * @param data_size the amount of the data placed to the provided buffer; 1349 * cannot be larger than provided buffer size, 1350 * must be non-zero. 1351 * 1352 * @return the pointer to the action if succeed, 1353 * NULL (equivalent of MHD_DCC_action_abort())in case of any error 1354 */ 1355 #define MHD_DCC_action_continue(ctx,data_size) \ 1356 MHD_DCC_action_continue_ce ((ctx), (data_size), NULL) 1357 1358 1359 /** 1360 * Create "finished" action with optional footers. 1361 * If function failed for any reason, the action is automatically 1362 * set to "stop with error". 1363 * 1364 * At most one DCC action can be created for one content callback. 1365 * 1366 * @param[in,out] ctx the pointer the context as provided to the callback 1367 * @param num_footers number of elements in the @a footers array, 1368 * must be zero if @a footers is NULL 1369 * @param footers the optional pointer to the array of the footers (the strings 1370 * are copied and does not need to be valid after return from 1371 * this function), 1372 * can be NULL if @a num_footers is zero 1373 * @return the pointer to the action if succeed, 1374 * NULL (equivalent of MHD_DCC_action_abort())in case of any error 1375 */ 1376 MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction * 1377 MHD_DCC_action_finish_with_footer ( 1378 struct MHD_DynamicContentCreatorContext *ctx, 1379 size_t num_footers, 1380 const struct MHD_NameValueCStr *MHD_RESTRICT footers) 1381 MHD_FN_PAR_NONNULL_ (1); 1382 1383 1384 /** 1385 * Create "finished" action. 1386 * If function failed for any reason, the action is automatically 1387 * set to "stop with error". 1388 * 1389 * At most one DCC action can be created for one content callback. 1390 * 1391 * @param[in,out] ctx the pointer the context as provided to the callback 1392 * @return the pointer to the action if succeed, 1393 * NULL (equivalent of MHD_DCC_action_abort())in case of any error 1394 */ 1395 #define MHD_DCC_action_finish(ctx) \ 1396 MHD_DCC_action_finish_with_footer ((ctx), 0, NULL) 1397 1398 1399 /** 1400 * Create "suspend" action. 1401 * If function failed for any reason, the action is automatically 1402 * set to "stop with error". 1403 * 1404 * At most one DCC action can be created for one content callback. 1405 * 1406 * @param[in,out] ctx the pointer the context as provided to the callback 1407 * @return the pointer to the action if succeed, 1408 * NULL (equivalent of MHD_DCC_action_abort())in case of any error 1409 */ 1410 MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction * 1411 MHD_DCC_action_suspend (struct MHD_DynamicContentCreatorContext *ctx) 1412 MHD_FN_PAR_NONNULL_ (1); 1413 1414 /** 1415 * Create "stop with error" action. 1416 * @param[in,out] ctx the pointer the context as provided to the callback 1417 * @return always NULL (the action "stop with error") 1418 */ 1419 #define MHD_DCC_action_abort(ctx) \ 1420 MHD_STATIC_CAST_ (const struct MHD_DynamicContentCreatorAction *, NULL) 1421 1422 /** 1423 * Callback used by libmicrohttpd in order to obtain content. The 1424 * callback is to copy at most @a max bytes of content into @a buf or 1425 * provide zero-copy data for #MHD_DCC_action_continue_zc(). 1426 * 1427 * @param dyn_cont_cls closure argument to the callback 1428 * @param ctx the context to produce the action to return, 1429 * the pointer is only valid until the callback returns 1430 * @param pos position in the datastream to access; 1431 * note that if a `struct MHD_Response` object is re-used, 1432 * it is possible for the same content reader to 1433 * be queried multiple times for the same data; 1434 * however, if a `struct MHD_Response` is not re-used, 1435 * libmicrohttpd guarantees that "pos" will be 1436 * the sum of all data sizes provided by this callback 1437 * @param[out] buf where to copy the data 1438 * @param max maximum number of bytes to copy to @a buf (size of @a buf), 1439 if the size of the content of the response is known then size 1440 of the buffer is never larger than amount of the content left 1441 * @return action to use, 1442 * NULL in case of any error (the response will be aborted) 1443 */ 1444 typedef const struct MHD_DynamicContentCreatorAction * 1445 (MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (4) 1446 *MHD_DynamicContentCreator)(void *dyn_cont_cls, 1447 struct MHD_DynamicContentCreatorContext *ctx, 1448 uint_fast64_t pos, 1449 void *buf, 1450 size_t max); 1451 1452 1453 /** 1454 * Create a response. The response object can be extended with 1455 * header information. 1456 * 1457 * @param sc status code to return 1458 * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown 1459 * @param dyn_cont callback to use to obtain response data 1460 * @param dyn_cont_cls extra argument to @a crc 1461 * @param dyn_cont_fc callback to call to free @a dyn_cont_cls resources 1462 * @return NULL on error (i.e. invalid arguments, out of memory) 1463 * FIXME: Call free callback on error? 1464 * @ingroup response 1465 */ 1466 MHD_EXTERN_ struct MHD_Response * 1467 MHD_response_from_callback (enum MHD_HTTP_StatusCode sc, 1468 uint_fast64_t size, 1469 MHD_DynamicContentCreator dyn_cont, 1470 void *dyn_cont_cls, 1471 MHD_FreeCallback dyn_cont_fc); 1472 1473 1474 /** 1475 * Create a response object. The response object can be extended with 1476 * header information. 1477 * 1478 * @param sc status code to use for the response; 1479 * #MHD_HTTP_STATUS_NO_CONTENT is only valid if @a size is 0; 1480 * @param buffer_size the size of the data portion of the response 1481 * @param buffer the @a size bytes containing the response's data portion, 1482 * needs to be valid while the response is used 1483 * @param free_cb the callback to free any allocated data, called 1484 * when response is being destroyed, can be NULL 1485 * to skip the free/cleanup callback; 1486 * @param free_cb_cls the parameter for @a free_cb 1487 * @return NULL on error (i.e. invalid arguments, out of memory) 1488 * on error, @a free_cb is NOT called 1489 * @ingroup response 1490 */ 1491 MHD_EXTERN_ struct MHD_Response * 1492 MHD_response_from_buffer ( 1493 enum MHD_HTTP_StatusCode sc, 1494 size_t buffer_size, 1495 const char *buffer, 1496 MHD_FreeCallback free_cb, 1497 void *free_cb_cls) 1498 MHD_FN_PAR_IN_SIZE_ (3,2); 1499 1500 1501 /** 1502 * Create a response object with body that is a 1503 * statically allocated buffer that never needs to 1504 * be freed as its lifetime exceeds that of the 1505 * daemon. 1506 * 1507 * The response object can be extended with header information and then be used 1508 * any number of times. 1509 * @param sc status code to use for the response 1510 * @param len number of bytes in @a buf 1511 * @param buf buffer with response payload 1512 */ 1513 #define MHD_response_from_buffer_static(sc, len, buf) \ 1514 MHD_response_from_buffer (sc, len, buf, NULL, NULL) 1515 1516 1517 /** 1518 * Create a response object with empty (zero size) body. 1519 * 1520 * The response object can be extended with header information and then be used 1521 * any number of times. 1522 * @param sc status code to use for the response 1523 */ 1524 #define MHD_response_from_empty(sc) \ 1525 MHD_response_from_buffer_static (sc, 0, "") 1526 1527 1528 /** 1529 * Create a response object. The response object can be extended with 1530 * header information. 1531 * 1532 * @param sc status code to use for the response 1533 * @param buffer_size the size of the data portion of the response 1534 * @param buffer the @a size bytes containing the response's data portion, 1535 * an internal copy will be made, there is no need to 1536 * keep this data after return from this function 1537 * @return NULL on error (i.e. invalid arguments, out of memory) 1538 * FIXME: Call free callback on error? 1539 * @ingroup response 1540 */ 1541 MHD_EXTERN_ struct MHD_Response * 1542 MHD_response_from_buffer_copy ( 1543 enum MHD_HTTP_StatusCode sc, 1544 size_t buffer_size, 1545 const char buffer[MHD_FN_PAR_DYN_ARR_SIZE_ (buffer_size)]) 1546 MHD_FN_PAR_IN_SIZE_ (3,2); 1547 1548 1549 /** 1550 * I/O vector type. Provided for use with #MHD_response_from_iovec(). 1551 * @ingroup response 1552 */ 1553 struct MHD_IoVec 1554 { 1555 /** 1556 * The pointer to the memory region for I/O. 1557 */ 1558 const void *iov_base; 1559 1560 /** 1561 * The size in bytes of the memory region for I/O. 1562 */ 1563 size_t iov_len; 1564 }; 1565 1566 1567 /** 1568 * Create a response object with an array of memory buffers 1569 * used as the response body. 1570 * 1571 * The response object can be extended with header information. 1572 * 1573 * If response object is used to answer HEAD request then the body 1574 * of the response is not used, while all headers (including automatic 1575 * headers) are used. 1576 * 1577 * @param sc status code to use for the response 1578 * @param iov_count the number of elements in @a iov 1579 * @param iov the array for response data buffers, an internal copy of this 1580 * will be made 1581 * @param free_cb the callback to clean up any data associated with @a iov when 1582 * the response is destroyed. 1583 * @param free_cb_cls the argument passed to @a free_cb 1584 * @return NULL on error (i.e. invalid arguments, out of memory) 1585 * FIXME: Call free callback on error? 1586 * @ingroup response 1587 */ 1588 MHD_EXTERN_ struct MHD_Response * 1589 MHD_response_from_iovec ( 1590 enum MHD_HTTP_StatusCode sc, 1591 unsigned int iov_count, 1592 const struct MHD_IoVec iov[MHD_FN_PAR_DYN_ARR_SIZE_ (iov_count)], 1593 MHD_FreeCallback free_cb, 1594 void *free_cb_cls); 1595 1596 1597 /** 1598 * Create a response object based on an @a fd from which 1599 * data is read. The response object can be extended with 1600 * header information. 1601 * 1602 * @param sc status code to return 1603 * @param fd file descriptor referring to a file on disk with the 1604 * data; will be closed when response is destroyed; 1605 * fd should be in 'blocking' mode 1606 * @param offset offset to start reading from in the file; 1607 * reading file beyond 2 GiB may be not supported by OS or 1608 * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE 1609 * @param size size of the data portion of the response; 1610 * sizes larger than 2 GiB may be not supported by OS or 1611 * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE 1612 * @return NULL on error (i.e. invalid arguments, out of memory) 1613 * FIXME: Close FD on error? 1614 * @ingroup response 1615 */ 1616 MHD_EXTERN_ struct MHD_Response * 1617 MHD_response_from_fd (enum MHD_HTTP_StatusCode sc, 1618 int fd, 1619 uint_fast64_t offset, 1620 uint_fast64_t size) 1621 MHD_FN_PAR_FD_READ_ (2); 1622 1623 /** 1624 * Create a response object with the response body created by reading 1625 * the provided pipe. 1626 * 1627 * The response object can be extended with header information and 1628 * then be used ONLY ONCE. 1629 * 1630 * If response object is used to answer HEAD request then the body 1631 * of the response is not used, while all headers (including automatic 1632 * headers) are used. 1633 * 1634 * @param sc status code to use for the response 1635 * @param fd file descriptor referring to a read-end of a pipe with the 1636 * data; will be closed when response is destroyed; 1637 * fd should be in 'blocking' mode 1638 * @return NULL on error (i.e. invalid arguments, out of memory) 1639 * FIXME: Close pipe FD on error? 1640 * @ingroup response 1641 */ 1642 MHD_EXTERN_ struct MHD_Response * 1643 MHD_response_from_pipe (enum MHD_HTTP_StatusCode sc, 1644 int fd) 1645 MHD_FN_PAR_FD_READ_ (2); 1646 1647 1648 /** 1649 * Destroy response. 1650 * Should be called if response was created but not consumed. 1651 * Also must be called if response has #MHD_R_O_REUSABLE set. 1652 * The actual destroy can be happen later, if the response 1653 * is still being used in any request. 1654 * The function does not block. 1655 * 1656 * @param[in] response the response to destroy 1657 * @ingroup response 1658 */ 1659 MHD_EXTERN_ void 1660 MHD_response_destroy (struct MHD_Response *response) 1661 MHD_FN_PAR_NONNULL_ (1); 1662 1663 1664 /** 1665 * Add a header line to the response. 1666 * 1667 * @param response response to add a header to, NULL is tolerated 1668 * @param name the name of the header to add, 1669 * an internal copy of the string will be made 1670 * @param value the value of the header to add, 1671 * an internal copy of the string will be made 1672 * @return #MHD_SC_OK on success, 1673 * error code otherwise 1674 * @ingroup response 1675 */ 1676 MHD_EXTERN_ enum MHD_StatusCode 1677 MHD_response_add_header (struct MHD_Response *MHD_RESTRICT response, 1678 const char *MHD_RESTRICT name, 1679 const char *MHD_RESTRICT value) 1680 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2) 1681 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3); 1682 1683 1684 /** 1685 * Add a header with predefined (standard) name to the response. 1686 * 1687 * @param response response to add a header to 1688 * @param stk the code of the predefined header 1689 * @param content the value of the header to add, 1690 * an internal copy of the string will be made 1691 * @return #MHD_SC_OK on success, 1692 * error code otherwise 1693 * @ingroup response 1694 */ 1695 MHD_EXTERN_ enum MHD_StatusCode 1696 MHD_response_add_predef_header (struct MHD_Response *MHD_RESTRICT response, 1697 enum MHD_PredefinedHeader stk, 1698 const char *MHD_RESTRICT content) 1699 MHD_FN_PAR_NONNULL_ (1) 1700 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3); 1701 1702 1703 /* ************ (b) Upload and PostProcessor functions ********************** */ 1704 1705 1706 /** 1707 * Suspend handling of network data for a given request. This can 1708 * be used to dequeue a request from MHD's event loop for a while. 1709 * 1710 * Suspended requests continue to count against the total number of 1711 * requests allowed (per daemon, as well as per IP, if such limits 1712 * are set). Suspended requests will NOT time out; timeouts will 1713 * restart when the request handling is resumed. While a 1714 * request is suspended, MHD may not detect disconnects by the 1715 * client. 1716 * 1717 * At most one upload action can be created for one upload callback. 1718 * 1719 * @param[in,out] request the request for which the action is generated 1720 * @return action to cause a request to be suspended, 1721 * NULL if any action has been already created for the @a request 1722 * @ingroup action 1723 */ 1724 MHD_EXTERN_ const struct MHD_UploadAction * 1725 MHD_upload_action_suspend (struct MHD_Request *request) 1726 MHD_FN_PAR_NONNULL_ALL_; 1727 1728 /** 1729 * Converts a @a response to an action. If #MHD_R_O_REUSABLE 1730 * is not set, the reference to the @a response is consumed 1731 * by the conversion. If #MHD_R_O_REUSABLE is #MHD_YES, 1732 * then the @a response can be used again to create actions in 1733 * the future. 1734 * However, the @a response is frozen by this step and 1735 * must no longer be modified (i.e. by setting headers). 1736 * 1737 * At most one upload action can be created for one upload callback. 1738 * 1739 * @param request the request to create the action for 1740 * @param[in] response the response to convert, 1741 * if NULL then this function is equivalent to 1742 * #MHD_upload_action_abort_request() call 1743 * @return pointer to the action, the action must be consumed 1744 * otherwise response object may leak; 1745 * NULL if failed (no memory) or if any action has been already 1746 * created for the @a request; 1747 * when failed the response object is consumed and need not 1748 * to be "destroyed" 1749 * @ingroup action 1750 */ 1751 MHD_EXTERN_ const struct MHD_UploadAction * 1752 MHD_upload_action_from_response (struct MHD_Request *MHD_RESTRICT request, 1753 struct MHD_Response *MHD_RESTRICT response) 1754 MHD_FN_PAR_NONNULL_ (1); 1755 1756 /** 1757 * Action telling MHD to continue processing the upload. 1758 * Valid only for incremental upload processing. 1759 * Works as #MHD_upload_action_abort_request() if used for full upload callback 1760 * or for the final (with zero data) incremental callback. 1761 * 1762 * At most one upload action can be created for one upload callback. 1763 * 1764 * @param request the request to make an action 1765 * @return action operation, 1766 * NULL if any action has been already created for the @a request 1767 * @ingroup action 1768 */ 1769 MHD_EXTERN_ const struct MHD_UploadAction * 1770 MHD_upload_action_continue (struct MHD_Request *request) 1771 MHD_FN_PAR_NONNULL_ (1); 1772 1773 1774 /** 1775 * Action telling MHD to close the connection hard 1776 * (kind-of breaking HTTP specification). 1777 * 1778 * @param req the request to make an action 1779 * @return action operation, always NULL 1780 * @ingroup action 1781 */ 1782 #define MHD_upload_action_abort_request(req) \ 1783 MHD_STATIC_CAST_ (const struct MHD_UploadAction *, NULL) 1784 1785 #ifndef MHD_UPLOADCALLBACK_DEFINED 1786 1787 /** 1788 * Function to process data uploaded by a client. 1789 * 1790 * @param upload_cls the argument given together with the function 1791 * pointer when the handler was registered with MHD 1792 * @param request the request is being processed 1793 * @param content_data_size the size of the @a content_data, 1794 * zero when all data have been processed 1795 * @param[in] content_data the uploaded content data, 1796 * may be modified in the callback, 1797 * valid only until return from the callback, 1798 * NULL when all data have been processed 1799 * @return action specifying how to proceed: 1800 * #MHD_upload_action_continue() to continue upload (for incremental 1801 * upload processing only), 1802 * #MHD_upload_action_suspend() to stop reading the upload until 1803 * the request is resumed, 1804 * #MHD_upload_action_abort_request() to close the socket, 1805 * or a response to discard the rest of the upload and transmit 1806 * the response 1807 * @ingroup action 1808 */ 1809 typedef const struct MHD_UploadAction * 1810 (MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_INOUT_SIZE_ (4,3) 1811 *MHD_UploadCallback)(void *upload_cls, 1812 struct MHD_Request *request, 1813 size_t content_data_size, 1814 void *content_data); 1815 1816 #define MHD_UPLOADCALLBACK_DEFINED 1 1817 #endif /* ! MHD_UPLOADCALLBACK_DEFINED */ 1818 1819 /** 1820 * Create an action that handles an upload. 1821 * 1822 * If @a uc_inc is NULL and upload cannot fit the allocated buffer 1823 * then request is aborted without response. 1824 * 1825 * At most one action can be created for any request. 1826 * 1827 * @param request the request to create action for 1828 * @param large_buffer_size how large should the upload buffer be. 1829 * May allocate memory from the shared "large" 1830 * memory pool if necessary and non-zero is given. 1831 * Must be zero if @a uc_full is NULL. 1832 * @param uc_full the function to call when complete upload 1833 * is received (only if fit @a upload_buffer_size), 1834 * can be NULL if uc_inc is not NULL, 1835 * must be NULL is @a upload_buffer_size is zero. 1836 * @param uc_full_cls closure for @a uc_full 1837 * @param uc_inc the function to incrementally process the upload data 1838 * if the upload if larger than @a upload_buffer_size or 1839 * @a upload_buffer_size cannot be allocated or 1840 * @a uc_full is NULL, 1841 * can be NULL if uc_full is not NULL 1842 * @param uc_inc_cls closure for @a uc_inc 1843 * @return NULL on error (out of memory, invalid parameters) 1844 * @return pointer to the action, 1845 * NULL if failed (no memory) or if any action has been already 1846 * created for the @a request. 1847 * @sa #MHD_D_OPTION_LARGE_POOL_SIZE() 1848 * @ingroup action 1849 */ 1850 MHD_EXTERN_ const struct MHD_Action * 1851 MHD_action_process_upload ( 1852 struct MHD_Request *request, 1853 size_t large_buffer_size, 1854 MHD_UploadCallback uc_full, 1855 void *uc_full_cls, 1856 MHD_UploadCallback uc_inc, 1857 void *uc_inc_cls) 1858 MHD_FN_PAR_NONNULL_ (1); 1859 1860 /** 1861 * Create an action that handles an upload as full upload data. 1862 * 1863 * @param request the request to create action for 1864 * @param buff_size how large should the upload buffer be. May allocate memory 1865 * from the large memory pool if necessary. Must not be zero. 1866 * @param uc the function to call when complete upload 1867 * is received (only if fit @a upload_buffer_size) 1868 * @param uc_cls closure for @a uc 1869 * @return NULL on error (out of memory. both @a uc is NULL) 1870 * @ingroup action 1871 */ 1872 #define MHD_action_process_upload_full(request,buff_size,uc,uc_cls) \ 1873 MHD_action_process_upload (request, buff_size, uc, uc_cls, NULL, NULL) 1874 1875 /** 1876 * Create an action that handles an upload incrementally. 1877 * 1878 * @param request the request to create action for 1879 * @param uc the function to incrementally process the upload data 1880 * @param uc_cls closure for @a uc 1881 * @return NULL on error (out of memory. both @a uc is NULL) 1882 * @ingroup action 1883 */ 1884 #define MHD_action_process_upload_inc(request,uc,uc_cls) \ 1885 MHD_action_process_upload (request, 0, NULL, NULL, uc, uc_cls) 1886 1887 #ifndef MHD_POST_PARSE_RESULT_DEFINED 1888 1889 /** 1890 * The result of POST data parsing 1891 */ 1892 enum MHD_FIXED_ENUM_MHD_SET_ MHD_PostParseResult 1893 { 1894 /** 1895 * The POST data parsed successfully and completely. 1896 */ 1897 MHD_POST_PARSE_RES_OK = 0 1898 , 1899 /** 1900 * The POST request has no content or zero-length content. 1901 */ 1902 MHD_POST_PARSE_RES_REQUEST_EMPTY = 1 1903 , 1904 /** 1905 * The POST data parsed successfully, but has missing or incorrect 1906 * termination. 1907 * The last parsed field may have incorrect data. 1908 */ 1909 MHD_POST_PARSE_RES_OK_BAD_TERMINATION = 2 1910 , 1911 /** 1912 * Parsing of the POST data is incomplete because client used incorrect 1913 * format of POST encoding. 1914 * The last parsed field may have incorrect data. 1915 * Some POST data is available or has been provided via callback. 1916 */ 1917 MHD_POST_PARSE_RES_PARTIAL_INVALID_POST_FORMAT = 3 1918 , 1919 /** 1920 * The POST data cannot be parsed completely because the stream has 1921 * no free pool memory. 1922 * Some POST data may be parsed. 1923 */ 1924 MHD_POST_PARSE_RES_FAILED_NO_POOL_MEM = 60 1925 , 1926 /** 1927 * The POST data cannot be parsed completely because no "large shared buffer" 1928 * space is available. 1929 * Some POST data may be parsed. 1930 */ 1931 MHD_POST_PARSE_RES_FAILED_NO_LARGE_BUF_MEM = 61 1932 , 1933 /** 1934 * The POST data cannot be parsed because 'Content-Type:' is unknown. 1935 */ 1936 MHD_POST_PARSE_RES_FAILED_UNKNOWN_CNTN_TYPE = 80 1937 , 1938 /** 1939 * The POST data cannot be parsed because 'Content-Type:' header is not set. 1940 */ 1941 MHD_POST_PARSE_RES_FAILED_NO_CNTN_TYPE = 81 1942 , 1943 /** 1944 * The POST data cannot be parsed because "Content-Type:" request header has 1945 * no "boundary" parameter for "multipart/form-data" 1946 */ 1947 MHD_POST_PARSE_RES_FAILED_HEADER_NO_BOUNDARY = 82 1948 , 1949 /** 1950 * The POST data cannot be parsed because "Content-Type: multipart/form-data" 1951 * request header is misformed 1952 */ 1953 MHD_POST_PARSE_RES_FAILED_HEADER_MISFORMED = 83 1954 , 1955 /** 1956 * The application set POST encoding to "multipart/form-data", but the request 1957 * has no "Content-Type: multipart/form-data" header which is required 1958 * to find "boundary" used in this encoding 1959 */ 1960 MHD_POST_PARSE_RES_FAILED_HEADER_NOT_MPART = 84 1961 , 1962 /** 1963 * The POST data cannot be parsed because client used incorrect format 1964 * of POST encoding. 1965 */ 1966 MHD_POST_PARSE_RES_FAILED_INVALID_POST_FORMAT = 90 1967 1968 }; 1969 1970 #define MHD_POST_PARSE_RESULT_DEFINED 1 1971 #endif /* ! MHD_POST_PARSE_RESULT_DEFINED */ 1972 1973 #ifndef MHD_POST_DATA_READER_DEFINED 1974 1975 /** 1976 * "Stream" reader for POST data. 1977 * This callback is called to incrementally process parsed POST data sent by 1978 * the client. 1979 * The pointers to the MHD_String and MHD_StringNullable are valid only until 1980 * return from this callback. 1981 * The pointers to the strings and the @a data are valid only until return from 1982 * this callback. 1983 * 1984 * @param req the request 1985 * @param cls user-specified closure 1986 * @param name the name of the POST field 1987 * @param filename the name of the uploaded file, @a cstr member is NULL if not 1988 * known / not provided 1989 * @param content_type the mime-type of the data, cstr member is NULL if not 1990 * known / not provided 1991 * @param encoding the encoding of the data, cstr member is NULL if not known / 1992 * not provided 1993 * @param size the number of bytes in @a data available, may be zero if 1994 * the @a final_data is #MHD_YES 1995 * @param data the pointer to @a size bytes of data at the specified 1996 * @a off offset, NOT zero-terminated 1997 * @param off the offset of @a data in the overall value, always equal to 1998 * the sum of sizes of previous calls for the same field / file; 1999 * client may provide more than one field with the same name and 2000 * the same filename, the new filed (or file) is indicated by zero 2001 * value of @a off (and the end is indicated by @a final_data) 2002 * @param final_data if set to #MHD_YES then full field data is provided, 2003 * if set to #MHD_NO then more field data may be provided 2004 * @return action specifying how to proceed: 2005 * #MHD_upload_action_continue() if all is well, 2006 * #MHD_upload_action_suspend() to stop reading the upload until 2007 * the request is resumed, 2008 * #MHD_upload_action_abort_request() to close the socket, 2009 * or a response to discard the rest of the upload and transmit 2010 * the response 2011 * @ingroup action 2012 */ 2013 typedef const struct MHD_UploadAction * 2014 (MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_NONNULL_ (4) 2015 MHD_FN_PAR_NONNULL_ (5) MHD_FN_PAR_NONNULL_ (6) 2016 *MHD_PostDataReader) (struct MHD_Request *req, 2017 void *cls, 2018 const struct MHD_String *name, 2019 const struct MHD_StringNullable *filename, 2020 const struct MHD_StringNullable *content_type, 2021 const struct MHD_StringNullable *encoding, 2022 size_t size, 2023 const void *data, 2024 uint_fast64_t off, 2025 enum MHD_Bool final_data); 2026 2027 2028 /** 2029 * The callback to be called when finished with processing 2030 * of the postprocessor upload data. 2031 * @param req the request 2032 * @param cls the closure 2033 * @param parsing_result the result of POST data parsing 2034 * @return the action to proceed 2035 */ 2036 typedef const struct MHD_UploadAction * 2037 (MHD_FN_PAR_NONNULL_ (1) 2038 *MHD_PostDataFinished) (struct MHD_Request *req, 2039 void *cls, 2040 enum MHD_PostParseResult parsing_result); 2041 2042 #define MHD_POST_DATA_READER_DEFINED 1 2043 #endif /* ! MHD_POST_DATA_READER_DEFINED */ 2044 2045 /** 2046 * Create an action to parse the POSTed content from the client. 2047 * 2048 * The action starts parsing of the POST data. Any value that does not fit 2049 * @a buffer_size or larger that @a auto_stream_size is given to 2050 * @a stream_reader (if it is not NULL). 2051 * 2052 * If @a buffer_size is zero, then buffers will be limited to the connection's 2053 * memory pool. To force all POST data process via @a stream_reader 2054 * set @a auto_stream_size to zero. 2055 * 2056 * At most one action can be created for any request. 2057 * 2058 * @param request the request to create action for 2059 * @param buffer_size the maximum size allowed for the buffers to parse this 2060 * request POST data. Within the set limit the buffer is 2061 * allocated automatically from the "large" shared memory 2062 * pool if necessary. 2063 * @param max_nonstream_size the size of the field (in encoded form) above which 2064 * values are not buffered and provided for 2065 * the @a steam_reader automatically; 2066 * useful to have large data (like file uploads) 2067 * processed incrementally, while keeping buffer space 2068 * for small fields only; 2069 * ignored if @a stream_reader is NULL 2070 * @param enc the data encoding to use, 2071 * use #MHD_HTTP_POST_ENCODING_OTHER to detect automatically 2072 * @param stream_reader the function to call for "oversize" values in 2073 * the stream; can be NULL if @a auto_stream_size is 2074 * not zero 2075 * @param reader_cls the closure for the @a stream_reader 2076 * @param done_cb called once all data has been processed for 2077 * the final action; values smaller than @a auto_stream_size that 2078 * fit into @a buffer_size will be available via 2079 * #MHD_request_get_values_cb(), #MHD_request_get_values_list() and 2080 * #MHD_request_get_post_data_cb(), #MHD_request_get_post_data_list() 2081 * @param done_cb_cls the closure for the @a done_cb 2082 * @return pointer to the action, 2083 * NULL if failed (no memory) or if any action has been already 2084 * created for the @a request. 2085 * @sa #MHD_D_OPTION_LARGE_POOL_SIZE() 2086 * @ingroup action 2087 */ 2088 MHD_EXTERN_ const struct MHD_Action * 2089 MHD_action_parse_post (struct MHD_Request *request, 2090 size_t buffer_size, 2091 size_t max_nonstream_size, 2092 enum MHD_HTTP_PostEncoding enc, 2093 MHD_PostDataReader stream_reader, 2094 void *reader_cls, 2095 MHD_PostDataFinished done_cb, 2096 void *done_cb_cls) 2097 MHD_FN_PAR_NONNULL_ (1); 2098 2099 2100 #ifndef MHD_POSTFILED_DEFINED 2101 2102 /** 2103 * Post data element. 2104 * If any member is not provided/set then pointer to C string is NULL. 2105 * If any member is set to empty string then pointer to C string not NULL, 2106 * but the length is zero. 2107 */ 2108 struct MHD_PostField 2109 { 2110 /** 2111 * The name of the field 2112 */ 2113 struct MHD_String name; 2114 /** 2115 * The field data 2116 * If not set or defined then to C string is NULL. 2117 * If set to empty string then pointer to C string not NULL, 2118 * but the length is zero. 2119 */ 2120 struct MHD_StringNullable value; 2121 /** 2122 * The filename if provided (only for "multipart/form-data") 2123 * If not set or defined then to C string is NULL. 2124 * If set to empty string then pointer to C string not NULL, 2125 * but the length is zero. 2126 */ 2127 struct MHD_StringNullable filename; 2128 /** 2129 * The Content-Type if provided (only for "multipart/form-data") 2130 * If not set or defined then to C string is NULL. 2131 * If set to empty string then pointer to C string not NULL, 2132 * but the length is zero. 2133 */ 2134 struct MHD_StringNullable content_type; 2135 /** 2136 * The Transfer-Encoding if provided (only for "multipart/form-data") 2137 * If not set or defined then to C string is NULL. 2138 * If set to empty string then pointer to C string not NULL, 2139 * but the length is zero. 2140 */ 2141 struct MHD_StringNullable transfer_encoding; 2142 }; 2143 2144 #define MHD_POSTFILED_DEFINED 1 2145 #endif /* ! MHD_POSTFILED_DEFINED */ 2146 2147 2148 /** 2149 * Iterator over POST data. 2150 * 2151 * The @a data pointer is valid only until return from this function. 2152 * 2153 * The pointers to the strings in @a data are valid until any MHD_UploadAction 2154 * is provided. If the data is needed beyond this point, it should be copied. 2155 * 2156 * @param cls closure 2157 * @param data the element of the post data, the pointer is valid only until 2158 * return from this function 2159 * @return #MHD_YES to continue iterating, 2160 * #MHD_NO to abort the iteration 2161 * @ingroup request 2162 */ 2163 typedef enum MHD_Bool 2164 (MHD_FN_PAR_NONNULL_ (2) 2165 *MHD_PostDataIterator)(void *cls, 2166 const struct MHD_PostField *data); 2167 2168 /** 2169 * Get all of the post data from the request via request. 2170 * 2171 * @param request the request to get data for 2172 * @param iterator callback to call on each header; 2173 * maybe NULL (then just count headers) 2174 * @param iterator_cls extra argument to @a iterator 2175 * @return number of entries iterated over 2176 * @ingroup request 2177 */ 2178 MHD_EXTERN_ size_t 2179 MHD_request_get_post_data_cb (struct MHD_Request *request, 2180 MHD_PostDataIterator iterator, 2181 void *iterator_cls) 2182 MHD_FN_PAR_NONNULL_ (1); 2183 2184 /** 2185 * Get all of the post data from the request. 2186 * 2187 * The pointers to the strings in @a elements are valid until any 2188 * MHD_UploadAction is provided. If the data is needed beyond this point, 2189 * it should be copied. 2190 * @param request the request to get data for 2191 * @param num_elements the number of elements in @a elements array 2192 * @param[out] elements the array of @a num_elements to get the data 2193 * @return the number of elements stored in @a elements, 2194 * zero if no data or postprocessor was not used. 2195 * @ingroup request 2196 */ 2197 MHD_EXTERN_ size_t 2198 MHD_request_get_post_data_list ( 2199 struct MHD_Request *request, 2200 size_t num_elements, 2201 struct MHD_PostField elements[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)]) 2202 MHD_FN_PAR_NONNULL_ (1) 2203 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_SIZE_ (3,2); 2204 2205 /* ***************** (c) WebSocket support ********** */ 2206 2207 /** 2208 * Handle given to the application to manage special 2209 * actions relating to MHD responses that "upgrade" 2210 * the HTTP protocol (i.e. to WebSockets). 2211 */ 2212 struct MHD_UpgradedHandle; 2213 2214 2215 #ifndef MHD_UPGRADEHANDLER_DEFINED 2216 2217 /** 2218 * Function called after a protocol "upgrade" response was sent successfully 2219 * and the connection is being switched to other protocol. 2220 * 2221 * The newly provided handle @a urh can be used to send and receive the data 2222 * by #MHD_upgraded_send() and #MHD_upgraded_recv(). The handle must be closed 2223 * by #MHD_upgraded_close() before destroying the daemon. 2224 * 2225 * "Upgraded" connection will not time out, but still counted for daemon 2226 * global connections limit and for per-IP limit (if set). 2227 * 2228 * Except when in 'thread-per-connection' mode, implementations 2229 * of this function should never block (as it will still be called 2230 * from within the main event loop). 2231 * 2232 * @param cls closure, whatever was given to #MHD_action_upgrade(). 2233 * @param request original HTTP request handle, 2234 * giving the function a last chance 2235 * to inspect the original HTTP request 2236 * @param urh argument for #MHD_upgrade_operation() on this @a response. 2237 * Applications must eventually use this callback to (indirectly) 2238 * perform the close() action on the @a sock. 2239 */ 2240 typedef void 2241 (MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3) 2242 *MHD_UpgradeHandler)(void *cls, 2243 struct MHD_Request *MHD_RESTRICT request, 2244 struct MHD_UpgradedHandle *MHD_RESTRICT urh); 2245 2246 #define MHD_UPGRADEHANDLER_DEFINED 1 2247 #endif /* ! MHD_UPGRADEHANDLER_DEFINED */ 2248 2249 2250 /** 2251 * Create a action object that can be used for 101 Upgrade 2252 * responses, for example to implement WebSockets. After sending the 2253 * response, control over the data stream is given to the callback (which 2254 * can then, for example, start some bi-directional communication). 2255 * The callback will ONLY be called after the response header was successfully 2256 * passed to the OS; if there are communication errors before, the usual MHD 2257 * connection error handling code will be performed. 2258 * 2259 * At most one action can be created for any request. 2260 * 2261 * @param request the request to create action for 2262 * @param upgrade_hdr_value the value of the "Upgrade:" header, mandatory 2263 string 2264 * @param upgrade_handler function to call with the "upgraded" socket 2265 * @param upgrade_handler_cls closure for @a upgrade_handler 2266 * @param num_headers number of elements in the @a headers array, 2267 * must be zero if @a headers is NULL 2268 * @param headers the optional pointer to the array of the headers (the strings 2269 * are copied and does not need to be valid after return from 2270 * this function), 2271 * can be NULL if @a num_headers is zero 2272 * @return NULL on error (i.e. invalid arguments, out of memory) 2273 * @ingroup action 2274 */ 2275 MHD_EXTERN_ const struct MHD_Action * 2276 MHD_action_upgrade (struct MHD_Request *MHD_RESTRICT request, 2277 const char *MHD_RESTRICT upgrade_hdr_value, 2278 MHD_UpgradeHandler upgrade_handler, 2279 void *upgrade_handler_cls, 2280 size_t num_headers, 2281 const struct MHD_NameValueCStr *MHD_RESTRICT headers) 2282 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2) 2283 MHD_FN_PAR_IN_SIZE_ (6,5); 2284 2285 2286 /** 2287 * Create a action object that can be used for 101 Upgrade 2288 * responses, for example to implement WebSockets. After sending the 2289 * response, control over the data stream is given to the callback (which 2290 * can then, for example, start some bi-directional communication). 2291 * The callback will ONLY be called after the response header was successfully 2292 * passed to the OS; if there are communication errors before, the usual MHD 2293 * connection error handling code will be performed. 2294 * 2295 * At most one action can be created for any request. 2296 * 2297 * @param request the request to create action for 2298 * @param upgrade_hdr_value the value of the "Upgrade:" header, mandatory 2299 string 2300 * @param upgrade_handler function to call with the "upgraded" socket 2301 * @param upgrade_handler_cls closure for @a upgrade_handler 2302 * @param num_headers number of elements in the @a headers array, 2303 * must be zero if @a headers is NULL 2304 * @param headers the optional pointer to the array of the headers (the strings 2305 * are copied and does not need to be valid after return from 2306 * this function), 2307 * can be NULL if @a num_headers is zero 2308 * @return NULL on error (i.e. invalid arguments, out of memory) 2309 * @ingroup action 2310 */ 2311 MHD_EXTERN_ const struct MHD_UploadAction * 2312 MHD_upload_action_upgrade ( 2313 struct MHD_Request *MHD_RESTRICT request, 2314 const char *MHD_RESTRICT upgrade_hdr_value, 2315 MHD_UpgradeHandler upgrade_handler, 2316 void *upgrade_handler_cls, 2317 size_t num_headers, 2318 const struct MHD_NameValueCStr *MHD_RESTRICT headers) 2319 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2) 2320 MHD_FN_PAR_IN_SIZE_ (6,5); 2321 2322 2323 /** 2324 * Receive data on the HTTP-Upgraded connection. 2325 * 2326 * The function finished if one of the following happens: 2327 * + ANY amount of data has been received, 2328 * + timeout reached, 2329 * + network error occurs 2330 * 2331 * @param urh the HTTP-Upgraded handle 2332 * @param recv_buf_size the size of the @a recv_buf 2333 * @param recv_buf the buffer to receive the data 2334 * @param received_size the pointer to variable to get amount of received data 2335 * @param max_wait_millisec the maximum wait time for the data, 2336 * non-blocking operation if set to zero, 2337 * wait indefinitely if larger or equal to 2338 * #MHD_WAIT_INDEFINITELY, 2339 * the function may return earlier if waiting is 2340 * interrupted or by other reasons 2341 * @return #MHD_SC_OK if ANY data received (check the @a received_size) or 2342 * remote shut down send side (indicated by @a received_size 2343 * set to zero), 2344 * #MHD_SC_UPGRADED_NET_TIMEOUT if NO data received but timeout expired, 2345 * #MHD_SC_UPGRADED_NET_CONN_CLOSED if network connection has been 2346 * closed, 2347 * #MHD_SC_UPGRADED_NET_CONN_BROKEN if broken network connection has 2348 * been detected, 2349 * #MHD_SC_UPGRADED_TLS_ERROR if TLS error occurs (only for TLS), 2350 * #MHD_SC_UPGRADED_NET_HARD_ERROR if any other network or sockets 2351 * unrecoverable error occurs, 2352 * #MHD_SC_UPGRADED_HANDLE_INVALID if @a urh is invalid, 2353 * #MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED if timed wait is not supported 2354 * by this MHD build or platform 2355 */ 2356 MHD_EXTERN_ enum MHD_StatusCode 2357 MHD_upgraded_recv (struct MHD_UpgradedHandle *MHD_RESTRICT urh, 2358 size_t recv_buf_size, 2359 void *MHD_RESTRICT recv_buf, 2360 size_t *MHD_RESTRICT received_size, 2361 uint_fast64_t max_wait_millisec) 2362 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (3,2) 2363 MHD_FN_PAR_OUT_ (4); 2364 2365 2366 /** 2367 * Send data on the HTTP-Upgraded connection. 2368 * 2369 * The function finished if one of the following happens: 2370 * + ALL provided data has been sent, 2371 * + timeout reached, 2372 * + network error occurs 2373 * 2374 * Parameter @a more_data_to_come controls network buffering. When set to 2375 * #MHD_YES, the OS waits shortly for additional data and tries to use 2376 * the network more effeciently delaying the last network packet, if it is 2377 * incomplete, to combine it with the next data provided. 2378 * 2379 * @param urh the HTTP-Upgraded handle 2380 * @param send_buf_size the amount of data in the @a send_buf 2381 * @param send_buf the buffer with the data to send 2382 * @param sent_size the pointer to get the amout of sent data 2383 * @param max_wait_millisec the maximum wait time for the data, 2384 * non-blocking operation if set to zero, 2385 * wait indefinitely if larger or equal to 2386 * #MHD_WAIT_INDEFINITELY 2387 * @param more_data_to_come set to #MHD_YES if the provided data in 2388 * the @a send_buf is part of a larger data package, 2389 * like an incomplete message or streamed 2390 * (not the final) part of some file, and more data 2391 * expected to be sent soon over the same connection, 2392 * set to #MHD_NO the data in the @a send_buf is 2393 * the complete message or the final part of 2394 * the message (or file) and it should be pushed 2395 * to the network (and to the client) as soon 2396 * as possible 2397 * @return #MHD_SC_OK if ANY data sent (check the @a sent_size), 2398 * #MHD_SC_UPGRADED_NET_TIMEOUT if NO data sent but timeout expired, 2399 * #MHD_SC_UPGRADED_NET_CONN_CLOSED if network connection has been 2400 * closed, 2401 * #MHD_SC_UPGRADED_NET_CONN_BROKEN if broken network connection has 2402 * been detected, 2403 * #MHD_SC_UPGRADED_TLS_ERROR if TLS error occurs (only for TLS), 2404 * #MHD_SC_UPGRADED_NET_HARD_ERROR if any other network or sockets 2405 * unrecoverable error occurs, 2406 * #MHD_SC_UPGRADED_HANDLE_INVALID if @a urh is invalid, 2407 * #MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED if timed wait is not supported 2408 * by this MHD build or platform 2409 */ 2410 MHD_EXTERN_ enum MHD_StatusCode 2411 MHD_upgraded_send (struct MHD_UpgradedHandle *MHD_RESTRICT urh, 2412 size_t send_buf_size, 2413 const void *MHD_RESTRICT send_buf, 2414 size_t *MHD_RESTRICT sent_size, 2415 uint_fast64_t max_wait_millisec, 2416 enum MHD_Bool more_data_to_come) 2417 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (3,2) 2418 MHD_FN_PAR_OUT_ (4); 2419 2420 2421 /** 2422 * Close HTTP-Upgraded connection handle. 2423 * 2424 * The handle cannot be used after successful return from this function. 2425 * 2426 * The function cannot fail if called correctly (the daemon is not destroyed 2427 * and the upgraded connection has not been closed yet). 2428 * 2429 * @param urh the handle to close 2430 * @return #MHD_SC_OK on success, 2431 * error code otherwise 2432 */ 2433 MHD_EXTERN_ enum MHD_StatusCode 2434 MHD_upgraded_close (struct MHD_UpgradedHandle *urh) 2435 MHD_FN_PAR_NONNULL_ (1); 2436 2437 2438 /* ********************** (e) Client auth ********************** */ 2439 2440 2441 /** 2442 * Length of the binary output of the MD5 hash function. 2443 * @sa #MHD_digest_get_hash_size() 2444 * @ingroup authentication 2445 */ 2446 #define MHD_MD5_DIGEST_SIZE 16 2447 2448 /** 2449 * Length of the binary output of the SHA-256 hash function. 2450 * @sa #MHD_digest_get_hash_size() 2451 * @ingroup authentication 2452 */ 2453 #define MHD_SHA256_DIGEST_SIZE 32 2454 2455 /** 2456 * Length of the binary output of the SHA-512/256 hash function. 2457 * @warning While this value is the same as the #MHD_SHA256_DIGEST_SIZE, 2458 * the calculated digests for SHA-256 and SHA-512/256 are different. 2459 * @sa #MHD_digest_get_hash_size() 2460 * @ingroup authentication 2461 */ 2462 #define MHD_SHA512_256_DIGEST_SIZE 32 2463 2464 /** 2465 * Base type of hash calculation. 2466 * Used as part of #MHD_DigestAuthAlgo values. 2467 * 2468 * @warning Not used directly by MHD API. 2469 */ 2470 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestBaseAlgo 2471 { 2472 /** 2473 * Invalid hash algorithm value 2474 */ 2475 MHD_DIGEST_BASE_ALGO_INVALID = 0 2476 , 2477 /** 2478 * MD5 hash algorithm. 2479 * As specified by RFC1321 2480 */ 2481 MHD_DIGEST_BASE_ALGO_MD5 = (1u << 0) 2482 , 2483 /** 2484 * SHA-256 hash algorithm. 2485 * As specified by FIPS PUB 180-4 2486 */ 2487 MHD_DIGEST_BASE_ALGO_SHA256 = (1u << 1) 2488 , 2489 /** 2490 * SHA-512/256 hash algorithm. 2491 * As specified by FIPS PUB 180-4 2492 */ 2493 MHD_DIGEST_BASE_ALGO_SHA512_256 = (1u << 2) 2494 }; 2495 2496 /** 2497 * The flag indicating non-session algorithm types, 2498 * like 'MD5', 'SHA-256' or 'SHA-512-256'. 2499 */ 2500 #define MHD_DIGEST_AUTH_ALGO_NON_SESSION (1u << 6) 2501 2502 /** 2503 * The flag indicating session algorithm types, 2504 * like 'MD5-sess', 'SHA-256-sess' or 'SHA-512-256-sess'. 2505 */ 2506 #define MHD_DIGEST_AUTH_ALGO_SESSION (1u << 7) 2507 2508 /** 2509 * Digest algorithm identification 2510 */ 2511 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthAlgo 2512 { 2513 /** 2514 * Unknown or wrong algorithm type. 2515 * Used in struct MHD_AuthDigestInfo to indicate client value that 2516 * cannot by identified. 2517 */ 2518 MHD_DIGEST_AUTH_ALGO_INVALID = 0 2519 , 2520 /** 2521 * The 'MD5' algorithm, non-session version. 2522 */ 2523 MHD_DIGEST_AUTH_ALGO_MD5 = 2524 MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO_NON_SESSION 2525 , 2526 /** 2527 * The 'MD5-sess' algorithm. 2528 * Not supported by MHD for authentication. 2529 */ 2530 MHD_DIGEST_AUTH_ALGO_MD5_SESSION = 2531 MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO_SESSION 2532 , 2533 /** 2534 * The 'SHA-256' algorithm, non-session version. 2535 */ 2536 MHD_DIGEST_AUTH_ALGO_SHA256 = 2537 MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_NON_SESSION 2538 , 2539 /** 2540 * The 'SHA-256-sess' algorithm. 2541 * Not supported by MHD for authentication. 2542 */ 2543 MHD_DIGEST_AUTH_ALGO_SHA256_SESSION = 2544 MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_SESSION 2545 , 2546 /** 2547 * The 'SHA-512-256' (SHA-512/256) algorithm. 2548 */ 2549 MHD_DIGEST_AUTH_ALGO_SHA512_256 = 2550 MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO_NON_SESSION 2551 , 2552 /** 2553 * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm. 2554 * Not supported by MHD for authentication. 2555 */ 2556 MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION = 2557 MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO_SESSION 2558 }; 2559 2560 2561 /** 2562 * Get digest size in bytes for specified algorithm. 2563 * 2564 * The size of the digest specifies the size of the userhash, userdigest 2565 * and other parameters which size depends on used hash algorithm. 2566 * @param algo the algorithm to check 2567 * @return the size (in bytes) of the digest (either #MHD_MD5_DIGEST_SIZE or 2568 * #MHD_SHA256_DIGEST_SIZE/MHD_SHA512_256_DIGEST_SIZE) 2569 * or zero if the input value is not supported or not valid 2570 * @sa #MHD_digest_auth_calc_userdigest() 2571 * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex() 2572 * @ingroup authentication 2573 */ 2574 MHD_EXTERN_ size_t 2575 MHD_digest_get_hash_size (enum MHD_DigestAuthAlgo algo) 2576 MHD_FN_CONST_; 2577 2578 /** 2579 * Digest algorithm identification, allow multiple selection. 2580 * 2581 * #MHD_DigestAuthAlgo always can be casted to #MHD_DigestAuthMultiAlgo, but 2582 * not vice versa. 2583 */ 2584 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiAlgo 2585 { 2586 /** 2587 * Unknown or wrong algorithm type. 2588 */ 2589 MHD_DIGEST_AUTH_MULT_ALGO_INVALID = MHD_DIGEST_AUTH_ALGO_INVALID 2590 , 2591 /** 2592 * The 'MD5' algorithm, non-session version. 2593 */ 2594 MHD_DIGEST_AUTH_MULT_ALGO_MD5 = MHD_DIGEST_AUTH_ALGO_MD5 2595 , 2596 /** 2597 * The 'MD5-sess' algorithm. 2598 * Not supported by MHD for authentication. 2599 * Reserved value. 2600 */ 2601 MHD_DIGEST_AUTH_MULT_ALGO_MD5_SESSION = MHD_DIGEST_AUTH_ALGO_MD5_SESSION 2602 , 2603 /** 2604 * The 'SHA-256' algorithm, non-session version. 2605 */ 2606 MHD_DIGEST_AUTH_MULT_ALGO_SHA256 = MHD_DIGEST_AUTH_ALGO_SHA256 2607 , 2608 /** 2609 * The 'SHA-256-sess' algorithm. 2610 * Not supported by MHD for authentication. 2611 * Reserved value. 2612 */ 2613 MHD_DIGEST_AUTH_MULT_ALGO_SHA256_SESSION = 2614 MHD_DIGEST_AUTH_ALGO_SHA256_SESSION 2615 , 2616 /** 2617 * The 'SHA-512-256' (SHA-512/256) algorithm, non-session version. 2618 */ 2619 MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256 = MHD_DIGEST_AUTH_ALGO_SHA512_256 2620 , 2621 /** 2622 * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm. 2623 * Not supported by MHD for authentication. 2624 * Reserved value. 2625 */ 2626 MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_SESSION = 2627 MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION 2628 , 2629 /** 2630 * SHA-256 or SHA-512/256 non-session algorithm, MHD will choose 2631 * the preferred or the matching one. 2632 */ 2633 MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_NON_SESSION = 2634 MHD_DIGEST_AUTH_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_SHA512_256 2635 , 2636 /** 2637 * Any non-session algorithm, MHD will choose the preferred or 2638 * the matching one. 2639 */ 2640 MHD_DIGEST_AUTH_MULT_ALGO_ANY_NON_SESSION = 2641 (0x3F) | MHD_DIGEST_AUTH_ALGO_NON_SESSION 2642 , 2643 /** 2644 * The SHA-256 or SHA-512/256 session algorithm. 2645 * Not supported by MHD. 2646 * Reserved value. 2647 */ 2648 MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_SESSION = 2649 MHD_DIGEST_AUTH_ALGO_SHA256_SESSION 2650 | MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION 2651 , 2652 /** 2653 * Any session algorithm. 2654 * Not supported by MHD. 2655 * Reserved value. 2656 */ 2657 MHD_DIGEST_AUTH_MULT_ALGO_ANY_SESSION = 2658 (0x3F) | MHD_DIGEST_AUTH_ALGO_SESSION 2659 , 2660 /** 2661 * The MD5 algorithm, session or non-session. 2662 * Currently supported as non-session only. 2663 */ 2664 MHD_DIGEST_AUTH_MULT_ALGO_MD5_ANY = 2665 MHD_DIGEST_AUTH_MULT_ALGO_MD5 | MHD_DIGEST_AUTH_MULT_ALGO_MD5_SESSION 2666 , 2667 /** 2668 * The SHA-256 algorithm, session or non-session. 2669 * Currently supported as non-session only. 2670 */ 2671 MHD_DIGEST_AUTH_MULT_ALGO_SHA256_ANY = 2672 MHD_DIGEST_AUTH_MULT_ALGO_SHA256 2673 | MHD_DIGEST_AUTH_MULT_ALGO_SHA256_SESSION 2674 , 2675 /** 2676 * The SHA-512/256 algorithm, session or non-session. 2677 * Currently supported as non-session only. 2678 */ 2679 MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_ANY = 2680 MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256 2681 | MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_SESSION 2682 , 2683 /** 2684 * The SHA-256 or SHA-512/256 algorithm, session or non-session. 2685 * Currently supported as non-session only. 2686 */ 2687 MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_ANY = 2688 MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_NON_SESSION 2689 | MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_SESSION 2690 , 2691 /** 2692 * Any algorithm, MHD will choose the preferred or the matching one. 2693 */ 2694 MHD_DIGEST_AUTH_MULT_ALGO_ANY = 2695 (0x3F) | MHD_DIGEST_AUTH_ALGO_NON_SESSION | MHD_DIGEST_AUTH_ALGO_SESSION 2696 }; 2697 2698 2699 /** 2700 * Calculate "userhash", return it as binary data. 2701 * 2702 * The "userhash" is the hash of the string "username:realm". 2703 * 2704 * The "userhash" could be used to avoid sending username in cleartext in Digest 2705 * Authorization client's header. 2706 * 2707 * Userhash is not designed to hide the username in local database or files, 2708 * as username in cleartext is required for #MHD_digest_auth_check() function 2709 * to check the response, but it can be used to hide username in HTTP headers. 2710 * 2711 * This function could be used when the new username is added to the username 2712 * database to save the "userhash" alongside with the username (preferably) or 2713 * when loading list of the usernames to generate the userhash for every loaded 2714 * username (this will cause delays at the start with the long lists). 2715 * 2716 * Once "userhash" is generated it could be used to identify users by clients 2717 * with "userhash" support. 2718 * Avoid repetitive usage of this function for the same username/realm 2719 * combination as it will cause excessive CPU load; save and reuse the result 2720 * instead. 2721 * 2722 * @param algo the algorithm for userhash calculations 2723 * @param username the username 2724 * @param realm the realm 2725 * @param[out] userhash_bin the output buffer for userhash as binary data; 2726 * if this function succeeds, then this buffer has 2727 * #MHD_digest_get_hash_size() bytes of userhash 2728 * upon return 2729 * @param bin_buf_size the size of the @a userhash_bin buffer, must be 2730 * at least #MHD_digest_get_hash_size() bytes long 2731 * @return #MHD_SC_OK on success, 2732 * #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small, 2733 * #MHD_SC_HASH_FAILED if hashing failed, 2734 * #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is 2735 * unknown or unsupported. 2736 * @sa #MHD_digest_auth_calc_userhash_hex() 2737 * @ingroup authentication 2738 */ 2739 MHD_EXTERN_ enum MHD_StatusCode 2740 MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo algo, 2741 const char *MHD_RESTRICT username, 2742 const char *MHD_RESTRICT realm, 2743 size_t bin_buf_size, 2744 void *MHD_RESTRICT userhash_bin) 2745 MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (2) 2746 MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_OUT_SIZE_ (5,4); 2747 2748 2749 /** 2750 * Calculate "userhash", return it as hexadecimal string. 2751 * 2752 * The "userhash" is the hash of the string "username:realm". 2753 * 2754 * The "userhash" could be used to avoid sending username in cleartext in Digest 2755 * Authorization client's header. 2756 * 2757 * Userhash is not designed to hide the username in local database or files, 2758 * as username in cleartext is required for #MHD_digest_auth_check() function 2759 * to check the response, but it can be used to hide username in HTTP headers. 2760 * 2761 * This function could be used when the new username is added to the username 2762 * database to save the "userhash" alongside with the username (preferably) or 2763 * when loading list of the usernames to generate the userhash for every loaded 2764 * username (this will cause delays at the start with the long lists). 2765 * 2766 * Once "userhash" is generated it could be used to identify users by clients 2767 * with "userhash" support. 2768 * Avoid repetitive usage of this function for the same username/realm 2769 * combination as it will cause excessive CPU load; save and reuse the result 2770 * instead. 2771 * 2772 * @param algo the algorithm for userhash calculations 2773 * @param username the username 2774 * @param realm the realm 2775 * @param hex_buf_size the size of the @a userhash_hex buffer, must be 2776 * at least #MHD_digest_get_hash_size()*2+1 chars long 2777 * @param[out] userhash_hex the output buffer for userhash as hex string; 2778 * if this function succeeds, then this buffer has 2779 * #MHD_digest_get_hash_size()*2 chars long 2780 * userhash string plus one zero-termination char 2781 * @return #MHD_SC_OK on success, 2782 * #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small, 2783 * #MHD_SC_HASH_FAILED if hashing failed, 2784 * #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is 2785 * unknown or unsupported. 2786 * @sa #MHD_digest_auth_calc_userhash() 2787 * @ingroup authentication 2788 */ 2789 MHD_EXTERN_ enum MHD_StatusCode 2790 MHD_digest_auth_calc_userhash_hex ( 2791 enum MHD_DigestAuthAlgo algo, 2792 const char *MHD_RESTRICT username, 2793 const char *MHD_RESTRICT realm, 2794 size_t hex_buf_size, 2795 char userhash_hex[MHD_FN_PAR_DYN_ARR_SIZE_ (hex_buf_size)]) 2796 MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (2) 2797 MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_OUT_SIZE_ (5,4); 2798 2799 2800 /** 2801 * The type of username used by client in Digest Authorization header 2802 * 2803 * Values are sorted so simplified checks could be used. 2804 * For example: 2805 * * (value <= MHD_DIGEST_AUTH_UNAME_TYPE_INVALID) is true if no valid username 2806 * is provided by the client (not used currently) 2807 * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH) is true if username is 2808 * provided in any form 2809 * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD) is true if username is 2810 * provided in clear text (no userhash matching is needed) 2811 */ 2812 enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthUsernameType 2813 { 2814 /** 2815 * No username parameter is in Digest Authorization header. 2816 * Not used currently. Value #MHD_SC_REQ_AUTH_DATA_BROKEN is returned 2817 * by #MHD_request_get_info_dynamic_sz() if the request has no username. 2818 */ 2819 MHD_DIGEST_AUTH_UNAME_TYPE_MISSING = 0 2820 , 2821 /** 2822 * The 'username' parameter is used to specify the username. 2823 */ 2824 MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD = (1u << 2) 2825 , 2826 /** 2827 * The username is specified by 'username*' parameter with 2828 * the extended notation (see RFC 5987, section-3.2.1). 2829 * The only difference between standard and extended types is 2830 * the way how username value is encoded in the header. 2831 */ 2832 MHD_DIGEST_AUTH_UNAME_TYPE_EXTENDED = (1u << 3) 2833 , 2834 /** 2835 * The username provided in form of 'userhash' as 2836 * specified by RFC 7616, section-3.4.4. 2837 * @sa #MHD_digest_auth_calc_userhash_hex(), #MHD_digest_auth_calc_userhash() 2838 */ 2839 MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH = (1u << 1) 2840 , 2841 /** 2842 * The invalid combination of username parameters are used by client. 2843 * Either: 2844 * + both 'username' and 'username*' are used 2845 * + 'username*' is used with 'userhash=true' 2846 * + 'username*' used with invalid extended notation 2847 * + 'username' is not hexadecimal string, while 'userhash' set to 'true' 2848 * Not used currently. Value #MHD_SC_REQ_AUTH_DATA_BROKEN is returned 2849 * by #MHD_request_get_info_dynamic_sz() if the request has broken username. 2850 */ 2851 MHD_DIGEST_AUTH_UNAME_TYPE_INVALID = (1u << 0) 2852 }; 2853 2854 /** 2855 * The QOP ('quality of protection') types. 2856 */ 2857 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthQOP 2858 { 2859 /** 2860 * Invalid/unknown QOP. 2861 * Used in struct MHD_AuthDigestInfo to indicate client value that 2862 * cannot by identified. 2863 */ 2864 MHD_DIGEST_AUTH_QOP_INVALID = 0 2865 , 2866 /** 2867 * No QOP parameter. 2868 * As described in old RFC 2069 original specification. 2869 * This mode is not allowed by latest RFCs and should be used only to 2870 * communicate with clients that do not support more modern modes (with QOP 2871 * parameter). 2872 * This mode is less secure than other modes and inefficient. 2873 */ 2874 MHD_DIGEST_AUTH_QOP_NONE = (1u << 0) 2875 , 2876 /** 2877 * The 'auth' QOP type. 2878 */ 2879 MHD_DIGEST_AUTH_QOP_AUTH = (1u << 1) 2880 , 2881 /** 2882 * The 'auth-int' QOP type. 2883 * Not supported by MHD for authentication. 2884 */ 2885 MHD_DIGEST_AUTH_QOP_AUTH_INT = (1u << 2) 2886 }; 2887 2888 /** 2889 * The QOP ('quality of protection') types, multiple selection. 2890 * 2891 * #MHD_DigestAuthQOP always can be casted to #MHD_DigestAuthMultiQOP, but 2892 * not vice versa. 2893 */ 2894 enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiQOP 2895 { 2896 /** 2897 * Invalid/unknown QOP. 2898 */ 2899 MHD_DIGEST_AUTH_MULT_QOP_INVALID = MHD_DIGEST_AUTH_QOP_INVALID 2900 , 2901 /** 2902 * No QOP parameter. 2903 * As described in old RFC 2069 original specification. 2904 * This mode is not allowed by latest RFCs and should be used only to 2905 * communicate with clients that do not support more modern modes (with QOP 2906 * parameter). 2907 * This mode is less secure than other modes and inefficient. 2908 */ 2909 MHD_DIGEST_AUTH_MULT_QOP_NONE = MHD_DIGEST_AUTH_QOP_NONE 2910 , 2911 /** 2912 * The 'auth' QOP type. 2913 */ 2914 MHD_DIGEST_AUTH_MULT_QOP_AUTH = MHD_DIGEST_AUTH_QOP_AUTH 2915 , 2916 /** 2917 * The 'auth-int' QOP type. 2918 * Not supported by MHD. 2919 * Reserved value. 2920 */ 2921 MHD_DIGEST_AUTH_MULT_QOP_AUTH_INT = MHD_DIGEST_AUTH_QOP_AUTH_INT 2922 , 2923 /** 2924 * The 'auth' QOP type OR the old RFC2069 (no QOP) type. 2925 * In other words: any types except 'auth-int'. 2926 * RFC2069-compatible mode is allowed, thus this value should be used only 2927 * when it is really necessary. 2928 */ 2929 MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT = 2930 MHD_DIGEST_AUTH_QOP_NONE | MHD_DIGEST_AUTH_QOP_AUTH 2931 , 2932 /** 2933 * Any 'auth' QOP type ('auth' or 'auth-int'). 2934 * Currently supported as 'auth' QOP type only. 2935 */ 2936 MHD_DIGEST_AUTH_MULT_QOP_AUTH_ANY = 2937 MHD_DIGEST_AUTH_QOP_AUTH | MHD_DIGEST_AUTH_QOP_AUTH_INT 2938 }; 2939 2940 /** 2941 * The type of 'nc' (nonce count) value provided in the request 2942 */ 2943 enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthNC 2944 { 2945 /** 2946 * Readable hexdecimal non-zero number. 2947 * The decoded value is placed in @a nc member of struct MHD_AuthDigestInfo 2948 */ 2949 MHD_DIGEST_AUTH_NC_NUMBER = 1 2950 , 2951 /** 2952 * Readable zero number. 2953 * Compliant clients should not use such values. 2954 * Can be treated as invalid request. 2955 */ 2956 MHD_DIGEST_AUTH_NC_ZERO = 2 2957 , 2958 /** 2959 * 'nc' value is not provided by the client. 2960 * Unless old RFC 2069 mode is allowed, this should be treated as invalid 2961 * request. 2962 */ 2963 MHD_DIGEST_AUTH_NC_NONE = 3 2964 , 2965 /** 2966 * 'nc' value is too long to be decoded. 2967 * Compliant clients should not use such values. 2968 * Can be treated as invalid request. 2969 */ 2970 MHD_DIGEST_AUTH_NC_TOO_LONG = 4 2971 , 2972 /** 2973 * 'nc' value is too large for uint32_t. 2974 * Compliant clients should not use such values. 2975 * Can be treated as request with a stale nonce or as invalid request. 2976 */ 2977 MHD_DIGEST_AUTH_NC_TOO_LARGE = 5 2978 }; 2979 2980 2981 /** 2982 * Information from Digest Authorization client's header. 2983 * 2984 * @see #MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO 2985 */ 2986 struct MHD_AuthDigestInfo 2987 { 2988 /** 2989 * The algorithm as defined by client. 2990 * Set automatically to MD5 if not specified by client. 2991 */ 2992 enum MHD_DigestAuthAlgo algo; 2993 2994 /** 2995 * The type of username used by client. 2996 */ 2997 enum MHD_DigestAuthUsernameType uname_type; 2998 2999 /** 3000 * The username string. 3001 * Used only if username type is standard or extended, always NULL otherwise. 3002 * If extended notation is used, this string is pct-decoded string 3003 * with charset and language tag removed (i.e. it is original username 3004 * extracted from the extended notation). 3005 * When userhash is used by the client, the string pointer is NULL and 3006 * @a userhash_hex and @a userhash_bin are set. 3007 */ 3008 struct MHD_StringNullable username; 3009 3010 /** 3011 * The userhash string. 3012 * Valid only if username type is userhash. 3013 * This is unqoted string without decoding of the hexadecimal 3014 * digits (as provided by the client). 3015 * @sa #MHD_digest_auth_calc_userhash_hex() 3016 */ 3017 struct MHD_StringNullable userhash_hex; 3018 3019 /** 3020 * The userhash decoded to binary form. 3021 * Used only if username type is userhash, always NULL otherwise. 3022 * When not NULL, this points to binary sequence @a userhash_bin_size bytes 3023 * long. 3024 * The valid size should be #MHD_digest_get_hash_size() bytes. 3025 * @warning This is a binary data, no zero termination. 3026 * @warning To avoid buffer overruns, always check the size of the data before 3027 * use, because @a userhash_bin can point even to zero-sized 3028 * data. 3029 * @sa #MHD_digest_auth_calc_userhash() 3030 */ 3031 const uint8_t *userhash_bin; 3032 3033 /** 3034 * The size of the data pointed by @a userhash_bin. 3035 * Always zero when @a userhash_bin is NULL. 3036 */ 3037 size_t userhash_bin_size; 3038 3039 /** 3040 * The 'opaque' parameter value, as specified by client. 3041 * If not specified by client then string pointer is NULL. 3042 */ 3043 struct MHD_StringNullable opaque; 3044 3045 /** 3046 * The 'realm' parameter value, as specified by client. 3047 * If not specified by client then string pointer is NULL. 3048 */ 3049 struct MHD_StringNullable realm; 3050 3051 /** 3052 * The 'qop' parameter value. 3053 */ 3054 enum MHD_DigestAuthQOP qop; 3055 3056 /** 3057 * The length of the 'cnonce' parameter value, including possible 3058 * backslash-escape characters. 3059 * 'cnonce' is used in hash calculation, which is CPU-intensive procedure. 3060 * An application may want to reject too large cnonces to limit the CPU load. 3061 * A few kilobytes is a reasonable limit, typically cnonce is just 32-160 3062 * characters long. 3063 */ 3064 size_t cnonce_len; 3065 3066 /** 3067 * The type of 'nc' (nonce count) value provided in the request. 3068 */ 3069 enum MHD_DigestAuthNC nc_type; 3070 3071 /** 3072 * The nc (nonce count) parameter value. 3073 * Can be used by application to limit the number of nonce re-uses. If @a nc 3074 * is higher than application wants to allow, then "auth required" response 3075 * with 'stale=true' could be used to force client to retry with the fresh 3076 * 'nonce'. 3077 * Set to zero when @a nc_type is not set to #MHD_DIGEST_AUTH_NC_NUMBER. 3078 */ 3079 uint_fast32_t nc; 3080 }; 3081 3082 /** 3083 * The result of digest authentication of the client. 3084 * 3085 * All error values are zero or negative. 3086 */ 3087 enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthResult 3088 { 3089 /** 3090 * Authentication OK. 3091 */ 3092 MHD_DAUTH_OK = 1 3093 , 3094 /** 3095 * General error, like "out of memory". 3096 * Authentication may be valid, but cannot be checked. 3097 */ 3098 MHD_DAUTH_ERROR = 0 3099 , 3100 /** 3101 * No "Authorization" header for Digest Authentication. 3102 */ 3103 MHD_DAUTH_HEADER_MISSING = -1 3104 , 3105 /** 3106 * Wrong format of the header. 3107 * Also returned if required parameters in Authorization header are missing 3108 * or broken (in invalid format). 3109 */ 3110 MHD_DAUTH_HEADER_BROKEN = -9 3111 , 3112 /** 3113 * Unsupported algorithm. 3114 */ 3115 MHD_DAUTH_UNSUPPORTED_ALGO = -10 3116 , 3117 /** 3118 * Unsupported 'qop'. 3119 */ 3120 MHD_DAUTH_UNSUPPORTED_QOP = -11 3121 , 3122 /** 3123 * Incorrect userdigest size. 3124 */ 3125 MHD_DAUTH_INVALID_USERDIGEST_SIZE = -15 3126 , 3127 /** 3128 * Wrong 'username'. 3129 */ 3130 MHD_DAUTH_WRONG_USERNAME = -17 3131 , 3132 /** 3133 * Wrong 'realm'. 3134 */ 3135 MHD_DAUTH_WRONG_REALM = -18 3136 , 3137 /** 3138 * Wrong 'URI' (or URI parameters). 3139 */ 3140 MHD_DAUTH_WRONG_URI = -19 3141 , 3142 /** 3143 * Wrong 'qop'. 3144 */ 3145 MHD_DAUTH_WRONG_QOP = -20 3146 , 3147 /** 3148 * Wrong 'algorithm'. 3149 */ 3150 MHD_DAUTH_WRONG_ALGO = -21 3151 , 3152 /** 3153 * Too large (>64 KiB) Authorization parameter value. 3154 */ 3155 MHD_DAUTH_TOO_LARGE = -22 3156 , 3157 /* The different form of naming is intentionally used for the results below, 3158 * as they are more important */ 3159 3160 /** 3161 * The 'nonce' is too old. Suggest the client to retry with the same 3162 * username and password to get the fresh 'nonce'. 3163 * The validity of the 'nonce' may be not checked. 3164 */ 3165 MHD_DAUTH_NONCE_STALE = -25 3166 , 3167 /** 3168 * The 'nonce' is wrong. May indicate an attack attempt. 3169 */ 3170 MHD_DAUTH_NONCE_WRONG = -33 3171 , 3172 /** 3173 * The 'response' is wrong. May indicate a wrong password used or 3174 * an attack attempt. 3175 */ 3176 MHD_DAUTH_RESPONSE_WRONG = -34 3177 }; 3178 3179 3180 /** 3181 * Authenticates the authorization header sent by the client. 3182 * 3183 * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in 3184 * @a mqop and the client uses this mode, then server generated nonces are 3185 * used as one-time nonces because nonce-count is not supported in this old RFC. 3186 * Communication in this mode is very inefficient, especially if the client 3187 * requests several resources one-by-one as for every request a new nonce must 3188 * be generated and client repeats all requests twice (first time to get a new 3189 * nonce and second time to perform an authorised request). 3190 * 3191 * @param request the request 3192 * @param realm the realm for authorization of the client 3193 * @param username the username to be authenticated, must be in clear text 3194 * even if userhash is used by the client 3195 * @param password the password matching the @a username (and the @a realm) 3196 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc 3197 * exceeds the specified value then MHD_DAUTH_NONCE_STALE is 3198 * returned; 3199 * if zero is specified then daemon default value is used. 3200 * @param mqop the QOP to use 3201 * @param malgo digest algorithms allowed to use, fail if algorithm used 3202 * by the client is not allowed by this parameter 3203 * @return #MHD_DAUTH_OK if authenticated, 3204 * the error code otherwise 3205 * @ingroup authentication 3206 */ 3207 MHD_EXTERN_ enum MHD_DigestAuthResult 3208 MHD_digest_auth_check (struct MHD_Request *MHD_RESTRICT request, 3209 const char *MHD_RESTRICT realm, 3210 const char *MHD_RESTRICT username, 3211 const char *MHD_RESTRICT password, 3212 uint_fast32_t max_nc, 3213 enum MHD_DigestAuthMultiQOP mqop, 3214 enum MHD_DigestAuthMultiAlgo malgo) 3215 MHD_FN_PAR_NONNULL_ALL_ 3216 MHD_FN_PAR_CSTR_ (2) MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_CSTR_ (4); 3217 3218 3219 /** 3220 * Calculate userdigest, return it as a binary data. 3221 * 3222 * The "userdigest" is the hash of the "username:realm:password" string. 3223 * 3224 * The "userdigest" can be used to avoid storing the password in clear text 3225 * in database/files 3226 * 3227 * This function is designed to improve security of stored credentials, 3228 * the "userdigest" does not improve security of the authentication process. 3229 * 3230 * The results can be used to store username & userdigest pairs instead of 3231 * username & password pairs. To further improve security, application may 3232 * store username & userhash & userdigest triplets. 3233 * 3234 * @param algo the digest algorithm 3235 * @param username the username 3236 * @param realm the realm 3237 * @param password the password 3238 * @param bin_buf_size the size of the @a userdigest_bin buffer, must be 3239 * at least #MHD_digest_get_hash_size() bytes long 3240 * @param[out] userdigest_bin the output buffer for userdigest; 3241 * if this function succeeds, then this buffer has 3242 * #MHD_digest_get_hash_size() bytes of 3243 * userdigest upon return 3244 * @return #MHD_SC_OK on success, 3245 * #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small, 3246 * #MHD_SC_HASH_FAILED if hashing failed, 3247 * #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is 3248 * unknown or unsupported. 3249 * @sa #MHD_digest_auth_check_digest() 3250 * @ingroup authentication 3251 */ 3252 MHD_EXTERN_ enum MHD_StatusCode 3253 MHD_digest_auth_calc_userdigest (enum MHD_DigestAuthAlgo algo, 3254 const char *MHD_RESTRICT username, 3255 const char *MHD_RESTRICT realm, 3256 const char *MHD_RESTRICT password, 3257 size_t bin_buf_size, 3258 void *MHD_RESTRICT userdigest_bin) 3259 MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ 3260 MHD_FN_PAR_CSTR_ (2) 3261 MHD_FN_PAR_CSTR_ (3) 3262 MHD_FN_PAR_CSTR_ (4) 3263 MHD_FN_PAR_OUT_SIZE_ (6,5); 3264 3265 3266 /** 3267 * Authenticates the authorization header sent by the client by using 3268 * hash of "username:realm:password". 3269 * 3270 * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in 3271 * @a mqop and the client uses this mode, then server generated nonces are 3272 * used as one-time nonces because nonce-count is not supported in this old RFC. 3273 * Communication in this mode is very inefficient, especially if the client 3274 * requests several resources one-by-one as for every request a new nonce must 3275 * be generated and client repeats all requests twice (first time to get a new 3276 * nonce and second time to perform an authorised request). 3277 * 3278 * @param request the request 3279 * @param realm the realm for authorization of the client 3280 * @param username the username to be authenticated, must be in clear text 3281 * even if userhash is used by the client 3282 * @param userdigest_size the size of the @a userdigest in bytes, must match the 3283 * hashing algorithm (see #MHD_MD5_DIGEST_SIZE, 3284 * #MHD_SHA256_DIGEST_SIZE, #MHD_SHA512_256_DIGEST_SIZE, 3285 * #MHD_digest_get_hash_size()) 3286 * @param userdigest the precalculated binary hash of the string 3287 * "username:realm:password", 3288 * see #MHD_digest_auth_calc_userdigest() 3289 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc 3290 * exceeds the specified value then MHD_DAUTH_NONCE_STALE is 3291 * returned; 3292 * if zero is specified then daemon default value is used. 3293 * @param mqop the QOP to use 3294 * @param malgo digest algorithms allowed to use, fail if algorithm used 3295 * by the client is not allowed by this parameter; 3296 * more than one base algorithms (MD5, SHA-256, SHA-512/256) 3297 * cannot be used at the same time for this function 3298 * as @a userdigest must match specified algorithm 3299 * @return #MHD_DAUTH_OK if authenticated, 3300 * the error code otherwise 3301 * @sa #MHD_digest_auth_calc_userdigest() 3302 * @ingroup authentication 3303 */ 3304 MHD_EXTERN_ enum MHD_DigestAuthResult 3305 MHD_digest_auth_check_digest (struct MHD_Request *MHD_RESTRICT request, 3306 const char *MHD_RESTRICT realm, 3307 const char *MHD_RESTRICT username, 3308 size_t userdigest_size, 3309 const void *MHD_RESTRICT userdigest, 3310 uint_fast32_t max_nc, 3311 enum MHD_DigestAuthMultiQOP mqop, 3312 enum MHD_DigestAuthMultiAlgo malgo) 3313 MHD_FN_PAR_NONNULL_ALL_ 3314 MHD_FN_PAR_CSTR_ (2) 3315 MHD_FN_PAR_CSTR_ (3) 3316 MHD_FN_PAR_IN_SIZE_ (5, 4); 3317 3318 3319 /** 3320 * Add Digest Authentication "challenge" to the response. 3321 * 3322 * The response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3323 * 3324 * If @a mqop allows both RFC 2069 (#MHD_DIGEST_AUTH_QOP_NONE) and other QOP 3325 * values, then the "challenge" is formed like if MHD_DIGEST_AUTH_QOP_NONE bit 3326 * was not set, because such "challenge" should be backward-compatible with 3327 * RFC 2069. 3328 * 3329 * If @a mqop allows only MHD_DIGEST_AUTH_MULT_QOP_NONE, then the response is 3330 * formed in strict accordance with RFC 2069 (no 'qop', no 'userhash', no 3331 * 'charset'). For better compatibility with clients, it is recommended (but 3332 * not required) to set @a domain to NULL in this mode. 3333 * 3334 * New nonces are generated each time when the resulting response is used. 3335 * 3336 * See RFC 7616, section 3.3 for details. 3337 * 3338 * @param response the response to update; should contain the "access denied" 3339 * body; 3340 * note: this function sets the "WWW Authenticate" header and 3341 * the caller should not set this header; 3342 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3343 * code; 3344 * the NULL is tolerated (the result is 3345 * #MHD_SC_RESP_POINTER_NULL) 3346 * @param realm the realm presented to the client 3347 * @param opaque the string for opaque value, can be NULL, but NULL is 3348 * not recommended for better compatibility with clients; 3349 * the recommended format is hex or Base64 encoded string 3350 * @param domain the optional space-separated list of URIs for which the 3351 * same authorisation could be used, URIs can be in form 3352 * "path-absolute" (the path for the same host with initial slash) 3353 * or in form "absolute-URI" (the full path with protocol), in 3354 * any case client may assume that URI is in the same "protection 3355 * space" if it starts with any of values specified here; 3356 * could be NULL (clients typically assume that the same 3357 * credentials could be used for any URI on the same host); 3358 * this list provides information for the client only and does 3359 * not actually restrict anything on the server side 3360 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used 3361 * in the client's request is indicated by adding 3362 * 'stale=true' to the authentication header, this 3363 * instructs the client to retry immediately with the new 3364 * nonce and the same credentials, without asking user 3365 * for the new password 3366 * @param mqop the QOP to use 3367 * @param malgo digest algorithm to use; if several algorithms are allowed 3368 * then one challenge for each allowed algorithm is added 3369 * @param userhash_support if set to #MHD_YES then support of userhash is 3370 * indicated, allowing client to provide 3371 * hash("username:realm") instead of the username in 3372 * clear text; 3373 * note that clients are allowed to provide the username 3374 * in cleartext even if this parameter set to non-zero; 3375 * when userhash is used, application must be ready to 3376 * identify users by provided userhash value instead of 3377 * username; see #MHD_digest_auth_calc_userhash() and 3378 * #MHD_digest_auth_calc_userhash_hex() 3379 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is 3380 * added, indicating for the client that UTF-8 encoding for 3381 * the username is preferred 3382 * @return #MHD_SC_OK if succeed, 3383 * #MHD_SC_TOO_LATE if the response has been already "frozen" (used to 3384 * create an action), 3385 * #MHD_SC_RESP_HEADERS_CONFLICT if Digest Authentication "challenge" 3386 * has been added already, 3387 * #MHD_SC_RESP_POINTER_NULL if @a response is NULL, 3388 * #MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE is response status code is wrong, 3389 * #MHD_SC_RESP_HEADER_VALUE_INVALID if @a realm, @a opaque or @a domain 3390 * have wrong characters or zero length (for @a realm), 3391 * #MHD_SC_RESPONSE_HEADER_MEM_ALLOC_FAILED if memory allocation failed, 3392 * or other error code if failed 3393 * @ingroup authentication 3394 */ 3395 MHD_EXTERN_ enum MHD_StatusCode 3396 MHD_response_add_auth_digest_challenge ( 3397 struct MHD_Response *MHD_RESTRICT response, 3398 const char *MHD_RESTRICT realm, 3399 const char *MHD_RESTRICT opaque, 3400 const char *MHD_RESTRICT domain, 3401 enum MHD_Bool indicate_stale, 3402 enum MHD_DigestAuthMultiQOP mqop, 3403 enum MHD_DigestAuthMultiAlgo malgo, 3404 enum MHD_Bool userhash_support, 3405 enum MHD_Bool prefer_utf8) 3406 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2) 3407 MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_CSTR_ (4); 3408 3409 3410 /* Application may define MHD_NO_STATIC_INLINE macro before including 3411 libmicrohttpd headers to disable static inline functions in the headers. */ 3412 #ifndef MHD_NO_STATIC_INLINE 3413 3414 /** 3415 * Create action to reply with Digest Authentication "challenge". 3416 * 3417 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3418 * 3419 * See RFC 7616, section 3.3 for details. 3420 * 3421 * @param request the request to create the action for 3422 * @param realm the realm presented to the client 3423 * @param opaque the string for opaque value, can be NULL, but NULL is 3424 * not recommended for better compatibility with clients; 3425 * the recommended format is hex or Base64 encoded string 3426 * @param domain the optional space-separated list of URIs for which the 3427 * same authorisation could be used, URIs can be in form 3428 * "path-absolute" (the path for the same host with initial slash) 3429 * or in form "absolute-URI" (the full path with protocol), in 3430 * any case client may assume that URI is in the same "protection 3431 * space" if it starts with any of values specified here; 3432 * could be NULL (clients typically assume that the same 3433 * credentials could be used for any URI on the same host); 3434 * this list provides information for the client only and does 3435 * not actually restrict anything on the server side 3436 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used 3437 * in the client's request is indicated by adding 3438 * 'stale=true' to the authentication header, this 3439 * instructs the client to retry immediately with the new 3440 * nonce and the same credentials, without asking user 3441 * for the new password 3442 * @param mqop the QOP to use 3443 * @param malgo digest algorithm to use; if several algorithms are allowed 3444 * then one challenge for each allowed algorithm is added 3445 * @param userhash_support if set to #MHD_YES then support of userhash is 3446 * indicated, allowing client to provide 3447 * hash("username:realm") instead of the username in 3448 * clear text; 3449 * note that clients are allowed to provide the username 3450 * in cleartext even if this parameter set to non-zero; 3451 * when userhash is used, application must be ready to 3452 * identify users by provided userhash value instead of 3453 * username; see #MHD_digest_auth_calc_userhash() and 3454 * #MHD_digest_auth_calc_userhash_hex() 3455 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is 3456 * added, indicating for the client that UTF-8 encoding for 3457 * the username is preferred 3458 * @param response the response to update; should contain the "access denied" 3459 * body; 3460 * note: this function sets the "WWW Authenticate" header and 3461 * the caller should not set this header; 3462 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3463 * code; 3464 * the NULL is tolerated (the result is 3465 * #MHD_SC_RESP_POINTER_NULL) 3466 * @param abort_if_failed if set to #MHD_NO the response will be used even if 3467 * failed to add Basic Authentication "challenge", 3468 * if not set to #MHD_NO the request will be aborted 3469 * if the "challenge" could not be added. 3470 * @return pointer to the action, the action must be consumed 3471 * otherwise response object may leak; 3472 * NULL if failed or if any action has been already created for 3473 * the @a request; 3474 * when failed the response object is consumed and need not 3475 * to be "destroyed" 3476 * @ingroup authentication 3477 */ 3478 MHD_STATIC_INLINE_ 3479 MHD_FN_PAR_NONNULL_ (1) 3480 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2) 3481 const struct MHD_Action * 3482 MHD_action_digest_auth_challenge (struct MHD_Request *MHD_RESTRICT request, 3483 const char *MHD_RESTRICT realm, 3484 const char *MHD_RESTRICT opaque, 3485 const char *MHD_RESTRICT domain, 3486 enum MHD_Bool indicate_stale, 3487 enum MHD_DigestAuthMultiQOP mqop, 3488 enum MHD_DigestAuthMultiAlgo malgo, 3489 enum MHD_Bool userhash_support, 3490 enum MHD_Bool prefer_utf8, 3491 struct MHD_Response *MHD_RESTRICT response, 3492 enum MHD_Bool abort_if_failed) 3493 { 3494 if ((MHD_SC_OK != 3495 MHD_response_add_auth_digest_challenge (response, realm, opaque, domain, 3496 indicate_stale, mqop, malgo, 3497 userhash_support, prefer_utf8)) 3498 && (MHD_NO != abort_if_failed)) 3499 { 3500 MHD_response_destroy (response); 3501 return MHD_action_abort_request (request); 3502 } 3503 return MHD_action_from_response (request, response); 3504 } 3505 3506 3507 MHD_STATIC_INLINE_END_ 3508 3509 /** 3510 * Create action to reply with Digest Authentication "challenge". 3511 * 3512 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3513 * 3514 * If the @a response object cannot be extended with the "challenge", 3515 * the @a response is used to reply without the "challenge". 3516 * 3517 * @param request the request to create the action for 3518 * @param realm the realm presented to the client 3519 * @param opaque the string for opaque value, can be NULL, but NULL is 3520 * not recommended for better compatibility with clients; 3521 * the recommended format is hex or Base64 encoded string 3522 * @param domain the optional space-separated list of URIs for which the 3523 * same authorisation could be used, URIs can be in form 3524 * "path-absolute" (the path for the same host with initial slash) 3525 * or in form "absolute-URI" (the full path with protocol), in 3526 * any case client may assume that URI is in the same "protection 3527 * space" if it starts with any of values specified here; 3528 * could be NULL (clients typically assume that the same 3529 * credentials could be used for any URI on the same host); 3530 * this list provides information for the client only and does 3531 * not actually restrict anything on the server side 3532 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used 3533 * in the client's request is indicated by adding 3534 * 'stale=true' to the authentication header, this 3535 * instructs the client to retry immediately with the new 3536 * nonce and the same credentials, without asking user 3537 * for the new password 3538 * @param mqop the QOP to use 3539 * @param algo digest algorithm to use; if several algorithms are allowed 3540 * then one challenge for each allowed algorithm is added 3541 * @param userhash_support if set to #MHD_YES then support of userhash is 3542 * indicated, allowing client to provide 3543 * hash("username:realm") instead of the username in 3544 * clear text; 3545 * note that clients are allowed to provide the username 3546 * in cleartext even if this parameter set to non-zero; 3547 * when userhash is used, application must be ready to 3548 * identify users by provided userhash value instead of 3549 * username; see #MHD_digest_auth_calc_userhash() and 3550 * #MHD_digest_auth_calc_userhash_hex() 3551 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is 3552 * added, indicating for the client that UTF-8 encoding for 3553 * the username is preferred 3554 * @param response the response to update; should contain the "access denied" 3555 * body; 3556 * note: this function sets the "WWW Authenticate" header and 3557 * the caller should not set this header; 3558 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3559 * code; 3560 * the NULL is tolerated (the result is 3561 * #MHD_SC_RESP_POINTER_NULL) 3562 * @return pointer to the action, the action must be consumed 3563 * otherwise response object may leak; 3564 * NULL if failed or if any action has been already created for 3565 * the @a request; 3566 * when failed the response object is consumed and need not 3567 * to be "destroyed" 3568 * @ingroup authentication 3569 */ 3570 #define MHD_action_digest_auth_challenge_p(rq,rlm,opq,dmn,stl,mqop,malgo, \ 3571 uh,utf,resp) \ 3572 MHD_action_digest_auth_challenge ((rq),(rlm),(opq),(dmn),(stl),(mqop), \ 3573 (malgo),(uh),(utf),(resp),MHD_NO) 3574 3575 3576 /** 3577 * Create action to reply with Digest Authentication "challenge". 3578 * 3579 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3580 * 3581 * If the @a response object cannot be extended with the "challenge", 3582 * the @a response is aborted. 3583 * 3584 * @param request the request to create the action for 3585 * @param realm the realm presented to the client 3586 * @param opaque the string for opaque value, can be NULL, but NULL is 3587 * not recommended for better compatibility with clients; 3588 * the recommended format is hex or Base64 encoded string 3589 * @param domain the optional space-separated list of URIs for which the 3590 * same authorisation could be used, URIs can be in form 3591 * "path-absolute" (the path for the same host with initial slash) 3592 * or in form "absolute-URI" (the full path with protocol), in 3593 * any case client may assume that URI is in the same "protection 3594 * space" if it starts with any of values specified here; 3595 * could be NULL (clients typically assume that the same 3596 * credentials could be used for any URI on the same host); 3597 * this list provides information for the client only and does 3598 * not actually restrict anything on the server side 3599 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used 3600 * in the client's request is indicated by adding 3601 * 'stale=true' to the authentication header, this 3602 * instructs the client to retry immediately with the new 3603 * nonce and the same credentials, without asking user 3604 * for the new password 3605 * @param mqop the QOP to use 3606 * @param algo digest algorithm to use; if several algorithms are allowed 3607 * then one challenge for each allowed algorithm is added 3608 * @param userhash_support if set to #MHD_YES then support of userhash is 3609 * indicated, allowing client to provide 3610 * hash("username:realm") instead of the username in 3611 * clear text; 3612 * note that clients are allowed to provide the username 3613 * in cleartext even if this parameter set to non-zero; 3614 * when userhash is used, application must be ready to 3615 * identify users by provided userhash value instead of 3616 * username; see #MHD_digest_auth_calc_userhash() and 3617 * #MHD_digest_auth_calc_userhash_hex() 3618 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is 3619 * added, indicating for the client that UTF-8 encoding for 3620 * the username is preferred 3621 * @param response the response to update; should contain the "access denied" 3622 * body; 3623 * note: this function sets the "WWW Authenticate" header and 3624 * the caller should not set this header; 3625 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3626 * code; 3627 * the NULL is tolerated (the result is 3628 * #MHD_SC_RESP_POINTER_NULL) 3629 * @return pointer to the action, the action must be consumed 3630 * otherwise response object may leak; 3631 * NULL if failed or if any action has been already created for 3632 * the @a request; 3633 * when failed the response object is consumed and need not 3634 * to be "destroyed" 3635 * @ingroup authentication 3636 */ 3637 #define MHD_action_digest_auth_challenge_a(rq,rlm,opq,dmn,stl,mqop,malgo, \ 3638 uh,utf,resp) \ 3639 MHD_action_digest_auth_challenge ((rq),(rlm),(opq),(dmn),(stl),(mqop), \ 3640 (malgo),(uh),(utf),(resp),MHD_YES) 3641 3642 #endif /* ! MHD_NO_STATIC_INLINE */ 3643 3644 3645 /** 3646 * Add Basic Authentication "challenge" to the response. 3647 * 3648 * The response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3649 * 3650 * If access to any resource should be limited to specific users, authenticated 3651 * by Basic Authentication mechanism, and the request for this resource does not 3652 * have Basic Authentication information (see #MHD_AuthBasicCreds), then response 3653 * with Basic Authentication "challenge" should be sent. This works as 3654 * an indication that Basic Authentication should be used for the access. 3655 * 3656 * See RFC 7617, section-2 for details. 3657 * 3658 * @param response the reply to send; should contain the "access denied" 3659 * body; 3660 * note: this function sets the "WWW Authenticate" header and 3661 * the caller should not set this header; 3662 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3663 * code; 3664 * the NULL is tolerated (the result is 3665 * #MHD_SC_RESP_POINTER_NULL) 3666 * @param realm the realm presented to the client 3667 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will 3668 * be added, indicating for client that UTF-8 encoding 3669 * is preferred 3670 * @return #MHD_SC_OK if succeed, 3671 * #MHD_SC_TOO_LATE if the response has been already "frozen" (used to 3672 * create an action), 3673 * #MHD_SC_RESP_HEADERS_CONFLICT if Basic Authentication "challenge" 3674 * has been added already, 3675 * #MHD_SC_RESP_POINTER_NULL if @a response is NULL, 3676 * #MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE is response status code is wrong, 3677 * #MHD_SC_RESP_HEADER_VALUE_INVALID if realm is zero-length or has CR 3678 * or LF characters, 3679 * #MHD_SC_RESPONSE_HEADER_MEM_ALLOC_FAILED if memory allocation failed, 3680 * or other error code if failed 3681 * @ingroup authentication 3682 */ 3683 MHD_EXTERN_ enum MHD_StatusCode 3684 MHD_response_add_auth_basic_challenge ( 3685 struct MHD_Response *MHD_RESTRICT response, 3686 const char *MHD_RESTRICT realm, 3687 enum MHD_Bool prefer_utf8) 3688 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2); 3689 3690 /* Application may define MHD_NO_STATIC_INLINE macro before including 3691 libmicrohttpd headers to disable static inline functions in the headers. */ 3692 #ifndef MHD_NO_STATIC_INLINE 3693 3694 /** 3695 * Create action to reply with Basic Authentication "challenge". 3696 * 3697 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3698 * 3699 * If access to any resource should be limited to specific users, authenticated 3700 * by Basic Authentication mechanism, and the request for this resource does not 3701 * have Basic Authentication information (see #MHD_AuthBasicCreds), then response 3702 * with Basic Authentication "challenge" should be sent. This works as 3703 * an indication that Basic Authentication should be used for the access. 3704 * 3705 * See RFC 7617, section-2 for details. 3706 * 3707 * @param request the request to create the action for 3708 * @param realm the realm presented to the client 3709 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will 3710 * be added, indicating for client that UTF-8 encoding 3711 * is preferred 3712 * @param response the reply to send; should contain the "access denied" 3713 * body; 3714 * note: this function adds the "WWW Authenticate" header in 3715 * the response and the caller should not set this header; 3716 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3717 * code; 3718 * the NULL is tolerated (the result is 3719 * #MHD_action_abort_request()) 3720 * @param abort_if_failed if set to #MHD_NO the response will be used even if 3721 * failed to add Basic Authentication "challenge", 3722 * if not set to #MHD_NO the request will be aborted 3723 * if the "challenge" could not be added. 3724 * @return pointer to the action, the action must be consumed 3725 * otherwise response object may leak; 3726 * NULL if failed or if any action has been already created for 3727 * the @a request; 3728 * when failed the response object is consumed and need not 3729 * to be "destroyed" 3730 * @ingroup authentication 3731 */ 3732 MHD_STATIC_INLINE_ 3733 MHD_FN_PAR_NONNULL_ (1) 3734 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2) 3735 const struct MHD_Action * 3736 MHD_action_basic_auth_challenge (struct MHD_Request *MHD_RESTRICT request, 3737 const char *MHD_RESTRICT realm, 3738 enum MHD_Bool prefer_utf8, 3739 struct MHD_Response *MHD_RESTRICT response, 3740 enum MHD_Bool abort_if_failed) 3741 { 3742 if ((MHD_SC_OK != 3743 MHD_response_add_auth_basic_challenge (response, realm, prefer_utf8)) 3744 && (MHD_NO != abort_if_failed)) 3745 { 3746 MHD_response_destroy (response); 3747 return MHD_action_abort_request (request); 3748 } 3749 return MHD_action_from_response (request, response); 3750 } 3751 3752 3753 MHD_STATIC_INLINE_END_ 3754 3755 3756 /** 3757 * Create action to reply with Basic Authentication "challenge". 3758 * 3759 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3760 * 3761 * If the @a response object cannot be extended with the "challenge", 3762 * the @a response will be used to reply without the "challenge". 3763 * 3764 * @param request the request to create the action for 3765 * @param realm the realm presented to the client 3766 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will 3767 * be added, indicating for client that UTF-8 encoding 3768 * is preferred 3769 * @param response the reply to send; should contain the "access denied" 3770 * body; 3771 * note: this function adds the "WWW Authenticate" header in 3772 * the response and the caller should not set this header; 3773 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3774 * code; 3775 * the NULL is tolerated (the result is 3776 * #MHD_action_abort_request()) 3777 * @return pointer to the action, the action must be consumed 3778 * otherwise response object may leak; 3779 * NULL if failed or if any action has been already created for 3780 * the @a request; 3781 * when failed the response object is consumed and need not 3782 * to be "destroyed" 3783 * @ingroup authentication 3784 */ 3785 #define MHD_action_basic_auth_challenge_p(request,realm,prefer_utf8,response) \ 3786 MHD_action_basic_auth_challenge ((request), (realm), (prefer_utf8), \ 3787 (response), MHD_NO) 3788 3789 /** 3790 * Create action to reply with Basic Authentication "challenge". 3791 * 3792 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code. 3793 * 3794 * If the @a response object cannot be extended with the "challenge", 3795 * the request will be aborted. 3796 * 3797 * @param request the request to create the action for 3798 * @param realm the realm presented to the client 3799 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will 3800 * be added, indicating for client that UTF-8 encoding 3801 * is preferred 3802 * @param response the reply to send; should contain the "access denied" 3803 * body; 3804 * note: this function adds the "WWW Authenticate" header in 3805 * the response and the caller should not set this header; 3806 * the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status 3807 * code; 3808 * the NULL is tolerated (the result is 3809 * #MHD_action_abort_request()) 3810 * @return pointer to the action, the action must be consumed 3811 * otherwise response object may leak; 3812 * NULL if failed or if any action has been already created for 3813 * the @a request; 3814 * when failed the response object is consumed and need not 3815 * to be "destroyed" 3816 * @ingroup authentication 3817 */ 3818 #define MHD_action_basic_auth_challenge_a(request,realm,prefer_utf8,response) \ 3819 MHD_action_basic_auth_challenge ((request), (realm), (prefer_utf8), \ 3820 (response), MHD_YES) 3821 3822 #endif /* ! MHD_NO_STATIC_INLINE */ 3823 3824 3825 /** 3826 * Information decoded from Basic Authentication client's header. 3827 * 3828 * @see #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS 3829 */ 3830 struct MHD_AuthBasicCreds 3831 { 3832 /** 3833 * The username 3834 */ 3835 struct MHD_String username; 3836 3837 /** 3838 * The password, string pointer may be NULL if password is not encoded 3839 * by the client. 3840 */ 3841 struct MHD_StringNullable password; 3842 }; 3843 3844 /* ********************** (f) Introspection ********************** */ 3845 3846 3847 /** 3848 * Types of information about MHD, used by #MHD_lib_get_info_fixed_sz(). 3849 * This information is not changed at run-time. 3850 */ 3851 enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoFixed 3852 { 3853 /* * Basic MHD information * */ 3854 3855 /** 3856 * Get the MHD version as a number. 3857 * The result is placed in @a v_version_num_uint32 member. 3858 */ 3859 MHD_LIB_INFO_FIXED_VERSION_NUM = 0 3860 , 3861 /** 3862 * Get the MHD version as a string. 3863 * The result is placed in @a v_version_string member. 3864 */ 3865 MHD_LIB_INFO_FIXED_VERSION_STRING = 1 3866 , 3867 3868 /* * Basic MHD features, buid-time configurable * */ 3869 /* These features should be always available unless the library was 3870 * not compiled specifically for some embedded project. 3871 * Exceptions are marked explicitly in the description. */ 3872 3873 /** 3874 * Get whether messages are supported. If supported then messages can be 3875 * printed to stderr or to an external logger. 3876 * The result is placed in @a v_support_log_messages_bool member. 3877 */ 3878 MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES = 11 3879 , 3880 /** 3881 * Get whether detailed automatic HTTP reply messages are supported. 3882 * If supported then automatic responses have bodies with text explaining 3883 * the error details. 3884 * Automatic responses are sent by MHD automatically when client is violating 3885 * HTTP specification, for example, the request header has whitespace in 3886 * header name or request's "Content-Length" header has non-number value. 3887 * The result is placed in @a v_support_auto_replies_bodies_bool member. 3888 */ 3889 MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES = 12 3890 , 3891 /** 3892 * Get whether MHD was built with debug asserts disabled. 3893 * These asserts enabled only on special debug builds. 3894 * For debug builds the error log is always enabled. 3895 * The result is placed in @a v_is_non_debug_bool member. 3896 */ 3897 MHD_LIB_INFO_FIXED_IS_NON_DEBUG = 13 3898 , 3899 /** 3900 * Get whether MHD supports threads. 3901 * The result is placed in @a v_support_threads_bool member. 3902 */ 3903 MHD_LIB_INFO_FIXED_SUPPORT_THREADS = 14 3904 , 3905 /** 3906 * Get whether automatic parsing of HTTP Cookie header is supported. 3907 * If disabled, no #MHD_VK_COOKIE will be generated by MHD. 3908 * The result is placed in @a v_support_cookie_parser_bool member. 3909 */ 3910 MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER = 15 3911 , 3912 /** 3913 * Get whether postprocessor is supported. If supported then 3914 * #MHD_action_post_processor() can be used. 3915 * The result is placed in @a v_support_post_parser_bool member. 3916 */ 3917 MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER = 16 3918 , 3919 /** 3920 * Get whether HTTP "Upgrade" is supported. 3921 * If supported then #MHD_action_upgrade() can be used. 3922 * The result is placed in @a v_support_upgrade_bool member. 3923 */ 3924 MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE = 17 3925 , 3926 /** 3927 * Get whether HTTP Basic authorization is supported. If supported 3928 * then functions #MHD_action_basic_auth_required_response () 3929 * and #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS can be used. 3930 * The result is placed in @a v_support_auth_basic_bool member. 3931 */ 3932 MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC = 20 3933 , 3934 /** 3935 * Get whether HTTP Digest authorization is supported. If 3936 * supported then options #MHD_D_O_RANDOM_ENTROPY, 3937 * #MHD_D_O_DAUTH_MAP_SIZE and functions 3938 * #MHD_action_digest_auth_required_response () and 3939 * #MHD_digest_auth_check() can be used. 3940 * The result is placed in @a v_support_auth_digest_bool member. 3941 */ 3942 MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST = 21 3943 , 3944 /** 3945 * Get whether the early version the Digest Authorization (RFC 2069) is 3946 * supported (digest authorisation without QOP parameter). 3947 * Currently it is always supported if Digest Auth module is built. 3948 * The result is placed in @a v_support_digest_auth_rfc2069_bool member. 3949 */ 3950 MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069 = 22 3951 , 3952 /** 3953 * Get whether the MD5-based hashing algorithms are supported for Digest 3954 * Authorization and the type of the implementation if supported. 3955 * Currently it is always supported if Digest Auth module is built 3956 * unless manually disabled in a custom build. 3957 * The result is placed in @a v_type_digest_auth_md5_algo_type member. 3958 */ 3959 MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 = 23 3960 , 3961 /** 3962 * Get whether the SHA-256-based hashing algorithms are supported for Digest 3963 * Authorization and the type of the implementation if supported. 3964 * Currently it is always supported if Digest Auth module is built 3965 * unless manually disabled in a custom build. 3966 * The result is placed in @a v_type_digest_auth_sha256_algo_type member. 3967 */ 3968 MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 = 24 3969 , 3970 /** 3971 * Get whether the SHA-512/256-based hashing algorithms are supported 3972 * Authorization and the type of the implementation if supported. 3973 * Currently it is always supported if Digest Auth module is built 3974 * unless manually disabled in a custom build. 3975 * The result is placed in @a v_type_digest_auth_sha512_256_algo_type member. 3976 */ 3977 MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 = 25 3978 , 3979 /** 3980 * Get whether QOP with value 'auth-int' (authentication with integrity 3981 * protection) is supported for Digest Authorization. 3982 * Currently it is always not supported. 3983 * The result is placed in @a v_support_digest_auth_auth_int_bool member. 3984 */ 3985 MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT = 28 3986 , 3987 /** 3988 * Get whether 'session' algorithms (like 'MD5-sess') are supported for Digest 3989 * Authorization. 3990 * Currently it is always not supported. 3991 * The result is placed in @a v_support_digest_auth_algo_session_bool member. 3992 */ 3993 MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION = 29 3994 , 3995 /** 3996 * Get whether 'userhash' is supported for Digest Authorization. 3997 * Currently it is always supported if Digest Auth module is built. 3998 * The result is placed in @a v_support_digest_auth_userhash_bool member. 3999 */ 4000 MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH = 30 4001 , 4002 4003 /* * Platform-dependent features, some are configurable at build-time * */ 4004 /* These features depends on the platform, third-party libraries and 4005 * the toolchain. 4006 * Some of the features can be disabled or selected at build-time. */ 4007 /** 4008 * Get sockets polling functions/techniques supported by this MHD build. 4009 * Some functions can be disabled (like epoll) in kernel, this is not 4010 * checked. 4011 * The result is placed in @a v_types_sockets_polling member. 4012 */ 4013 MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING = 60 4014 , 4015 /** 4016 * Get whether aggregate FD external polling is supported. 4017 * The result is placed in @a v_support_aggregate_fd_bool member. 4018 */ 4019 MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD = 61 4020 , 4021 /** 4022 * Get whether IPv6 is supported on the platform and IPv6-only listen socket 4023 * can be used. 4024 * The result is placed in @a v_ipv6 member. 4025 * @note The platform may have disabled IPv6 at run-time, it is not checked 4026 * by this information type. 4027 */ 4028 MHD_LIB_INFO_FIXED_TYPE_IPV6 = 62 4029 , 4030 /** 4031 * Get whether TCP Fast Open is supported by MHD build. 4032 * If supported then option #MHD_D_O_TCP_FASTOPEN can be used. 4033 * The result is placed in @a v_support_tcp_fastopen_bool member. 4034 */ 4035 MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN = 64 4036 , 4037 /** 4038 * Get whether MHD support automatic detection of bind port number. 4039 * @sa #MHD_D_O_BIND_PORT 4040 * The result is placed in @a v_has_autodetect_bind_port_bool member. 4041 */ 4042 MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT = 65 4043 , 4044 /** 4045 * Get whether MHD use system's sendfile() function to send 4046 * file-FD based responses over non-TLS connections. 4047 * The result is placed in @a v_has_sendfile_bool member. 4048 */ 4049 MHD_LIB_INFO_FIXED_HAS_SENDFILE = 66 4050 , 4051 /** 4052 * Get whether MHD supports automatic SIGPIPE suppression within internal 4053 * events loop (MHD's managed threads). 4054 * If SIGPIPE suppression is not supported, application must handle 4055 * SIGPIPE signal by itself whem using MHD with internal events loop. 4056 * If the platform does not have SIGPIPE the result is #MHD_YES. 4057 * The result is placed in @a v_has_autosuppress_sigpipe_int_bool member. 4058 */ 4059 MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT = 80 4060 , 4061 /** 4062 * Get whether MHD supports automatic SIGPIPE suppression when used with 4063 * extenal events loop (in application thread). 4064 * If SIGPIPE suppression is not supported, application must handle 4065 * SIGPIPE signal by itself whem using MHD with external events loop. 4066 * If the platform does not have SIGPIPE the result is #MHD_YES. 4067 * The result is placed in @a v_has_autosuppress_sigpipe_ext_bool member. 4068 */ 4069 MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT = 81 4070 , 4071 /** 4072 * Get whether MHD sets names on generated threads. 4073 * The result is placed in @a v_has_thread_names_bool member. 4074 */ 4075 MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES = 82 4076 , 4077 /** 4078 * Get the type of supported inter-thread communication. 4079 * The result is placed in @a v_type_itc member. 4080 */ 4081 MHD_LIB_INFO_FIXED_TYPE_ITC = 83 4082 , 4083 /** 4084 * Get whether reading files beyond 2 GiB boundary is supported. 4085 * If supported then #MHD_response_from_fd() can be used with sizes and 4086 * offsets larger than 2 GiB. If not supported value of size+offset could be 4087 * limited to 2 GiB. 4088 * The result is placed in @a v_support_large_file_bool member. 4089 */ 4090 MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE = 84 4091 , 4092 4093 /* * Platform-dependent features, some set on startup and some are 4094 * configurable at build-time * */ 4095 /* These features depends on the platform, third-party libraries availability 4096 * and configuration. The features can be enabled/disabled during startup 4097 * of the library depending on conditions. 4098 * Some of the features can be disabled or selected at build-time. */ 4099 /** 4100 * Get whether HTTPS and which types of TLS backend(s) supported by 4101 * this build. 4102 * The result is placed in @a v_tls_backends member. 4103 */ 4104 MHD_LIB_INFO_FIXED_TLS_BACKENDS = 100 4105 , 4106 /** 4107 * Get whether password encrypted private key for HTTPS daemon is 4108 * supported by TLS backends. 4109 * If supported then option #MHD_D_OPTION_TLS_KEY_CERT can be used with 4110 * non-NULL @a mem_pass. 4111 * The result is placed in @a v_tls_key_password_backends member. 4112 */ 4113 MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS = 102 4114 , 4115 4116 /* * Sentinel * */ 4117 /** 4118 * The sentinel value. 4119 * This value enforces specific underlying integer type for the enum. 4120 * Do not use. 4121 */ 4122 MHD_LIB_INFO_FIXED_SENTINEL = 65535 4123 }; 4124 4125 /** 4126 * The type of the data for digest algorithm implementations. 4127 */ 4128 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedDigestAlgoType 4129 { 4130 /** 4131 * The algorithm is not implemented or disabled at the build time. 4132 */ 4133 MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE = 0 4134 , 4135 /** 4136 * The algorithm is implemented by MHD internal code. 4137 * MHD implementation of hashing can never fail. 4138 */ 4139 MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN = 1 4140 , 4141 /** 4142 * The algorithm is implemented by external code that never fails. 4143 */ 4144 MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL = 2 4145 , 4146 /** 4147 * The algorithm is implemented by external code that may hypothetically fail. 4148 */ 4149 MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL = 3 4150 }; 4151 4152 /** 4153 * The types of the sockets polling functions/techniques supported 4154 */ 4155 struct MHD_LibInfoFixedPollingFunc 4156 { 4157 /** 4158 * select() function for sockets polling 4159 */ 4160 enum MHD_Bool func_select; 4161 /** 4162 * poll() function for sockets polling 4163 */ 4164 enum MHD_Bool func_poll; 4165 /** 4166 * epoll technique for sockets polling 4167 */ 4168 enum MHD_Bool tech_epoll; 4169 }; 4170 4171 /** 4172 * The types of IPv6 supported 4173 */ 4174 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedIPv6Type 4175 { 4176 /** 4177 * IPv6 is not supported by this MHD build 4178 */ 4179 MHD_LIB_INFO_FIXED_IPV6_TYPE_NONE = 0 4180 , 4181 /** 4182 * IPv6 is supported only as "dual stack". 4183 * IPv4 connections can be received by IPv6 listen socket. 4184 */ 4185 MHD_LIB_INFO_FIXED_IPV6_TYPE_DUAL_ONLY = 1 4186 , 4187 /** 4188 * IPv6 can be used as IPv6-only (without getting IPv4 incoming connections). 4189 * The platform may support "dual stack" too. 4190 */ 4191 MHD_LIB_INFO_FIXED_IPV6_TYPE_IPV6_PURE = 2 4192 }; 4193 4194 /** 4195 * The types of inter-thread communication 4196 * @note the enum can be extended in future versions with new values 4197 */ 4198 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedITCType 4199 { 4200 /** 4201 * No ITC used. 4202 * This value is returned if MHD is built without threads support 4203 */ 4204 MHD_LIB_INFO_FIXED_ITC_TYPE_NONE = 0 4205 , 4206 /** 4207 * The pair of sockets are used as inter-thread communication. 4208 * The is the least efficient method of communication. 4209 */ 4210 MHD_LIB_INFO_FIXED_ITC_TYPE_SOCKETPAIR = 1 4211 , 4212 /** 4213 * The pipe is used as inter-thread communication. 4214 */ 4215 MHD_LIB_INFO_FIXED_ITC_TYPE_PIPE = 2 4216 , 4217 /** 4218 * The EventFD is used as inter-thread communication. 4219 * This is the most efficient method of communication. 4220 */ 4221 MHD_LIB_INFO_FIXED_ITC_TYPE_EVENTFD = 3 4222 }; 4223 4224 4225 /** 4226 * The types of the TLS (or TLS feature) backend supported/available/enabled 4227 * @note the enum can be extended in future versions with new members 4228 */ 4229 struct MHD_LibInfoTLSType 4230 { 4231 /** 4232 * The TLS (or TLS feature) is supported/enabled. 4233 * Set to #MHD_YES if any other member is #MHD_YES. 4234 */ 4235 enum MHD_Bool tls_supported; 4236 /** 4237 * The GnuTLS backend is supported/available/enabled. 4238 */ 4239 enum MHD_Bool backend_gnutls; 4240 /** 4241 * The OpenSSL backend is supported/available/enabled. 4242 */ 4243 enum MHD_Bool backend_openssl; 4244 /** 4245 * The MbedTLS backend is supported/available/enabled. 4246 */ 4247 enum MHD_Bool backend_mbedtls; 4248 }; 4249 4250 /** 4251 * The data provided by #MHD_lib_get_info_fixed_sz() 4252 */ 4253 union MHD_LibInfoFixedData 4254 { 4255 /** 4256 * The data for the #MHD_LIB_INFO_FIXED_VERSION_NUM query 4257 */ 4258 uint_fast32_t v_version_num_uint32; 4259 /** 4260 * The data for the #MHD_LIB_INFO_FIXED_VERSION_STR query 4261 */ 4262 struct MHD_String v_version_string; 4263 /** 4264 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES query 4265 */ 4266 enum MHD_Bool v_support_log_messages_bool; 4267 /** 4268 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES query 4269 */ 4270 enum MHD_Bool v_support_auto_replies_bodies_bool; 4271 /** 4272 * The data for the #MHD_LIB_INFO_FIXED_IS_NON_DEBUG query 4273 */ 4274 enum MHD_Bool v_is_non_debug_bool; 4275 /** 4276 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_THREADS query 4277 */ 4278 enum MHD_Bool v_support_threads_bool; 4279 /** 4280 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER query 4281 */ 4282 enum MHD_Bool v_support_cookie_parser_bool; 4283 /** 4284 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER query 4285 */ 4286 enum MHD_Bool v_support_post_parser_bool; 4287 /** 4288 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE query 4289 */ 4290 enum MHD_Bool v_support_upgrade_bool; 4291 /** 4292 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC query 4293 */ 4294 enum MHD_Bool v_support_auth_basic_bool; 4295 /** 4296 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST query 4297 */ 4298 enum MHD_Bool v_support_auth_digest_bool; 4299 /** 4300 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069 query 4301 */ 4302 enum MHD_Bool v_support_digest_auth_rfc2069_bool; 4303 /** 4304 * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 query 4305 */ 4306 enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_md5_algo_type; 4307 /** 4308 * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 query 4309 */ 4310 enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha256_algo_type; 4311 /** 4312 * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 query 4313 */ 4314 enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha512_256_algo_type; 4315 /** 4316 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT query 4317 */ 4318 enum MHD_Bool v_support_digest_auth_auth_int_bool; 4319 /** 4320 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION query 4321 */ 4322 enum MHD_Bool v_support_digest_auth_algo_session_bool; 4323 /** 4324 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH query 4325 */ 4326 enum MHD_Bool v_support_digest_auth_userhash_bool; 4327 /** 4328 * The data for the #MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING query 4329 */ 4330 struct MHD_LibInfoFixedPollingFunc v_types_sockets_polling; 4331 /** 4332 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD query 4333 */ 4334 enum MHD_Bool v_support_aggregate_fd_bool; 4335 /** 4336 * The data for the #MHD_LIB_INFO_FIXED_TYPE_IPV6 query 4337 */ 4338 enum MHD_LibInfoFixedIPv6Type v_ipv6; 4339 /** 4340 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN query 4341 */ 4342 enum MHD_Bool v_support_tcp_fastopen_bool; 4343 /** 4344 * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT query 4345 */ 4346 enum MHD_Bool v_has_autodetect_bind_port_bool; 4347 /** 4348 * The data for the #MHD_LIB_INFO_FIXED_HAS_SENDFILE query 4349 */ 4350 enum MHD_Bool v_has_sendfile_bool; 4351 /** 4352 * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT query 4353 */ 4354 enum MHD_Bool v_has_autosuppress_sigpipe_int_bool; 4355 /** 4356 * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT query 4357 */ 4358 enum MHD_Bool v_has_autosuppress_sigpipe_ext_bool; 4359 /** 4360 * The data for the #MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES query 4361 */ 4362 enum MHD_Bool v_has_thread_names_bool; 4363 /** 4364 * The data for the #MHD_LIB_INFO_FIXED_TYPE_ITC query 4365 */ 4366 enum MHD_LibInfoFixedITCType v_type_itc; 4367 /** 4368 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE query 4369 */ 4370 enum MHD_Bool v_support_large_file_bool; 4371 /** 4372 * The data for the #MHD_LIB_INFO_FIXED_TLS_BACKENDS query 4373 */ 4374 struct MHD_LibInfoTLSType v_tls_backends; 4375 /** 4376 * The data for the #MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS query 4377 */ 4378 struct MHD_LibInfoTLSType v_tls_key_password_backends; 4379 }; 4380 4381 /** 4382 * Get fixed information about MHD that is not changed at run-time. 4383 * The returned information can be cached by application as it will be not 4384 * changed at run-time. 4385 * 4386 * For any valid @a info_type the only possible returned error value is 4387 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL. If the buffer is large enough and 4388 * the requested type of information is valid, the function always succeeds 4389 * and returns #MHD_SC_OK. 4390 * 4391 * The wrapper macro #MHD_lib_get_info_fixed() may be more convenient. 4392 * 4393 * @param info_type the type of requested information 4394 * @param[out] output_buf the pointer to union to be set to the requested 4395 * information 4396 * @param output_buf_size the size of the memory area pointed by @a output_buf 4397 * (provided by the caller for storing the requested 4398 * information), in bytes 4399 * @return #MHD_SC_OK if succeed, 4400 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4401 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small 4402 * @ingroup specialized 4403 */ 4404 MHD_EXTERN_ enum MHD_StatusCode 4405 MHD_lib_get_info_fixed_sz (enum MHD_LibInfoFixed info_type, 4406 union MHD_LibInfoFixedData *MHD_RESTRICT output_buf, 4407 size_t output_buf_size) 4408 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2); 4409 4410 /** 4411 * Get fixed information about MHD that is not changed at run-time. 4412 * The returned information can be cached by application as it will be not 4413 * changed at run-time. 4414 * 4415 * @param info the type of requested information 4416 * @param[out] output_buf the pointer to union to be set to the requested 4417 * information 4418 * @return #MHD_SC_OK if succeed, 4419 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4420 * or other error code 4421 * @ingroup specialized 4422 */ 4423 #define MHD_lib_get_info_fixed(info,output_buf) \ 4424 MHD_lib_get_info_fixed_sz ((info),(output_buf),sizeof(*(output_buf))) 4425 4426 /* Application may define MHD_NO_STATIC_INLINE macro before including 4427 libmicrohttpd headers to disable static inline functions in the headers. */ 4428 #ifndef MHD_NO_STATIC_INLINE 4429 4430 /* 4431 * A helper below can be used in a simple check preventing use of downgraded 4432 * library version. 4433 * As new library version may introduce new functionality, and the application 4434 * may detect some functionality available at application build-time, use of 4435 * previous versions may lead to run-time failures. 4436 * To prevent run-time failures, application may use a check like: 4437 4438 if (MHD_lib_get_info_ver_num() < ((uint_fast32_t) MHD_VERSION)) 4439 handle_init_failure(); 4440 4441 */ 4442 /** 4443 * Get the library version number. 4444 * @return the library version number. 4445 */ 4446 MHD_STATIC_INLINE_ MHD_FN_PURE_ uint_fast32_t 4447 MHD_lib_get_info_ver_num (void) 4448 { 4449 union MHD_LibInfoFixedData data; 4450 data.v_version_num_uint32 = 0; /* Not really necessary */ 4451 (void) MHD_lib_get_info_fixed (MHD_LIB_INFO_FIXED_VERSION_NUM, \ 4452 &data); /* Never fail */ 4453 return data.v_version_num_uint32; 4454 } 4455 4456 4457 MHD_STATIC_INLINE_END_ 4458 4459 #endif /* ! MHD_NO_STATIC_INLINE */ 4460 4461 /** 4462 * Types of information about MHD, used by #MHD_lib_get_info_dynamic_sz(). 4463 * This information may vary over time. 4464 */ 4465 enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoDynamic 4466 { 4467 /* * Basic MHD information * */ 4468 4469 /** 4470 * Get whether MHD has been successfully fully initialised. 4471 * MHD uses lazy initialisation: a minimal initialisation is performed at 4472 * startup, complete initialisation is performed when any daemon is created 4473 * (or when called some function which requires full initialisation). 4474 * The result is #MHD_NO when the library has been not yet initialised 4475 * completely since startup. 4476 * The result is placed in @a v_inited_fully_once_bool member. 4477 */ 4478 MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE = 0 4479 , 4480 /** 4481 * Get whether MHD is fully initialised. 4482 * MHD uses lazy initialisation: a minimal initialisation is performed at 4483 * startup, complete initialisation is perfromed when any daemon is created 4484 * (or when called some function which requires full initialisation). 4485 * The result is #MHD_YES if library is initialised state now (meaning 4486 * that at least one daemon is created and not destroyed or some function 4487 * required full initialisation is running). 4488 * The result is placed in @a v_inited_fully_now_bool member. 4489 */ 4490 MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW = 1 4491 , 4492 4493 /** 4494 * Get whether HTTPS and which types of TLS backend(s) currently available. 4495 * If any MHD daemons active (created and not destroyed, not necessary 4496 * running) the result reflects the current backends availability. 4497 * If no MHD daemon is active, then this function would try to temporarily 4498 * enable backends to check for their availability. 4499 * If global library initialisation failed, the function returns 4500 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE error code. 4501 * The result is placed in @a v_tls_backends member. 4502 */ 4503 MHD_LIB_INFO_DYNAMIC_TYPE_TLS = 100 4504 , 4505 4506 /* * Sentinel * */ 4507 /** 4508 * The sentinel value. 4509 * This value enforces specific underlying integer type for the enum. 4510 * Do not use. 4511 */ 4512 MHD_LIB_INFO_DYNAMIC_SENTINEL = 65535 4513 }; 4514 4515 4516 /** 4517 * The data provided by #MHD_lib_get_info_dynamic_sz(). 4518 * The resulting value may vary over time. 4519 */ 4520 union MHD_LibInfoDynamicData 4521 { 4522 /** 4523 * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE query 4524 */ 4525 enum MHD_Bool v_inited_fully_once_bool; 4526 4527 /** 4528 * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW query 4529 */ 4530 enum MHD_Bool v_inited_fully_now_bool; 4531 4532 /** 4533 * The data for the #MHD_LIB_INFO_DYNAMIC_TYPE_TLS query 4534 */ 4535 struct MHD_LibInfoTLSType v_tls_backends; 4536 4537 /** 4538 * Unused member. 4539 * Help enforcing future-proof alignment of the union. 4540 * Do not use. 4541 */ 4542 void *reserved; 4543 }; 4544 4545 /** 4546 * Get dynamic information about MHD that may be changed at run-time. 4547 * The wrapper macro #MHD_lib_get_info_dynamic() could be more convenient. 4548 * 4549 * @param info_type the type of requested information 4550 * @param[out] output_buf the pointer to union to be set to the requested 4551 * information 4552 * @param output_buf_size the size of the memory area pointed by @a output_buf 4553 * (provided by the caller for storing the requested 4554 * information), in bytes 4555 * @return #MHD_SC_OK if succeed, 4556 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4557 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 4558 * or other error code 4559 * @ingroup specialized 4560 */ 4561 MHD_EXTERN_ enum MHD_StatusCode 4562 MHD_lib_get_info_dynamic_sz ( 4563 enum MHD_LibInfoDynamic info_type, 4564 union MHD_LibInfoDynamicData *MHD_RESTRICT output_buf, 4565 size_t output_buf_size) 4566 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2); 4567 4568 /** 4569 * Get dynamic information about MHD that may be changed at run-time. 4570 * 4571 * @param info the type of requested information 4572 * @param[out] output_buf the pointer to union to be set to the requested 4573 * information 4574 * @return #MHD_SC_OK if succeed, 4575 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4576 * or other error code 4577 * @ingroup specialized 4578 */ 4579 #define MHD_lib_get_info_dynamic(info,output_buf) \ 4580 MHD_lib_get_info_dynamic_sz ((info),(output_buf),sizeof(*(output_buf))) 4581 4582 4583 /** 4584 * Values of this enum are used to specify what information about a daemon is 4585 * requested. 4586 * These types of information do not change after the start of the daemon 4587 * until the daemon is destroyed. 4588 */ 4589 enum MHD_DaemonInfoFixedType 4590 { 4591 4592 /** 4593 * Get the type of system call used for sockets polling. 4594 * The value #MHD_SPS_AUTO is never set in the returned data. 4595 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4596 * does not use internal sockets polling. 4597 * The result is placed in @a v_poll_syscall member. 4598 */ 4599 MHD_DAEMON_INFO_FIXED_POLL_SYSCALL = 41 4600 , 4601 /** 4602 * Get the file descriptor for the single FD that triggered when 4603 * any MHD event happens. 4604 * This FD can be watched as aggregate indicator for all MHD events. 4605 * The provided socket must be used as 'read-only': only select() or similar 4606 * functions should be used. Any modifications (changing socket attributes, 4607 * calling accept(), closing it etc.) will lead to undefined behaviour. 4608 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library 4609 * does not support mode with agregate FD. 4610 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4611 * is not configured to use this mode. 4612 * The result is placed in @a v_aggreagate_fd member. 4613 */ 4614 MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 46 4615 , 4616 /** 4617 * Get the number of worker threads when used in MHD_WM_WORKER_THREADS mode. 4618 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4619 * does not use worker threads mode. 4620 * The result is placed in @a v_num_work_threads_uint member. 4621 */ 4622 MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS = 47 4623 , 4624 /** 4625 * Get the port number of daemon's listen socket. 4626 * Note: if port '0' (auto port) was specified for #MHD_D_OPTION_BIND_PORT(), 4627 * returned value will be the real port number. 4628 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4629 * does not have listening socket or if listening socket is non-IP. 4630 * The function returns #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the port number 4631 * detection failed or not supported by the platform. 4632 * If the function succeed, the returned port number is never zero. 4633 * The result is placed in @a v_bind_port_uint16 member. 4634 */ 4635 MHD_DAEMON_INFO_FIXED_BIND_PORT = 80 4636 , 4637 /** 4638 * Get the file descriptor for the listening socket. 4639 * The provided socket must be used as 'read-only': only select() or similar 4640 * functions should be used. Any modifications (changing socket attributes, 4641 * calling accept(), closing it etc.) will lead to undefined behaviour. 4642 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4643 * does not have listening socket. 4644 * The result is placed in @a v_listen_socket member. 4645 */ 4646 MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 82 4647 , 4648 /** 4649 * Get the TLS backend used by the daemon. 4650 * The value #MHD_TLS_BACKEND_ANY is never set in the returned data. 4651 * The value #MHD_TLS_BACKEND_NONE is set if the daemon does not use TLS. 4652 * If MHD built without TLS support then #MHD_TLS_BACKEND_NONE is always set. 4653 * The result is placed in @a v_tls_backend member. 4654 */ 4655 MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 120 4656 , 4657 /** 4658 * Get the default inactivity timeout for connections. 4659 * The result is placed in @a v_default_timeout_uint member. 4660 */ 4661 MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT = 160 4662 , 4663 /** 4664 * Get the limit of number of simutaneous network connections served by 4665 * the daemon. 4666 * The result is placed in @a v_global_connection_limit_uint member. 4667 */ 4668 MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT = 161 4669 , 4670 /** 4671 * Get the limit of number of simutaneous network connections served by 4672 * the daemon for any single IP address. 4673 * The result is placed in @a v_per_ip_limit_uint member. 4674 */ 4675 MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT = 162 4676 , 4677 /** 4678 * Get the setting for suppression of the 'Date:' header in replies. 4679 * The result is placed in @a v_suppress_date_header_bool member. 4680 */ 4681 MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER = 240 4682 , 4683 /** 4684 * Get the size of buffer unsed per connection. 4685 * The result is placed in @a v_conn_memory_limit_sizet member. 4686 */ 4687 MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT = 280 4688 , 4689 /** 4690 * Get the limit of maximum FD value for the daemon. 4691 * The daemon rejects (closes) any sockets with FD equal or higher 4692 * the resulting number. 4693 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4694 * is built for W32. 4695 * The result is placed in @a v_fd_number_limit_uint member. 4696 */ 4697 MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT = 283 4698 , 4699 4700 /* * Sentinel * */ 4701 /** 4702 * The sentinel value. 4703 * This value enforces specific underlying integer type for the enum. 4704 * Do not use. 4705 */ 4706 MHD_DAEMON_INFO_FIXED_SENTINEL = 65535 4707 4708 }; 4709 4710 4711 /** 4712 * Information about an MHD daemon. 4713 */ 4714 union MHD_DaemonInfoFixedData 4715 { 4716 /** 4717 * The data for the #MHD_DAEMON_INFO_FIXED_POLL_SYSCALL query 4718 */ 4719 enum MHD_SockPollSyscall v_poll_syscall; 4720 4721 /** 4722 * The data for the #MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS query 4723 */ 4724 unsigned int v_num_work_threads_uint; 4725 4726 /** 4727 * The data for the #MHD_DAEMON_INFO_FIXED_BIND_PORT query 4728 */ 4729 uint_least16_t v_bind_port_uint16; 4730 4731 /** 4732 * The data for the #MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET query 4733 */ 4734 MHD_Socket v_listen_socket; 4735 4736 /** 4737 * The data for the #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD query 4738 */ 4739 int v_aggreagate_fd; 4740 4741 /** 4742 * The data for the #MHD_DAEMON_INFO_FIXED_TLS_BACKEND query 4743 */ 4744 enum MHD_TlsBackend v_tls_backend; 4745 4746 /** 4747 * The data for the #MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT query 4748 */ 4749 unsigned int v_default_timeout_uint; 4750 4751 /** 4752 * The data for the #MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT query 4753 */ 4754 unsigned int v_global_connection_limit_uint; 4755 4756 /** 4757 * The data for the #MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT query 4758 */ 4759 unsigned int v_per_ip_limit_uint; 4760 4761 /** 4762 * The data for the #MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER query 4763 */ 4764 enum MHD_Bool v_suppress_date_header_bool; 4765 4766 /** 4767 * The data for the #MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT query 4768 */ 4769 size_t v_conn_memory_limit_sizet; 4770 4771 /** 4772 * The data for the #MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT query 4773 */ 4774 MHD_Socket v_fd_number_limit_socket; 4775 4776 /** 4777 * Unused member. 4778 * Help enforcing future-proof alignment of the union. 4779 * Do not use. 4780 */ 4781 void *reserved; 4782 }; 4783 4784 4785 /** 4786 * Obtain fixed information about the given daemon. 4787 * This information is not changed at after start of the daemon until 4788 * the daemon is destroyed. 4789 * The wrapper macro #MHD_daemon_get_info_fixed() may be more convenient. 4790 * 4791 * @param daemon the daemon to get information about 4792 * @param info_type the type of information requested 4793 * @param[out] output_buf pointer to union where requested information will 4794 * be stored 4795 * @param output_buf_size the size of the memory area pointed by @a output_buf 4796 * (provided by the caller for storing the requested 4797 * information), in bytes 4798 * @return #MHD_SC_OK if succeed, 4799 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4800 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4801 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4802 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4803 * is not available for this 4804 * daemon due to the daemon 4805 * configuration/mode, 4806 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4807 * should be available for 4808 * the daemon, but cannot be provided 4809 * due to some error or other 4810 * reasons, 4811 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 4812 * other error codes in case of other errors 4813 * @ingroup specialized 4814 */ 4815 MHD_EXTERN_ enum MHD_StatusCode 4816 MHD_daemon_get_info_fixed_sz ( 4817 struct MHD_Daemon *MHD_RESTRICT daemon, 4818 enum MHD_DaemonInfoFixedType info_type, 4819 union MHD_DaemonInfoFixedData *MHD_RESTRICT output_buf, 4820 size_t output_buf_size) 4821 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 4822 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 4823 4824 /** 4825 * Obtain fixed information about the given daemon. 4826 * This types of information are not changed at after start of the daemon until 4827 * the daemon is destroyed. 4828 * 4829 * @param daemon the daemon to get information about 4830 * @param info_type the type of information requested 4831 * @param[out] output_buf pointer to union where requested information will 4832 * be stored 4833 * @return #MHD_SC_OK if succeed, 4834 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4835 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4836 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4837 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4838 * is not available for this 4839 * daemon due to the daemon 4840 * configuration/mode, 4841 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4842 * should be available for 4843 * the daemon, but cannot be provided 4844 * due to some error or other 4845 * reasons, 4846 * other error codes in case of other errors 4847 * @ingroup specialized 4848 */ 4849 #define MHD_daemon_get_info_fixed(daemon,info_type,output_buf) \ 4850 MHD_daemon_get_info_fixed_sz ((daemon), (info_type), (output_buf), \ 4851 sizeof(*(output_buf))) 4852 4853 4854 /** 4855 * Values of this enum are used to specify what 4856 * information about a daemon is desired. 4857 * This types of information may be changed after the start of the daemon. 4858 */ 4859 enum MHD_DaemonInfoDynamicType 4860 { 4861 /** 4862 * The the maximum number of millisecond from the current moment until 4863 * the mandatory call of the daemon data processing function (like 4864 * #MHD_daemon_process_reg_events(), #MHD_daemon_process_blocking()). 4865 * If resulting value is zero then daemon data processing function should be 4866 * called as soon as possible as some data processing is already pending. 4867 * The data processing function can also be called earlier as well. 4868 * Available only for daemons stated in #MHD_WM_EXTERNAL_PERIODIC, 4869 * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL, #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE 4870 * or #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes. 4871 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon has 4872 * internal handling of events (internal threads). 4873 * The result is placed in @a v_max_time_to_wait_uint64 member. 4874 */ 4875 MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT = 1 4876 , 4877 /** 4878 * Check whether the daemon has any connected network clients. 4879 * The result is placed in @a v_has_connections_bool member. 4880 */ 4881 MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS = 20 4882 , 4883 /* * Sentinel * */ 4884 /** 4885 * The sentinel value. 4886 * This value enforces specific underlying integer type for the enum. 4887 * Do not use. 4888 */ 4889 MHD_DAEMON_INFO_DYNAMIC_SENTINEL = 65535 4890 }; 4891 4892 4893 /** 4894 * Information about an MHD daemon. 4895 */ 4896 union MHD_DaemonInfoDynamicData 4897 { 4898 /** 4899 * The data for the #MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT query 4900 */ 4901 uint_fast64_t v_max_time_to_wait_uint64; 4902 4903 /** 4904 * The data for the #MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS query 4905 */ 4906 enum MHD_Bool v_has_connections_bool; 4907 4908 /** 4909 * Unused member. 4910 * Help enforcing future-proof alignment of the union. 4911 * Do not use. 4912 */ 4913 void *reserved; 4914 }; 4915 4916 4917 /** 4918 * Obtain dynamic information about the given daemon. 4919 * This information may be changed after the start of the daemon. 4920 * The wrapper macro #MHD_daemon_get_info_dynamic() could be more convenient. 4921 * 4922 * @param daemon the daemon to get information about 4923 * @param info_type the type of information requested 4924 * @param[out] output_buf the pointer to union to be set to the requested 4925 * information 4926 * @param output_buf_size the size of the memory area pointed by @a output_buf 4927 * (provided by the caller for storing the requested 4928 * information), in bytes 4929 * @return #MHD_SC_OK if succeed, 4930 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4931 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4932 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4933 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4934 * is not available for this 4935 * daemon due to the daemon 4936 * configuration/mode, 4937 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4938 * should be available for 4939 * the daemon, but cannot be provided 4940 * due to some error or other 4941 * reasons, 4942 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 4943 * other error codes in case of other errors 4944 * @ingroup specialized 4945 */ 4946 MHD_EXTERN_ enum MHD_StatusCode 4947 MHD_daemon_get_info_dynamic_sz ( 4948 struct MHD_Daemon *MHD_RESTRICT daemon, 4949 enum MHD_DaemonInfoDynamicType info_type, 4950 union MHD_DaemonInfoDynamicData *MHD_RESTRICT output_buf, 4951 size_t output_buf_size) 4952 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 4953 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 4954 4955 /** 4956 * Obtain dynamic information about the given daemon. 4957 * This types of information may be changed after the start of the daemon. 4958 * 4959 * @param daemon the daemon to get information about 4960 * @param info_type the type of information requested 4961 * @param[out] output_buf the pointer to union to be set to the requested 4962 * information 4963 * @return #MHD_SC_OK if succeed, 4964 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4965 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4966 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4967 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4968 * is not available for this 4969 * daemon due to the daemon 4970 * configuration/mode, 4971 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4972 * should be available for 4973 * the daemon, but cannot be provided 4974 * due to some error or other 4975 * reasons, 4976 * other error codes in case of other errors 4977 * @ingroup specialized 4978 */ 4979 #define MHD_daemon_get_info_dynamic(daemon,info_type,output_buf) \ 4980 MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (output_buf), \ 4981 sizeof(*(output_buf))) 4982 4983 4984 /** 4985 * Select which fixed information about connection is desired. 4986 * This information is not changed during the lifetime of the connection. 4987 */ 4988 enum MHD_ConnectionInfoFixedType 4989 { 4990 /** 4991 * Get the network address of the client. 4992 * If the connection does not have known remote address (was not provided 4993 * by the system or by the application in case of externally added 4994 * connection) then error code #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is 4995 * returned if connection is IP type or unknown type or error code 4996 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if connection type is non-IP. 4997 * The @a sa pointer is never NULL if the function succeed (#MHD_SC_OK 4998 * returned). 4999 * The result is placed in @a v_client_address_sa_info member. 5000 * @ingroup request 5001 */ 5002 MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS = 1 5003 , 5004 /** 5005 * Get the file descriptor for the connection socket. 5006 * The provided socket must be used as 'read-only': only select() or similar 5007 * functions should be used. Any modifications (changing socket attributes, 5008 * calling send() or recv(), closing it etc.) will lead to undefined 5009 * behaviour. 5010 * The result is placed in @a v_connection_socket member. 5011 * @ingroup request 5012 */ 5013 MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET = 2 5014 , 5015 /** 5016 * Get the `struct MHD_Daemon *` responsible for managing this connection. 5017 * The result is placed in @a v_daemon member. 5018 * @ingroup request 5019 */ 5020 MHD_CONNECTION_INFO_FIXED_DAEMON = 20 5021 , 5022 /** 5023 * Returns the pointer to a variable pointing to connection-specific 5024 * application context data that was (possibly) set during 5025 * a #MHD_NotifyConnectionCallback or provided via @a connection_cntx 5026 * parameter of #MHD_daemon_add_connection(). 5027 * By using provided pointer application may get or set the pointer to 5028 * any data specific for the particular connection. 5029 * Note: resulting data is NOT the context pointer itself. 5030 * The result is placed in @a v_app_context_ppvoid member. 5031 * @ingroup request 5032 */ 5033 MHD_CONNECTION_INFO_FIXED_APP_CONTEXT = 30 5034 , 5035 5036 /* * Sentinel * */ 5037 /** 5038 * The sentinel value. 5039 * This value enforces specific underlying integer type for the enum. 5040 * Do not use. 5041 */ 5042 MHD_CONNECTION_INFO_FIXED_SENTINEL = 65535 5043 }; 5044 5045 /** 5046 * Socket address information data 5047 */ 5048 struct MHD_ConnInfoFixedSockAddr 5049 { 5050 /** 5051 * The size of the @a sa 5052 */ 5053 size_t sa_size; 5054 5055 /** 5056 * Socket Address type 5057 */ 5058 const struct sockaddr *sa; 5059 }; 5060 5061 /** 5062 * Information about a connection. 5063 */ 5064 union MHD_ConnectionInfoFixedData 5065 { 5066 5067 /** 5068 * The data for the #MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS query 5069 */ 5070 struct MHD_ConnInfoFixedSockAddr v_client_address_sa_info; 5071 5072 /** 5073 * The data for the #MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET query 5074 */ 5075 MHD_Socket v_connection_socket; 5076 5077 /** 5078 * The data for the #MHD_CONNECTION_INFO_FIXED_DAEMON query 5079 */ 5080 struct MHD_Daemon *v_daemon; 5081 5082 /** 5083 * The data for the #MHD_CONNECTION_INFO_FIXED_APP_CONTEXT query 5084 */ 5085 void **v_app_context_ppvoid; 5086 }; 5087 5088 5089 /** 5090 * Obtain fixed information about the given connection. 5091 * This information is not changed for the lifetime of the connection. 5092 * The wrapper macro #MHD_connection_get_info_fixed() may be more convenient. 5093 * 5094 * @param connection the connection to get information about 5095 * @param info_type the type of information requested 5096 * @param[out] output_buf the pointer to union to be set to the requested 5097 * information 5098 * @param output_buf_size the size of the memory area pointed by @a output_buf 5099 * (provided by the caller for storing the requested 5100 * information), in bytes 5101 * @return #MHD_SC_OK if succeed, 5102 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5103 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5104 * is not available for this 5105 * connection due to the connection 5106 * configuration/mode, 5107 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5108 * should be available for 5109 * the connection, but cannot be 5110 * provided due to some error or 5111 * other reasons, 5112 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5113 * other error codes in case of other errors 5114 * @ingroup specialized 5115 */ 5116 MHD_EXTERN_ enum MHD_StatusCode 5117 MHD_connection_get_info_fixed_sz ( 5118 struct MHD_Connection *MHD_RESTRICT connection, 5119 enum MHD_ConnectionInfoFixedType info_type, 5120 union MHD_ConnectionInfoFixedData *MHD_RESTRICT output_buf, 5121 size_t output_buf_size) 5122 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5123 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5124 5125 5126 /** 5127 * Obtain fixed information about the given connection. 5128 * This information is not changed for the lifetime of the connection. 5129 * 5130 * @param connection the connection to get information about 5131 * @param info_type the type of information requested 5132 * @param[out] output_buf the pointer to union to be set to the requested 5133 * information 5134 * @return #MHD_SC_OK if succeed, 5135 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5136 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5137 * is not available for this 5138 * connection due to the connection 5139 * configuration/mode, 5140 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5141 * should be available for 5142 * the connection, but cannot be 5143 * provided due to some error or 5144 * other reasons, 5145 * other error codes in case of other errors 5146 * @ingroup specialized 5147 */ 5148 #define MHD_connection_get_info_fixed(connection,info_type,output_buf) \ 5149 MHD_connection_get_info_fixed_sz ((connection),(info_type), \ 5150 (output_buf), sizeof(*(output_buf))) 5151 5152 5153 /** 5154 * Select which dynamic information about connection is desired. 5155 * This information may be changed during the lifetime of the connection. 5156 */ 5157 enum MHD_ConnectionInfoDynamicType 5158 { 5159 /** 5160 * Get current version of HTTP protocol used for connection. 5161 * If connection is handling HTTP/1.x requests the function may return 5162 * error code #MHD_SC_TOO_EARLY if the full request line has not been received 5163 * yet for the current request. 5164 * The result is placed in @a v_http_ver member. 5165 * @ingroup request 5166 */ 5167 MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER = 1 5168 , 5169 /** 5170 * Get connection timeout value. 5171 * This is the total number of seconds after which the idle connection is 5172 * automatically disconnected. 5173 * Note: the value set is NOT the number of seconds left before automatic 5174 * disconnection. 5175 * The result is placed in @a v_connection_timeout_uint member. 5176 * @ingroup request 5177 */ 5178 MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT = 10 5179 , 5180 /** 5181 * Check whether the connection is suspended. 5182 * The result is placed in @a v_connection_suspended_bool member. 5183 * @ingroup request 5184 */ 5185 MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED = 11 5186 , 5187 /** 5188 * Get current version of TLS transport protocol used for connection 5189 * If plain TCP connection is used then #MHD_TLS_VERSION_NO_TLS set in 5190 * the data. 5191 * It TLS handshake is not yet finished then error code #MHD_SC_TOO_EARLY is 5192 * returned. If TLS has failed or being closed then #MHD_SC_TOO_LATE error 5193 * code is returned. 5194 * If TLS version cannot be detected for any reason then error code 5195 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is returned. 5196 * The result is placed in @a v_tls_ver member. 5197 * @ingroup request 5198 */ 5199 MHD_CONNECTION_INFO_DYNAMIC_TLS_VER = 105 5200 , 5201 /** 5202 * Get the TLS backend session handle. 5203 * If plain TCP connection is used then the function returns error code 5204 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE. 5205 * The resulting union has only one valid member. 5206 * The result is placed in @a v_tls_session member. 5207 * @ingroup request 5208 */ 5209 MHD_CONNECTION_INFO_DYNAMIC_TLS_SESSION = 140 5210 , 5211 5212 /* * Sentinel * */ 5213 /** 5214 * The sentinel value. 5215 * This value enforces specific underlying integer type for the enum. 5216 * Do not use. 5217 */ 5218 MHD_CONNECTION_INFO_DYNAMIC_SENTINEL = 65535 5219 }; 5220 5221 5222 /** 5223 * The versions of TLS protocol 5224 */ 5225 enum MHD_FIXED_ENUM_MHD_SET_ MHD_TlsVersion 5226 { 5227 5228 /** 5229 * No TLS / plain socket connection 5230 */ 5231 MHD_TLS_VERSION_NO_TLS = 0 5232 , 5233 /** 5234 * Not supported/failed to negotiate/failed to handshake TLS 5235 */ 5236 MHD_TLS_VERSION_BROKEN = 1 5237 , 5238 /** 5239 * TLS version 1.0 5240 */ 5241 MHD_TLS_VERSION_1_0 = 2 5242 , 5243 /** 5244 * TLS version 1.1 5245 */ 5246 MHD_TLS_VERSION_1_1 = 3 5247 , 5248 /** 5249 * TLS version 1.2 5250 */ 5251 MHD_TLS_VERSION_1_2 = 4 5252 , 5253 /** 5254 * TLS version 1.3 5255 */ 5256 MHD_TLS_VERSION_1_3 = 5 5257 , 5258 /** 5259 * Some unknown TLS version. 5260 * The TLS version is supported by TLS backend, but unknown to MHD. 5261 */ 5262 MHD_TLS_VERSION_UNKNOWN = 1999 5263 }; 5264 5265 /** 5266 * Connection TLS session information. 5267 * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out 5268 * which member should be used. 5269 */ 5270 union MHD_ConnInfoDynamicTlsSess 5271 { 5272 /* Include <gnutls/gnutls.h> before this header to get a better type safety */ 5273 /** 5274 * GnuTLS session handle, of type "gnutls_session_t". 5275 */ 5276 #if defined(GNUTLS_VERSION_MAJOR) && GNUTLS_VERSION_MAJOR >= 3 5277 gnutls_session_t v_gnutls_session; 5278 #else 5279 void * /* gnutls_session_t */ v_gnutls_session; 5280 #endif 5281 5282 /* Include <openssl/types.h> or <openssl/crypto.h> before this header to get 5283 a better type safety */ 5284 /** 5285 * OpenSSL session handle, of type "SSL*". 5286 */ 5287 #if defined(OPENSSL_TYPES_H) && OPENSSL_VERSION_MAJOR >= 3 5288 SSL *v_openssl_session; 5289 #else 5290 void /* SSL */ *v_openssl_session; 5291 #endif 5292 5293 /* Include <mbedtls/ssl.h> before this header to get a better type safety */ 5294 /** 5295 * MbedTLS session handle, of type "mbedtls_ssl_context*". 5296 */ 5297 #if defined(MBEDTLS_SSL_H) 5298 mbedtls_ssl_context *v_mbedtls_session; 5299 #else 5300 void /* mbedtls_ssl_context */ *v_mbedtls_session; 5301 #endif 5302 }; 5303 5304 /** 5305 * Information about a connection. 5306 */ 5307 union MHD_ConnectionInfoDynamicData 5308 { 5309 /** 5310 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER query 5311 */ 5312 enum MHD_HTTP_ProtocolVersion v_http_ver; 5313 5314 /** 5315 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT query 5316 */ 5317 unsigned int v_connection_timeout_uint; 5318 5319 /** 5320 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query 5321 */ 5322 enum MHD_Bool v_connection_suspended_bool; 5323 5324 /** 5325 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query 5326 */ 5327 enum MHD_TlsVersion v_tls_ver; 5328 5329 /** 5330 * Connection TLS session information. 5331 * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out 5332 * which member should be used. 5333 */ 5334 union MHD_ConnInfoDynamicTlsSess v_tls_session; 5335 }; 5336 5337 /** 5338 * Obtain dynamic information about the given connection. 5339 * This information may be changed during the lifetime of the connection. 5340 * 5341 * The wrapper macro #MHD_connection_get_info_dynamic() may be more convenient. 5342 * 5343 * @param connection the connection to get information about 5344 * @param info_type the type of information requested 5345 * @param[out] output_buf the pointer to union to be set to the requested 5346 * information 5347 * @param output_buf_size the size of the memory area pointed by @a output_buf 5348 * (provided by the caller for storing the requested 5349 * information), in bytes 5350 * @return #MHD_SC_OK if succeed, 5351 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5352 * #MHD_SC_TOO_EARLY if the connection has not reached yet required 5353 * state, 5354 * #MHD_SC_TOO_LATE if the connection is already in state where 5355 * the requested information is not available, 5356 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5357 * is not available for this 5358 * connection due to the connection 5359 * configuration/mode, 5360 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5361 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5362 * should be available for 5363 * the connection, but cannot be 5364 * provided due to some error or 5365 * other reasons, 5366 * other error codes in case of other errors 5367 * @ingroup specialized 5368 */ 5369 MHD_EXTERN_ enum MHD_StatusCode 5370 MHD_connection_get_info_dynamic_sz ( 5371 struct MHD_Connection *MHD_RESTRICT connection, 5372 enum MHD_ConnectionInfoDynamicType info_type, 5373 union MHD_ConnectionInfoDynamicData *MHD_RESTRICT output_buf, 5374 size_t output_buf_size) 5375 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5376 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5377 5378 5379 /** 5380 * Obtain dynamic information about the given connection. 5381 * This information may be changed during the lifetime of the connection. 5382 * 5383 * @param connection the connection to get information about 5384 * @param info_type the type of information requested 5385 * @param[out] output_buf the pointer to union to be set to the requested 5386 * information 5387 * @return #MHD_SC_OK if succeed, 5388 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5389 * #MHD_SC_TOO_EARLY if the connection has not reached yet required 5390 * state, 5391 * #MHD_SC_TOO_LATE if the connection is already in state where 5392 * the requested information is not available, 5393 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5394 * is not available for this 5395 * connection due to the connection 5396 * configuration/mode, 5397 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5398 * should be available for 5399 * the connection, but cannot be 5400 * provided due to some error or 5401 * other reasons, 5402 * other error codes in case of other errors 5403 * @ingroup specialized 5404 */ 5405 #define MHD_connection_get_info_dynamic(connection,info_type,output_buf) \ 5406 MHD_connection_get_info_dynamic_sz ((connection),(info_type), \ 5407 (output_buf),sizeof(*(output_buf))) 5408 5409 5410 /** 5411 * Select which fixed information about stream is desired. 5412 * This information is not changed during the lifetime of the connection. 5413 */ 5414 enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoFixedType 5415 { 5416 /** 5417 * Get the `struct MHD_Daemon *` responsible for managing connection which 5418 * is responsible for this stream. 5419 * The result is placed in @a v_daemon member. 5420 * @ingroup request 5421 */ 5422 MHD_STREAM_INFO_FIXED_DAEMON = 20 5423 , 5424 /** 5425 * Get the `struct MHD_Connection *` responsible for managing this stream. 5426 * The result is placed in @a v_connection member. 5427 * @ingroup request 5428 */ 5429 MHD_STREAM_INFO_FIXED_CONNECTION = 21 5430 , 5431 5432 /* * Sentinel * */ 5433 /** 5434 * The sentinel value. 5435 * This value enforces specific underlying integer type for the enum. 5436 * Do not use. 5437 */ 5438 MHD_STREAM_INFO_FIXED_SENTINEL = 65535 5439 }; 5440 5441 5442 /** 5443 * Fixed information about a stream. 5444 */ 5445 union MHD_StreamInfoFixedData 5446 { 5447 /** 5448 * The data for the #MHD_STREAM_INFO_FIXED_DAEMON query 5449 */ 5450 struct MHD_Daemon *v_daemon; 5451 /** 5452 * The data for the #MHD_STREAM_INFO_FIXED_CONNECTION query 5453 */ 5454 struct MHD_Connection *v_connection; 5455 }; 5456 5457 5458 /** 5459 * Obtain fixed information about the given stream. 5460 * This information is not changed for the lifetime of the stream. 5461 * 5462 * The wrapper macro #MHD_stream_get_info_fixed() may be more convenient. 5463 * 5464 * @param stream the stream to get information about 5465 * @param info_type the type of information requested 5466 * @param[out] output_buf the pointer to union to be set to the requested 5467 * information 5468 * @param output_buf_size the size of the memory area pointed by @a output_buf 5469 * (provided by the caller for storing the requested 5470 * information), in bytes 5471 * @return #MHD_SC_OK if succeed, 5472 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5473 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5474 * other error codes in case of other errors 5475 * @ingroup specialized 5476 */ 5477 MHD_EXTERN_ enum MHD_StatusCode 5478 MHD_stream_get_info_fixed_sz ( 5479 struct MHD_Stream *MHD_RESTRICT stream, 5480 enum MHD_StreamInfoFixedType info_type, 5481 union MHD_StreamInfoFixedData *MHD_RESTRICT output_buf, 5482 size_t output_buf_size) 5483 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5484 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5485 5486 5487 /** 5488 * Obtain fixed information about the given stream. 5489 * This information is not changed for the lifetime of the tream. 5490 * 5491 * @param stream the stream to get information about 5492 * @param info_type the type of information requested 5493 * @param[out] output_buf the pointer to union to be set to the requested 5494 * information 5495 * @return #MHD_SC_OK if succeed, 5496 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5497 * other error codes in case of other errors 5498 * @ingroup specialized 5499 */ 5500 #define MHD_stream_get_info_fixed(stream,info_type,output_buf) \ 5501 MHD_stream_get_info_fixed_sz ((stream),(info_type),(output_buf), \ 5502 sizeof(*(output_buf))) 5503 5504 5505 /** 5506 * Select which fixed information about stream is desired. 5507 * This information may be changed during the lifetime of the stream. 5508 */ 5509 enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoDynamicType 5510 { 5511 /** 5512 * Get the `struct MHD_Request *` for current request processed by the stream. 5513 * If no request is being processed, the error code #MHD_SC_TOO_EARLY is 5514 * returned. 5515 * The result is placed in @a v_request member. 5516 * @ingroup request 5517 */ 5518 MHD_STREAM_INFO_DYNAMIC_REQUEST = 20 5519 , 5520 5521 /* * Sentinel * */ 5522 /** 5523 * The sentinel value. 5524 * This value enforces specific underlying integer type for the enum. 5525 * Do not use. 5526 */ 5527 MHD_STREAM_INFO_DYNAMIC_SENTINEL = 65535 5528 }; 5529 5530 5531 /** 5532 * Dynamic information about stream. 5533 * This information may be changed during the lifetime of the connection. 5534 */ 5535 union MHD_StreamInfoDynamicData 5536 { 5537 /** 5538 * The data for the #MHD_STREAM_INFO_DYNAMIC_REQUEST query 5539 */ 5540 struct MHD_Request *v_request; 5541 }; 5542 5543 /** 5544 * Obtain dynamic information about the given stream. 5545 * This information may be changed during the lifetime of the stream. 5546 * 5547 * The wrapper macro #MHD_stream_get_info_dynamic() may be more convenient. 5548 * 5549 * @param stream the stream to get information about 5550 * @param info_type the type of information requested 5551 * @param[out] output_buf the pointer to union to be set to the requested 5552 * information 5553 * @param output_buf_size the size of the memory area pointed by @a output_buf 5554 * (provided by the caller for storing the requested 5555 * information), in bytes 5556 * @return #MHD_SC_OK if succeed, 5557 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5558 * #MHD_SC_TOO_EARLY if the stream has not reached yet required state, 5559 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5560 * other error codes in case of other errors 5561 * @ingroup specialized 5562 */ 5563 MHD_EXTERN_ enum MHD_StatusCode 5564 MHD_stream_get_info_dynamic_sz ( 5565 struct MHD_Stream *MHD_RESTRICT stream, 5566 enum MHD_StreamInfoDynamicType info_type, 5567 union MHD_StreamInfoDynamicData *MHD_RESTRICT output_buf, 5568 size_t output_buf_size) 5569 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5570 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5571 5572 5573 /** 5574 * Obtain dynamic information about the given stream. 5575 * This information may be changed during the lifetime of the stream. 5576 * 5577 * @param stream the stream to get information about 5578 * @param info_type the type of information requested 5579 * @param[out] output_buf the pointer to union to be set to the requested 5580 * information 5581 * @return #MHD_SC_OK if succeed, 5582 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5583 * #MHD_SC_TOO_EARLY if the stream has not reached yet required state, 5584 * other error codes in case of other errors 5585 * @ingroup specialized 5586 */ 5587 #define MHD_stream_get_info_dynamic(stream,info_type,output_buf) \ 5588 MHD_stream_get_info_dynamic_sz ((stream),(info_type),(output_buf), \ 5589 sizeof(*(output_buf))) 5590 5591 5592 /** 5593 * Select which fixed information about request is desired. 5594 * This information is not changed during the lifetime of the request. 5595 */ 5596 enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoFixedType 5597 { 5598 /** 5599 * Get the version of HTTP protocol used for the request. 5600 * If request line has not been fully received yet then #MHD_SC_TOO_EARLY 5601 * error code is returned. 5602 * The result is placed in @a v_http_ver member. 5603 * @ingroup request 5604 */ 5605 MHD_REQUEST_INFO_FIXED_HTTP_VER = 1 5606 , 5607 /** 5608 * Get the HTTP method used for the request (as a enum). 5609 * The result is placed in @a v_http_method member. 5610 * @sa #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR 5611 * @ingroup request 5612 */ 5613 MHD_REQUEST_INFO_FIXED_HTTP_METHOD = 2 5614 , 5615 /** 5616 * Return MHD daemon to which the request belongs to. 5617 * The result is placed in @a v_daemon member. 5618 */ 5619 MHD_REQUEST_INFO_FIXED_DAEMON = 20 5620 , 5621 /** 5622 * Return which connection is associated with the stream which is associated 5623 * with the request. 5624 * The result is placed in @a v_connection member. 5625 */ 5626 MHD_REQUEST_INFO_FIXED_CONNECTION = 21 5627 , 5628 /** 5629 * Return which stream the request is associated with. 5630 * The result is placed in @a v_stream member. 5631 */ 5632 MHD_REQUEST_INFO_FIXED_STREAM = 22 5633 , 5634 /** 5635 * Returns the pointer to a variable pointing to request-specific 5636 * application context data. The same data is provided for 5637 * #MHD_EarlyUriLogCallback and #MHD_RequestTerminationCallback. 5638 * By using provided pointer application may get or set the pointer to 5639 * any data specific for the particular request. 5640 * Note: resulting data is NOT the context pointer itself. 5641 * The result is placed in @a v_app_context_ppvoid member. 5642 * @ingroup request 5643 */ 5644 MHD_REQUEST_INFO_FIXED_APP_CONTEXT = 30 5645 , 5646 5647 /* * Sentinel * */ 5648 /** 5649 * The sentinel value. 5650 * This value enforces specific underlying integer type for the enum. 5651 * Do not use. 5652 */ 5653 MHD_REQUEST_INFO_FIXED_SENTINEL = 65535 5654 }; 5655 5656 5657 /** 5658 * Fixed information about a request. 5659 */ 5660 union MHD_RequestInfoFixedData 5661 { 5662 5663 /** 5664 * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_VER query 5665 */ 5666 enum MHD_HTTP_ProtocolVersion v_http_ver; 5667 5668 /** 5669 * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_METHOD query 5670 */ 5671 enum MHD_HTTP_Method v_http_method; 5672 5673 /** 5674 * The data for the #MHD_REQUEST_INFO_FIXED_DAEMON query 5675 */ 5676 struct MHD_Daemon *v_daemon; 5677 5678 /** 5679 * The data for the #MHD_REQUEST_INFO_FIXED_CONNECTION query 5680 */ 5681 struct MHD_Connection *v_connection; 5682 5683 /** 5684 * The data for the #MHD_REQUEST_INFO_FIXED_STREAM query 5685 */ 5686 struct MHD_Stream *v_stream; 5687 5688 /** 5689 * The data for the #MHD_REQUEST_INFO_FIXED_APP_CONTEXT query 5690 */ 5691 void **v_app_context_ppvoid; 5692 }; 5693 5694 /** 5695 * Obtain fixed information about the given request. 5696 * This information is not changed for the lifetime of the request. 5697 * 5698 * The wrapper macro #MHD_request_get_info_fixed() may be more convenient. 5699 * 5700 * @param request the request to get information about 5701 * @param info_type the type of information requested 5702 * @param[out] output_buf the pointer to union to be set to the requested 5703 * information 5704 * @param output_buf_size the size of the memory area pointed by @a output_buf 5705 * (provided by the caller for storing the requested 5706 * information), in bytes 5707 * @return #MHD_SC_OK if succeed, 5708 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5709 * #MHD_SC_TOO_EARLY if the request processing has not reached yet 5710 * the required state, 5711 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5712 * other error codes in case of other errors 5713 * @ingroup specialized 5714 */ 5715 MHD_EXTERN_ enum MHD_StatusCode 5716 MHD_request_get_info_fixed_sz ( 5717 struct MHD_Request *MHD_RESTRICT request, 5718 enum MHD_RequestInfoFixedType info_type, 5719 union MHD_RequestInfoFixedData *MHD_RESTRICT output_buf, 5720 size_t output_buf_size) 5721 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5722 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5723 5724 5725 /** 5726 * Obtain fixed information about the given request. 5727 * This information is not changed for the lifetime of the request. 5728 * 5729 * @param request the request to get information about 5730 * @param info_type the type of information requested 5731 * @param[out] output_buf the pointer to union to be set to the requested 5732 * information 5733 * @return #MHD_SC_OK if succeed, 5734 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5735 * #MHD_SC_TOO_EARLY if the request processing has not reached yet 5736 * the required state, 5737 * other error codes in case of other errors 5738 * @ingroup specialized 5739 */ 5740 #define MHD_request_get_info_fixed(request,info_type,output_buf) \ 5741 MHD_request_get_info_fixed_sz ((request), (info_type), (output_buf), \ 5742 sizeof(*(output_buf))) 5743 5744 5745 /** 5746 * Select which dynamic information about request is desired. 5747 * This information may be changed during the lifetime of the request. 5748 * Any returned string pointers are valid only until a response is provided. 5749 */ 5750 enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoDynamicType 5751 { 5752 /** 5753 * Get the HTTP method used for the request (as a MHD_String). 5754 * The resulting string pointer in valid only until a response is provided. 5755 * The result is placed in @a v_http_method_string member. 5756 * @sa #MHD_REQUEST_INFO_FIXED_HTTP_METHOD 5757 * @ingroup request 5758 */ 5759 MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING = 1 5760 , 5761 /** 5762 * Get the URI used for the request (as a MHD_String), excluding 5763 * the parameter part (anything after '?'). 5764 * The resulting string pointer in valid only until a response is provided. 5765 * The result is placed in @a v_uri_string member. 5766 * @ingroup request 5767 */ 5768 MHD_REQUEST_INFO_DYNAMIC_URI = 2 5769 , 5770 /** 5771 * Get the number of URI parameters (the decoded part of the original 5772 * URI string after '?'). Sometimes it is called "GET parameters". 5773 * The result is placed in @a v_number_uri_params_sizet member. 5774 * @ingroup request 5775 */ 5776 MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS = 3 5777 , 5778 /** 5779 * Get the number of cookies in the request. 5780 * The result is placed in @a v_number_cookies_sizet member. 5781 * If cookies parsing is disabled in MHD build then the function returns 5782 * error code #MHD_SC_FEATURE_DISABLED. 5783 * If cookies parsing is disabled this daemon then the function returns 5784 * error code #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE. 5785 * @ingroup request 5786 */ 5787 MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES = 4 5788 , 5789 /** 5790 * Return length of the client's HTTP request header. 5791 * This is a total raw size of the header (after TLS decipher if any) 5792 * The result is placed in @a v_header_size_sizet member. 5793 * @ingroup request 5794 */ 5795 MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE = 5 5796 , 5797 /** 5798 * Get the number of decoded POST entries in the request. 5799 * The result is placed in @a v_number_post_params_sizet member. 5800 * @ingroup request 5801 */ 5802 MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS = 6 5803 , 5804 /** 5805 * Get whether the upload content is present in the request. 5806 * The result is #MHD_YES if any upload content is present, even 5807 * if the upload content size is zero. 5808 * The result is placed in @a v_upload_present_bool member. 5809 * @ingroup request 5810 */ 5811 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT = 10 5812 , 5813 /** 5814 * Get whether the chunked upload content is present in the request. 5815 * The result is #MHD_YES if chunked upload content is present. 5816 * The result is placed in @a v_upload_chunked_bool member. 5817 * @ingroup request 5818 */ 5819 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED = 11 5820 , 5821 /** 5822 * Get the total content upload size. 5823 * Resulted in zero if no content upload or upload content size is zero, 5824 * #MHD_SIZE_UNKNOWN if size is not known (chunked upload). 5825 * The result is placed in @a v_upload_size_total_uint64 member. 5826 * @ingroup request 5827 */ 5828 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL = 12 5829 , 5830 /** 5831 * Get the total size of the content upload already received from the client. 5832 * This is the total size received, could be not yet fully processed by the 5833 * application. 5834 * The result is placed in @a v_upload_size_recieved_uint64 member. 5835 * @ingroup request 5836 */ 5837 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED = 13 5838 , 5839 /** 5840 * Get the total size of the content upload left to be received from 5841 * the client. 5842 * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload). 5843 * The result is placed in @a v_upload_size_to_recieve_uint64 member. 5844 * @ingroup request 5845 */ 5846 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE = 14 5847 , 5848 /** 5849 * Get the total size of the content upload already processed (upload callback 5850 * called and completed (if any)). 5851 * If the value is requested from #MHD_UploadCallback, then result does NOT 5852 * include the current data being processed by the callback. 5853 * The result is placed in @a v_upload_size_processed_uint64 member. 5854 * @ingroup request 5855 */ 5856 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED = 15 5857 , 5858 /** 5859 * Get the total size of the content upload left to be processed. 5860 * The resulting value includes the size of the data not yet received from 5861 * the client. 5862 * If the value is requested from #MHD_UploadCallback, then result includes 5863 * the current data being processed by the callback. 5864 * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload). 5865 * The result is placed in @a v_upload_size_to_process_uint64 member. 5866 * @ingroup request 5867 */ 5868 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS = 16 5869 , 5870 /** 5871 * Returns pointer to information about digest auth in client request. 5872 * The resulting pointer is NULL if no digest auth header is set by 5873 * the client or the format of the digest auth header is broken. 5874 * Pointers in the returned structure (if any) are valid until response 5875 * is provided for the request. 5876 * The result is placed in @a v_auth_digest_info member. 5877 */ 5878 MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO = 42 5879 , 5880 /** 5881 * Returns information about Basic Authentication credentials in the request. 5882 * Pointers in the returned structure (if any) are valid until any MHD_Action 5883 * or MHD_UploadAction is provided. If the data is needed beyond this point, 5884 * it should be copied. 5885 * If #MHD_request_get_info_dynamic_sz() returns #MHD_SC_OK then 5886 * @a v_auth_basic_creds is NOT NULL and at least the username data 5887 * is provided. 5888 * The result is placed in @a v_auth_basic_creds member. 5889 */ 5890 MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS = 51 5891 , 5892 /* * Sentinel * */ 5893 /** 5894 * The sentinel value. 5895 * This value enforces specific underlying integer type for the enum. 5896 * Do not use. 5897 */ 5898 MHD_REQUEST_INFO_DYNAMIC_SENTINEL = 65535 5899 }; 5900 5901 5902 /** 5903 * Dynamic information about a request. 5904 */ 5905 union MHD_RequestInfoDynamicData 5906 { 5907 5908 /** 5909 * The data for the #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING query 5910 */ 5911 struct MHD_String v_http_method_string; 5912 5913 /** 5914 * The data for the #MHD_REQUEST_INFO_DYNAMIC_URI query 5915 */ 5916 struct MHD_String v_uri_string; 5917 5918 /** 5919 * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS query 5920 */ 5921 size_t v_number_uri_params_sizet; 5922 5923 /** 5924 * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES query 5925 */ 5926 size_t v_number_cookies_sizet; 5927 5928 /** 5929 * The data for the #MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE query 5930 */ 5931 size_t v_header_size_sizet; 5932 5933 /** 5934 * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS query 5935 */ 5936 size_t v_number_post_params_sizet; 5937 5938 /** 5939 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT query 5940 */ 5941 enum MHD_Bool v_upload_present_bool; 5942 5943 /** 5944 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED query 5945 */ 5946 enum MHD_Bool v_upload_chunked_bool; 5947 5948 /** 5949 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL query 5950 */ 5951 uint_fast64_t v_upload_size_total_uint64; 5952 5953 /** 5954 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED query 5955 */ 5956 uint_fast64_t v_upload_size_recieved_uint64; 5957 5958 /** 5959 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE query 5960 */ 5961 uint_fast64_t v_upload_size_to_recieve_uint64; 5962 5963 /** 5964 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED query 5965 */ 5966 uint_fast64_t v_upload_size_processed_uint64; 5967 5968 /** 5969 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS query 5970 */ 5971 uint_fast64_t v_upload_size_to_process_uint64; 5972 5973 /** 5974 * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO query 5975 */ 5976 const struct MHD_AuthDigestInfo *v_auth_digest_info; 5977 5978 /** 5979 * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS query 5980 */ 5981 const struct MHD_AuthBasicCreds *v_auth_basic_creds; 5982 }; 5983 5984 5985 /** 5986 * Obtain dynamic information about the given request. 5987 * This information may be changed during the lifetime of the request. 5988 * Most of the data provided is available only when the request line or complete 5989 * request headers are processed and not available if responding has been 5990 * started. 5991 * 5992 * The wrapper macro #MHD_request_get_info_dynamic() may be more convenient. 5993 * 5994 * Any pointers in the returned data are valid until any MHD_Action or 5995 * MHD_UploadAction is provided. If the data is needed beyond this point, 5996 * it should be copied. 5997 * 5998 * @param request the request to get information about 5999 * @param info_type the type of information requested 6000 * @param[out] output_buf the pointer to union to be set to the requested 6001 * information 6002 * @param output_buf_size the size of the memory area pointed by @a output_buf 6003 * (provided by the caller for storing the requested 6004 * information), in bytes 6005 * @return #MHD_SC_OK if succeed, 6006 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is 6007 * not recognized by MHD, 6008 * #MHD_SC_TOO_LATE if request is already being closed or the response 6009 * is being sent 6010 * #MHD_SC_TOO_EARLY if requested data is not yet ready (for example, 6011 * headers are not yet received), 6012 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is 6013 * not available for this request 6014 * due to used configuration/mode, 6015 * #MHD_SC_FEATURE_DISABLED if requested functionality is not supported 6016 * by this MHD build, 6017 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 6018 * #MHD_SC_AUTH_ABSENT if request does not have particular Auth data, 6019 * #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool 6020 * has no space to put decoded 6021 * authentication data, 6022 * #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is 6023 * incorrect or broken, 6024 * other error codes in case of other errors 6025 * @ingroup specialized 6026 */ 6027 MHD_EXTERN_ enum MHD_StatusCode 6028 MHD_request_get_info_dynamic_sz ( 6029 struct MHD_Request *MHD_RESTRICT request, 6030 enum MHD_RequestInfoDynamicType info_type, 6031 union MHD_RequestInfoDynamicData *MHD_RESTRICT output_buf, 6032 size_t output_buf_size) 6033 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 6034 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 6035 6036 6037 /** 6038 * Obtain dynamic information about the given request. 6039 * This information may be changed during the lifetime of the request. 6040 * Most of the data provided is available only when the request line or complete 6041 * request headers are processed and not available if responding has been 6042 * started. 6043 * 6044 * Any pointers in the returned data are valid until any MHD_Action or 6045 * MHD_UploadAction is provided. If the data is needed beyond this point, 6046 * it should be copied. 6047 * 6048 * @param request the request to get information about 6049 * @param info_type the type of information requested 6050 * @param[out] output_buf the pointer to union to be set to the requested 6051 * information 6052 * @return #MHD_SC_OK if succeed, 6053 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is 6054 * not recognized by MHD, 6055 * #MHD_SC_TOO_LATE if request is already being closed or the response 6056 * is being sent 6057 * #MHD_SC_TOO_EARLY if requested data is not yet ready (for example, 6058 * headers are not yet received), 6059 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is 6060 * not available for this request 6061 * due to used configuration/mode, 6062 * #MHD_SC_FEATURE_DISABLED if requested functionality is not supported 6063 * by this MHD build, 6064 * #MHD_SC_AUTH_ABSENT if request does not have particular Auth data, 6065 * #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool 6066 * has no space to put decoded 6067 * authentication data, 6068 * #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is 6069 * incorrect or broken, 6070 * other error codes in case of other errors 6071 * @ingroup specialized 6072 */ 6073 #define MHD_request_get_info_dynamic(request,info_type,output_buf) \ 6074 MHD_request_get_info_dynamic_sz ((request), (info_type), \ 6075 (output_buf), \ 6076 sizeof(*(output_buf))) 6077 6078 /** 6079 * Callback for serious error condition. The default action is to print 6080 * an error message and `abort()`. 6081 * The callback should not return. 6082 * Some parameters could be empty strings (the strings with zero-termination at 6083 * zero position) if MHD built without log messages (only for embedded 6084 * projects). 6085 * 6086 * @param cls user specified value 6087 * @param file where the error occurred, could be empty 6088 * @param func the name of the function, where the error occurred, may be empty 6089 * @param line where the error occurred 6090 * @param message the error details, could be empty 6091 * @ingroup logging 6092 */ 6093 typedef void 6094 (*MHD_PanicCallback) (void *cls, 6095 const char *file, 6096 const char *func, 6097 unsigned int line, 6098 const char *message); 6099 6100 6101 /** 6102 * Sets the global error handler to a different implementation. 6103 * The @a cb will only be called in the case of typically fatal, serious 6104 * internal consistency issues. 6105 * These issues should only arise in the case of serious memory corruption or 6106 * similar problems with the architecture. 6107 * The @a cb should not return. 6108 * 6109 * The default implementation that is used if no panic function is set 6110 * simply prints an error message and calls `abort()`. Alternative 6111 * implementations might call `exit()` or other similar functions. 6112 * 6113 * @param cb new error handler, NULL to reset to default handler 6114 * @param cls passed to @a cb 6115 * @ingroup logging 6116 */ 6117 MHD_EXTERN_ void 6118 MHD_lib_set_panic_func (MHD_PanicCallback cb, 6119 void *cls); 6120 6121 #define MHD_lib_set_panic_func_default() \ 6122 MHD_lib_set_panic_func (MHD_STATIC_CAST_ (MHD_PanicCallback,NULL),NULL)