microhttpd2_main.h.in (227923B)
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 new_socket socket to manage (MHD will expect to receive an 259 HTTP request from this socket next). 260 * @param addr_size number of bytes in @a addr 261 * @param addr IP address of the client, ignored when @a addrlen is zero 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 new_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 new_socket, 271 size_t addr_size, 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 * kqueue technique for sockets polling 4171 */ 4172 enum MHD_Bool tech_kqueue; 4173 }; 4174 4175 /** 4176 * The types of IPv6 supported 4177 */ 4178 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedIPv6Type 4179 { 4180 /** 4181 * IPv6 is not supported by this MHD build 4182 */ 4183 MHD_LIB_INFO_FIXED_IPV6_TYPE_NONE = 0 4184 , 4185 /** 4186 * IPv6 is supported only as "dual stack". 4187 * IPv4 connections can be received by IPv6 listen socket. 4188 */ 4189 MHD_LIB_INFO_FIXED_IPV6_TYPE_DUAL_ONLY = 1 4190 , 4191 /** 4192 * IPv6 can be used as IPv6-only (without getting IPv4 incoming connections). 4193 * The platform may support "dual stack" too. 4194 */ 4195 MHD_LIB_INFO_FIXED_IPV6_TYPE_IPV6_PURE = 2 4196 }; 4197 4198 /** 4199 * The types of inter-thread communication 4200 * @note the enum can be extended in future versions with new values 4201 */ 4202 enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedITCType 4203 { 4204 /** 4205 * No ITC used. 4206 * This value is returned if MHD is built without threads support 4207 */ 4208 MHD_LIB_INFO_FIXED_ITC_TYPE_NONE = 0 4209 , 4210 /** 4211 * The pair of sockets are used as inter-thread communication. 4212 * The is the least efficient method of communication. 4213 */ 4214 MHD_LIB_INFO_FIXED_ITC_TYPE_SOCKETPAIR = 1 4215 , 4216 /** 4217 * The pipe is used as inter-thread communication. 4218 */ 4219 MHD_LIB_INFO_FIXED_ITC_TYPE_PIPE = 2 4220 , 4221 /** 4222 * The EventFD is used as inter-thread communication. 4223 * This is the most efficient method of communication. 4224 */ 4225 MHD_LIB_INFO_FIXED_ITC_TYPE_EVENTFD = 3 4226 }; 4227 4228 4229 /** 4230 * The types of the TLS (or TLS feature) backend supported/available/enabled 4231 * @note the enum can be extended in future versions with new members 4232 */ 4233 struct MHD_LibInfoTLSType 4234 { 4235 /** 4236 * The TLS (or TLS feature) is supported/enabled. 4237 * Set to #MHD_YES if any other member is #MHD_YES. 4238 */ 4239 enum MHD_Bool tls_supported; 4240 /** 4241 * The GnuTLS backend is supported/available/enabled. 4242 */ 4243 enum MHD_Bool backend_gnutls; 4244 /** 4245 * The OpenSSL backend is supported/available/enabled. 4246 */ 4247 enum MHD_Bool backend_openssl; 4248 /** 4249 * The MbedTLS backend is supported/available/enabled. 4250 */ 4251 enum MHD_Bool backend_mbedtls; 4252 }; 4253 4254 /** 4255 * The data provided by #MHD_lib_get_info_fixed_sz() 4256 */ 4257 union MHD_LibInfoFixedData 4258 { 4259 /** 4260 * The data for the #MHD_LIB_INFO_FIXED_VERSION_NUM query 4261 */ 4262 uint_fast32_t v_version_num_uint32; 4263 /** 4264 * The data for the #MHD_LIB_INFO_FIXED_VERSION_STR query 4265 */ 4266 struct MHD_String v_version_string; 4267 /** 4268 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES query 4269 */ 4270 enum MHD_Bool v_support_log_messages_bool; 4271 /** 4272 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES query 4273 */ 4274 enum MHD_Bool v_support_auto_replies_bodies_bool; 4275 /** 4276 * The data for the #MHD_LIB_INFO_FIXED_IS_NON_DEBUG query 4277 */ 4278 enum MHD_Bool v_is_non_debug_bool; 4279 /** 4280 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_THREADS query 4281 */ 4282 enum MHD_Bool v_support_threads_bool; 4283 /** 4284 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER query 4285 */ 4286 enum MHD_Bool v_support_cookie_parser_bool; 4287 /** 4288 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER query 4289 */ 4290 enum MHD_Bool v_support_post_parser_bool; 4291 /** 4292 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE query 4293 */ 4294 enum MHD_Bool v_support_upgrade_bool; 4295 /** 4296 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC query 4297 */ 4298 enum MHD_Bool v_support_auth_basic_bool; 4299 /** 4300 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST query 4301 */ 4302 enum MHD_Bool v_support_auth_digest_bool; 4303 /** 4304 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069 query 4305 */ 4306 enum MHD_Bool v_support_digest_auth_rfc2069_bool; 4307 /** 4308 * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 query 4309 */ 4310 enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_md5_algo_type; 4311 /** 4312 * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 query 4313 */ 4314 enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha256_algo_type; 4315 /** 4316 * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 query 4317 */ 4318 enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha512_256_algo_type; 4319 /** 4320 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT query 4321 */ 4322 enum MHD_Bool v_support_digest_auth_auth_int_bool; 4323 /** 4324 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION query 4325 */ 4326 enum MHD_Bool v_support_digest_auth_algo_session_bool; 4327 /** 4328 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH query 4329 */ 4330 enum MHD_Bool v_support_digest_auth_userhash_bool; 4331 /** 4332 * The data for the #MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING query 4333 */ 4334 struct MHD_LibInfoFixedPollingFunc v_types_sockets_polling; 4335 /** 4336 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD query 4337 */ 4338 enum MHD_Bool v_support_aggregate_fd_bool; 4339 /** 4340 * The data for the #MHD_LIB_INFO_FIXED_TYPE_IPV6 query 4341 */ 4342 enum MHD_LibInfoFixedIPv6Type v_ipv6; 4343 /** 4344 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN query 4345 */ 4346 enum MHD_Bool v_support_tcp_fastopen_bool; 4347 /** 4348 * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT query 4349 */ 4350 enum MHD_Bool v_has_autodetect_bind_port_bool; 4351 /** 4352 * The data for the #MHD_LIB_INFO_FIXED_HAS_SENDFILE query 4353 */ 4354 enum MHD_Bool v_has_sendfile_bool; 4355 /** 4356 * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT query 4357 */ 4358 enum MHD_Bool v_has_autosuppress_sigpipe_int_bool; 4359 /** 4360 * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT query 4361 */ 4362 enum MHD_Bool v_has_autosuppress_sigpipe_ext_bool; 4363 /** 4364 * The data for the #MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES query 4365 */ 4366 enum MHD_Bool v_has_thread_names_bool; 4367 /** 4368 * The data for the #MHD_LIB_INFO_FIXED_TYPE_ITC query 4369 */ 4370 enum MHD_LibInfoFixedITCType v_type_itc; 4371 /** 4372 * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE query 4373 */ 4374 enum MHD_Bool v_support_large_file_bool; 4375 /** 4376 * The data for the #MHD_LIB_INFO_FIXED_TLS_BACKENDS query 4377 */ 4378 struct MHD_LibInfoTLSType v_tls_backends; 4379 /** 4380 * The data for the #MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS query 4381 */ 4382 struct MHD_LibInfoTLSType v_tls_key_password_backends; 4383 }; 4384 4385 /** 4386 * Get fixed information about MHD that is not changed at run-time. 4387 * The returned information can be cached by application as it will be not 4388 * changed at run-time. 4389 * 4390 * For any valid @a info_type the only possible returned error value is 4391 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL. If the buffer is large enough and 4392 * the requested type of information is valid, the function always succeeds 4393 * and returns #MHD_SC_OK. 4394 * 4395 * The wrapper macro #MHD_lib_get_info_fixed() may be more convenient. 4396 * 4397 * @param info_type the type of requested information 4398 * @param[out] output_buf the pointer to union to be set to the requested 4399 * information 4400 * @param output_buf_size the size of the memory area pointed by @a output_buf 4401 * (provided by the caller for storing the requested 4402 * information), in bytes 4403 * @return #MHD_SC_OK if succeed, 4404 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4405 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small 4406 * @ingroup specialized 4407 */ 4408 MHD_EXTERN_ enum MHD_StatusCode 4409 MHD_lib_get_info_fixed_sz (enum MHD_LibInfoFixed info_type, 4410 union MHD_LibInfoFixedData *MHD_RESTRICT output_buf, 4411 size_t output_buf_size) 4412 MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2); 4413 4414 /** 4415 * Get fixed information about MHD that is not changed at run-time. 4416 * The returned information can be cached by application as it will be not 4417 * changed at run-time. 4418 * 4419 * @param info the type of requested information 4420 * @param[out] output_buf the pointer to union to be set to the requested 4421 * information 4422 * @return #MHD_SC_OK if succeed, 4423 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4424 * or other error code 4425 * @ingroup specialized 4426 */ 4427 #define MHD_lib_get_info_fixed(info,output_buf) \ 4428 MHD_lib_get_info_fixed_sz ((info),(output_buf),sizeof(*(output_buf))) 4429 4430 /* Application may define MHD_NO_STATIC_INLINE macro before including 4431 libmicrohttpd headers to disable static inline functions in the headers. */ 4432 #ifndef MHD_NO_STATIC_INLINE 4433 4434 /* 4435 * A helper below can be used in a simple check preventing use of downgraded 4436 * library version. 4437 * As new library version may introduce new functionality, and the application 4438 * may detect some functionality available at application build-time, use of 4439 * previous versions may lead to run-time failures. 4440 * To prevent run-time failures, application may use a check like: 4441 4442 if (MHD_lib_get_info_ver_num() < ((uint_fast32_t) MHD_VERSION)) 4443 handle_init_failure(); 4444 4445 */ 4446 /** 4447 * Get the library version number. 4448 * @return the library version number. 4449 */ 4450 MHD_STATIC_INLINE_ MHD_FN_PURE_ uint_fast32_t 4451 MHD_lib_get_info_ver_num (void) 4452 { 4453 union MHD_LibInfoFixedData data; 4454 data.v_version_num_uint32 = 0; /* Not really necessary */ 4455 (void) MHD_lib_get_info_fixed (MHD_LIB_INFO_FIXED_VERSION_NUM, \ 4456 &data); /* Never fail */ 4457 return data.v_version_num_uint32; 4458 } 4459 4460 4461 MHD_STATIC_INLINE_END_ 4462 4463 #endif /* ! MHD_NO_STATIC_INLINE */ 4464 4465 /** 4466 * Types of information about MHD, used by #MHD_lib_get_info_dynamic_sz(). 4467 * This information may vary over time. 4468 */ 4469 enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoDynamic 4470 { 4471 /* * Basic MHD information * */ 4472 4473 /** 4474 * Get whether MHD has been successfully fully initialised. 4475 * MHD uses lazy initialisation: a minimal initialisation is performed at 4476 * startup, complete initialisation is performed when any daemon is created 4477 * (or when called some function which requires full initialisation). 4478 * The result is #MHD_NO when the library has been not yet initialised 4479 * completely since startup. 4480 * The result is placed in @a v_inited_fully_once_bool member. 4481 */ 4482 MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE = 0 4483 , 4484 /** 4485 * Get whether MHD is fully initialised. 4486 * MHD uses lazy initialisation: a minimal initialisation is performed at 4487 * startup, complete initialisation is perfromed when any daemon is created 4488 * (or when called some function which requires full initialisation). 4489 * The result is #MHD_YES if library is initialised state now (meaning 4490 * that at least one daemon is created and not destroyed or some function 4491 * required full initialisation is running). 4492 * The result is placed in @a v_inited_fully_now_bool member. 4493 */ 4494 MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW = 1 4495 , 4496 4497 /** 4498 * Get whether HTTPS and which types of TLS backend(s) currently available. 4499 * If any MHD daemons active (created and not destroyed, not necessary 4500 * running) the result reflects the current backends availability. 4501 * If no MHD daemon is active, then this function would try to temporarily 4502 * enable backends to check for their availability. 4503 * If global library initialisation failed, the function returns 4504 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE error code. 4505 * The result is placed in @a v_tls_backends member. 4506 */ 4507 MHD_LIB_INFO_DYNAMIC_TYPE_TLS = 100 4508 , 4509 4510 /* * Sentinel * */ 4511 /** 4512 * The sentinel value. 4513 * This value enforces specific underlying integer type for the enum. 4514 * Do not use. 4515 */ 4516 MHD_LIB_INFO_DYNAMIC_SENTINEL = 65535 4517 }; 4518 4519 4520 /** 4521 * The data provided by #MHD_lib_get_info_dynamic_sz(). 4522 * The resulting value may vary over time. 4523 */ 4524 union MHD_LibInfoDynamicData 4525 { 4526 /** 4527 * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE query 4528 */ 4529 enum MHD_Bool v_inited_fully_once_bool; 4530 4531 /** 4532 * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW query 4533 */ 4534 enum MHD_Bool v_inited_fully_now_bool; 4535 4536 /** 4537 * The data for the #MHD_LIB_INFO_DYNAMIC_TYPE_TLS query 4538 */ 4539 struct MHD_LibInfoTLSType v_tls_backends; 4540 4541 /** 4542 * Unused member. 4543 * Help enforcing future-proof alignment of the union. 4544 * Do not use. 4545 */ 4546 void *reserved; 4547 }; 4548 4549 /** 4550 * Get dynamic information about MHD that may be changed at run-time. 4551 * The wrapper macro #MHD_lib_get_info_dynamic() could be more convenient. 4552 * 4553 * @param info_type the type of requested information 4554 * @param[out] output_buf the pointer to union to be set to the requested 4555 * information 4556 * @param output_buf_size the size of the memory area pointed by @a output_buf 4557 * (provided by the caller for storing the requested 4558 * information), in bytes 4559 * @return #MHD_SC_OK if succeed, 4560 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4561 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 4562 * or other error code 4563 * @ingroup specialized 4564 */ 4565 MHD_EXTERN_ enum MHD_StatusCode 4566 MHD_lib_get_info_dynamic_sz ( 4567 enum MHD_LibInfoDynamic info_type, 4568 union MHD_LibInfoDynamicData *MHD_RESTRICT output_buf, 4569 size_t output_buf_size) 4570 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2); 4571 4572 /** 4573 * Get dynamic information about MHD that may be changed at run-time. 4574 * 4575 * @param info the type of requested information 4576 * @param[out] output_buf the pointer to union to be set to the requested 4577 * information 4578 * @return #MHD_SC_OK if succeed, 4579 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4580 * or other error code 4581 * @ingroup specialized 4582 */ 4583 #define MHD_lib_get_info_dynamic(info,output_buf) \ 4584 MHD_lib_get_info_dynamic_sz ((info),(output_buf),sizeof(*(output_buf))) 4585 4586 4587 /** 4588 * Values of this enum are used to specify what information about a daemon is 4589 * requested. 4590 * These types of information do not change after the start of the daemon 4591 * until the daemon is destroyed. 4592 */ 4593 enum MHD_DaemonInfoFixedType 4594 { 4595 4596 /** 4597 * Get the type of system call used for sockets polling. 4598 * The value #MHD_SPS_AUTO is never set in the returned data. 4599 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4600 * does not use internal sockets polling. 4601 * The result is placed in @a v_poll_syscall member. 4602 */ 4603 MHD_DAEMON_INFO_FIXED_POLL_SYSCALL = 41 4604 , 4605 /** 4606 * Get the file descriptor for the single FD that triggered when 4607 * any MHD event happens. 4608 * This FD can be watched as aggregate indicator for all MHD events. 4609 * The provided socket must be used as 'read-only': only select() or similar 4610 * functions should be used. Any modifications (changing socket attributes, 4611 * calling accept(), closing it etc.) will lead to undefined behaviour. 4612 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library 4613 * does not support mode with agregate FD. 4614 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4615 * is not configured to use this mode. 4616 * The result is placed in @a v_aggreagate_fd member. 4617 */ 4618 MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 46 4619 , 4620 /** 4621 * Get the number of worker threads when used in MHD_WM_WORKER_THREADS mode. 4622 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4623 * does not use worker threads mode. 4624 * The result is placed in @a v_num_work_threads_uint member. 4625 */ 4626 MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS = 47 4627 , 4628 /** 4629 * Get the port number of daemon's listen socket. 4630 * Note: if port '0' (auto port) was specified for #MHD_D_OPTION_BIND_PORT(), 4631 * returned value will be the real port number. 4632 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4633 * does not have listening socket or if listening socket is non-IP. 4634 * The function returns #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the port number 4635 * detection failed or not supported by the platform. 4636 * If the function succeed, the returned port number is never zero. 4637 * The result is placed in @a v_bind_port_uint16 member. 4638 */ 4639 MHD_DAEMON_INFO_FIXED_BIND_PORT = 80 4640 , 4641 /** 4642 * Get the file descriptor for the listening socket. 4643 * The provided socket must be used as 'read-only': only select() or similar 4644 * functions should be used. Any modifications (changing socket attributes, 4645 * calling accept(), closing it etc.) will lead to undefined behaviour. 4646 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4647 * does not have listening socket. 4648 * The result is placed in @a v_listen_socket member. 4649 */ 4650 MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 82 4651 , 4652 /** 4653 * Get the TLS backend used by the daemon. 4654 * The value #MHD_TLS_BACKEND_ANY is never set in the returned data. 4655 * The value #MHD_TLS_BACKEND_NONE is set if the daemon does not use TLS. 4656 * If MHD built without TLS support then #MHD_TLS_BACKEND_NONE is always set. 4657 * The result is placed in @a v_tls_backend member. 4658 */ 4659 MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 120 4660 , 4661 /** 4662 * Get the default inactivity timeout for connections in milliseconds. 4663 * The result is placed in @a v_default_timeout_milsec_uint32 member. 4664 */ 4665 MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT_MILSEC = 160 4666 , 4667 /** 4668 * Get the limit of number of simutaneous network connections served by 4669 * the daemon. 4670 * The result is placed in @a v_global_connection_limit_uint member. 4671 */ 4672 MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT = 161 4673 , 4674 /** 4675 * Get the limit of number of simutaneous network connections served by 4676 * the daemon for any single IP address. 4677 * The result is placed in @a v_per_ip_limit_uint member. 4678 */ 4679 MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT = 162 4680 , 4681 /** 4682 * Get the setting for suppression of the 'Date:' header in replies. 4683 * The result is placed in @a v_suppress_date_header_bool member. 4684 */ 4685 MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER = 240 4686 , 4687 /** 4688 * Get the size of buffer unsed per connection. 4689 * The result is placed in @a v_conn_memory_limit_sizet member. 4690 */ 4691 MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT = 280 4692 , 4693 /** 4694 * Get the limit of maximum FD value for the daemon. 4695 * The daemon rejects (closes) any sockets with FD equal or higher 4696 * the resulting number. 4697 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon 4698 * is built for W32. 4699 * The result is placed in @a v_fd_number_limit_uint member. 4700 */ 4701 MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT = 283 4702 , 4703 4704 /* * Sentinel * */ 4705 /** 4706 * The sentinel value. 4707 * This value enforces specific underlying integer type for the enum. 4708 * Do not use. 4709 */ 4710 MHD_DAEMON_INFO_FIXED_SENTINEL = 65535 4711 4712 }; 4713 4714 4715 /** 4716 * Information about an MHD daemon. 4717 */ 4718 union MHD_DaemonInfoFixedData 4719 { 4720 /** 4721 * The data for the #MHD_DAEMON_INFO_FIXED_POLL_SYSCALL query 4722 */ 4723 enum MHD_SockPollSyscall v_poll_syscall; 4724 4725 /** 4726 * The data for the #MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS query 4727 */ 4728 unsigned int v_num_work_threads_uint; 4729 4730 /** 4731 * The data for the #MHD_DAEMON_INFO_FIXED_BIND_PORT query 4732 */ 4733 uint_least16_t v_bind_port_uint16; 4734 4735 /** 4736 * The data for the #MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET query 4737 */ 4738 MHD_Socket v_listen_socket; 4739 4740 /** 4741 * The data for the #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD query 4742 */ 4743 int v_aggreagate_fd; 4744 4745 /** 4746 * The data for the #MHD_DAEMON_INFO_FIXED_TLS_BACKEND query 4747 */ 4748 enum MHD_TlsBackend v_tls_backend; 4749 4750 /** 4751 * The data for the #MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT_MILSEC query 4752 */ 4753 uint_fast32_t v_default_timeout_milsec_uint32; 4754 4755 /** 4756 * The data for the #MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT query 4757 */ 4758 unsigned int v_global_connection_limit_uint; 4759 4760 /** 4761 * The data for the #MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT query 4762 */ 4763 unsigned int v_per_ip_limit_uint; 4764 4765 /** 4766 * The data for the #MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER query 4767 */ 4768 enum MHD_Bool v_suppress_date_header_bool; 4769 4770 /** 4771 * The data for the #MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT query 4772 */ 4773 size_t v_conn_memory_limit_sizet; 4774 4775 /** 4776 * The data for the #MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT query 4777 */ 4778 MHD_Socket v_fd_number_limit_socket; 4779 4780 /** 4781 * Unused member. 4782 * Help enforcing future-proof alignment of the union. 4783 * Do not use. 4784 */ 4785 void *reserved; 4786 }; 4787 4788 4789 /** 4790 * Obtain fixed information about the given daemon. 4791 * This information is not changed at after start of the daemon until 4792 * the daemon is destroyed. 4793 * The wrapper macro #MHD_daemon_get_info_fixed() may be more convenient. 4794 * 4795 * @param daemon the daemon to get information about 4796 * @param info_type the type of information requested 4797 * @param[out] output_buf pointer to union where requested information will 4798 * be stored 4799 * @param output_buf_size the size of the memory area pointed by @a output_buf 4800 * (provided by the caller for storing the requested 4801 * information), in bytes 4802 * @return #MHD_SC_OK if succeed, 4803 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4804 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4805 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4806 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4807 * is not available for this 4808 * daemon due to the daemon 4809 * configuration/mode, 4810 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4811 * should be available for 4812 * the daemon, but cannot be provided 4813 * due to some error or other 4814 * reasons, 4815 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 4816 * other error codes in case of other errors 4817 * @ingroup specialized 4818 */ 4819 MHD_EXTERN_ enum MHD_StatusCode 4820 MHD_daemon_get_info_fixed_sz ( 4821 struct MHD_Daemon *MHD_RESTRICT daemon, 4822 enum MHD_DaemonInfoFixedType info_type, 4823 union MHD_DaemonInfoFixedData *MHD_RESTRICT output_buf, 4824 size_t output_buf_size) 4825 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 4826 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 4827 4828 /** 4829 * Obtain fixed information about the given daemon. 4830 * This types of information are not changed at after start of the daemon until 4831 * the daemon is destroyed. 4832 * 4833 * @param daemon the daemon to get information about 4834 * @param info_type the type of information requested 4835 * @param[out] output_buf pointer to union where requested information will 4836 * be stored 4837 * @return #MHD_SC_OK if succeed, 4838 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4839 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4840 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4841 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4842 * is not available for this 4843 * daemon due to the daemon 4844 * configuration/mode, 4845 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4846 * should be available for 4847 * the daemon, but cannot be provided 4848 * due to some error or other 4849 * reasons, 4850 * other error codes in case of other errors 4851 * @ingroup specialized 4852 */ 4853 #define MHD_daemon_get_info_fixed(daemon,info_type,output_buf) \ 4854 MHD_daemon_get_info_fixed_sz ((daemon), (info_type), (output_buf), \ 4855 sizeof(*(output_buf))) 4856 4857 4858 /** 4859 * Values of this enum are used to specify what 4860 * information about a daemon is desired. 4861 * This types of information may be changed after the start of the daemon. 4862 */ 4863 enum MHD_DaemonInfoDynamicType 4864 { 4865 /** 4866 * The the maximum number of millisecond from the current moment until 4867 * the mandatory call of the daemon data processing function (like 4868 * #MHD_daemon_process_reg_events(), #MHD_daemon_process_blocking()). 4869 * If resulting value is zero then daemon data processing function should be 4870 * called as soon as possible as some data processing is already pending. 4871 * The data processing function can also be called earlier as well. 4872 * Available only for daemons stated in #MHD_WM_EXTERNAL_PERIODIC, 4873 * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL, #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE 4874 * or #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes. 4875 * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon has 4876 * internal handling of events (internal threads). 4877 * The result is placed in @a v_max_time_to_wait_uint64 member. 4878 */ 4879 MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT = 1 4880 , 4881 /** 4882 * Check whether the daemon has any connected network clients. 4883 * The result is placed in @a v_has_connections_bool member. 4884 */ 4885 MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS = 20 4886 , 4887 /* * Sentinel * */ 4888 /** 4889 * The sentinel value. 4890 * This value enforces specific underlying integer type for the enum. 4891 * Do not use. 4892 */ 4893 MHD_DAEMON_INFO_DYNAMIC_SENTINEL = 65535 4894 }; 4895 4896 4897 /** 4898 * Information about an MHD daemon. 4899 */ 4900 union MHD_DaemonInfoDynamicData 4901 { 4902 /** 4903 * The data for the #MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT query 4904 */ 4905 uint_fast64_t v_max_time_to_wait_uint64; 4906 4907 /** 4908 * The data for the #MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS query 4909 */ 4910 enum MHD_Bool v_has_connections_bool; 4911 4912 /** 4913 * Unused member. 4914 * Help enforcing future-proof alignment of the union. 4915 * Do not use. 4916 */ 4917 void *reserved; 4918 }; 4919 4920 4921 /** 4922 * Obtain dynamic information about the given daemon. 4923 * This information may be changed after the start of the daemon. 4924 * The wrapper macro #MHD_daemon_get_info_dynamic() could be more convenient. 4925 * 4926 * @param daemon the daemon to get information about 4927 * @param info_type the type of information requested 4928 * @param[out] output_buf the pointer to union to be set to the requested 4929 * information 4930 * @param output_buf_size the size of the memory area pointed by @a output_buf 4931 * (provided by the caller for storing the requested 4932 * information), in bytes 4933 * @return #MHD_SC_OK if succeed, 4934 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4935 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4936 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4937 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4938 * is not available for this 4939 * daemon due to the daemon 4940 * configuration/mode, 4941 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4942 * should be available for 4943 * the daemon, but cannot be provided 4944 * due to some error or other 4945 * reasons, 4946 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 4947 * other error codes in case of other errors 4948 * @ingroup specialized 4949 */ 4950 MHD_EXTERN_ enum MHD_StatusCode 4951 MHD_daemon_get_info_dynamic_sz ( 4952 struct MHD_Daemon *MHD_RESTRICT daemon, 4953 enum MHD_DaemonInfoDynamicType info_type, 4954 union MHD_DaemonInfoDynamicData *MHD_RESTRICT output_buf, 4955 size_t output_buf_size) 4956 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 4957 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 4958 4959 /** 4960 * Obtain dynamic information about the given daemon. 4961 * This types of information may be changed after the start of the daemon. 4962 * 4963 * @param daemon the daemon to get information about 4964 * @param info_type the type of information requested 4965 * @param[out] output_buf the pointer to union to be set to the requested 4966 * information 4967 * @return #MHD_SC_OK if succeed, 4968 * #MHD_SC_TOO_EARLY if the daemon has not been started yet, 4969 * #MHD_SC_TOO_LATE if the daemon is being stopped or has failed, 4970 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 4971 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 4972 * is not available for this 4973 * daemon due to the daemon 4974 * configuration/mode, 4975 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 4976 * should be available for 4977 * the daemon, but cannot be provided 4978 * due to some error or other 4979 * reasons, 4980 * other error codes in case of other errors 4981 * @ingroup specialized 4982 */ 4983 #define MHD_daemon_get_info_dynamic(daemon,info_type,output_buf) \ 4984 MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (output_buf), \ 4985 sizeof(*(output_buf))) 4986 4987 4988 /** 4989 * Select which fixed information about connection is desired. 4990 * This information is not changed during the lifetime of the connection. 4991 */ 4992 enum MHD_ConnectionInfoFixedType 4993 { 4994 /** 4995 * Get the network address of the client. 4996 * If the connection does not have known remote address (was not provided 4997 * by the system or by the application in case of externally added 4998 * connection) then error code #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is 4999 * returned if connection is IP type or unknown type or error code 5000 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if connection type is non-IP. 5001 * The @a sa pointer is never NULL if the function succeed (#MHD_SC_OK 5002 * returned). 5003 * The result is placed in @a v_client_address_sa_info member. 5004 * @ingroup request 5005 */ 5006 MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS = 1 5007 , 5008 /** 5009 * Get the file descriptor for the connection socket. 5010 * The provided socket must be used as 'read-only': only select() or similar 5011 * functions should be used. Any modifications (changing socket attributes, 5012 * calling send() or recv(), closing it etc.) will lead to undefined 5013 * behaviour. 5014 * The result is placed in @a v_connection_socket member. 5015 * @ingroup request 5016 */ 5017 MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET = 2 5018 , 5019 /** 5020 * Get the `struct MHD_Daemon *` responsible for managing this connection. 5021 * The result is placed in @a v_daemon member. 5022 * @ingroup request 5023 */ 5024 MHD_CONNECTION_INFO_FIXED_DAEMON = 20 5025 , 5026 /** 5027 * Returns the pointer to a variable pointing to connection-specific 5028 * application context data that was (possibly) set during 5029 * a #MHD_NotifyConnectionCallback or provided via @a connection_cntx 5030 * parameter of #MHD_daemon_add_connection(). 5031 * By using provided pointer application may get or set the pointer to 5032 * any data specific for the particular connection. 5033 * Note: resulting data is NOT the context pointer itself. 5034 * The result is placed in @a v_app_context_ppvoid member. 5035 * @ingroup request 5036 */ 5037 MHD_CONNECTION_INFO_FIXED_APP_CONTEXT = 30 5038 , 5039 5040 /* * Sentinel * */ 5041 /** 5042 * The sentinel value. 5043 * This value enforces specific underlying integer type for the enum. 5044 * Do not use. 5045 */ 5046 MHD_CONNECTION_INFO_FIXED_SENTINEL = 65535 5047 }; 5048 5049 /** 5050 * Socket address information data 5051 */ 5052 struct MHD_ConnInfoFixedSockAddr 5053 { 5054 /** 5055 * The size of the @a sa 5056 */ 5057 size_t sa_size; 5058 5059 /** 5060 * Socket Address type 5061 */ 5062 const struct sockaddr *sa; 5063 }; 5064 5065 /** 5066 * Information about a connection. 5067 */ 5068 union MHD_ConnectionInfoFixedData 5069 { 5070 5071 /** 5072 * The data for the #MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS query 5073 */ 5074 struct MHD_ConnInfoFixedSockAddr v_client_address_sa_info; 5075 5076 /** 5077 * The data for the #MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET query 5078 */ 5079 MHD_Socket v_connection_socket; 5080 5081 /** 5082 * The data for the #MHD_CONNECTION_INFO_FIXED_DAEMON query 5083 */ 5084 struct MHD_Daemon *v_daemon; 5085 5086 /** 5087 * The data for the #MHD_CONNECTION_INFO_FIXED_APP_CONTEXT query 5088 */ 5089 void **v_app_context_ppvoid; 5090 }; 5091 5092 5093 /** 5094 * Obtain fixed information about the given connection. 5095 * This information is not changed for the lifetime of the connection. 5096 * The wrapper macro #MHD_connection_get_info_fixed() may be more convenient. 5097 * 5098 * @param connection the connection to get information about 5099 * @param info_type the type of information requested 5100 * @param[out] output_buf the pointer to union to be set to the requested 5101 * information 5102 * @param output_buf_size the size of the memory area pointed by @a output_buf 5103 * (provided by the caller for storing the requested 5104 * information), in bytes 5105 * @return #MHD_SC_OK if succeed, 5106 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5107 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5108 * is not available for this 5109 * connection due to the connection 5110 * configuration/mode, 5111 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5112 * should be available for 5113 * the connection, but cannot be 5114 * provided due to some error or 5115 * other reasons, 5116 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5117 * other error codes in case of other errors 5118 * @ingroup specialized 5119 */ 5120 MHD_EXTERN_ enum MHD_StatusCode 5121 MHD_connection_get_info_fixed_sz ( 5122 struct MHD_Connection *MHD_RESTRICT connection, 5123 enum MHD_ConnectionInfoFixedType info_type, 5124 union MHD_ConnectionInfoFixedData *MHD_RESTRICT output_buf, 5125 size_t output_buf_size) 5126 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5127 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5128 5129 5130 /** 5131 * Obtain fixed information about the given connection. 5132 * This information is not changed for the lifetime of the connection. 5133 * 5134 * @param connection the connection to get information about 5135 * @param info_type the type of information requested 5136 * @param[out] output_buf the pointer to union to be set to the requested 5137 * information 5138 * @return #MHD_SC_OK if succeed, 5139 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5140 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5141 * is not available for this 5142 * connection due to the connection 5143 * configuration/mode, 5144 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5145 * should be available for 5146 * the connection, but cannot be 5147 * provided due to some error or 5148 * other reasons, 5149 * other error codes in case of other errors 5150 * @ingroup specialized 5151 */ 5152 #define MHD_connection_get_info_fixed(connection,info_type,output_buf) \ 5153 MHD_connection_get_info_fixed_sz ((connection),(info_type), \ 5154 (output_buf), sizeof(*(output_buf))) 5155 5156 5157 /** 5158 * Select which dynamic information about connection is desired. 5159 * This information may be changed during the lifetime of the connection. 5160 */ 5161 enum MHD_ConnectionInfoDynamicType 5162 { 5163 /** 5164 * Get current version of HTTP protocol used for connection. 5165 * If connection is handling HTTP/1.x requests the function may return 5166 * error code #MHD_SC_TOO_EARLY if the full request line has not been received 5167 * yet for the current request. 5168 * The result is placed in @a v_http_ver member. 5169 * @ingroup request 5170 */ 5171 MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER = 1 5172 , 5173 /** 5174 * Get connection timeout value. 5175 * This is the total number of milliseconds after which the idle 5176 * connection is automatically disconnected. 5177 * Note: the value set is NOT the number of milliseconds left before 5178 * automatic disconnection. 5179 * The result is placed in @a v_connection_timeout_uint32 member. 5180 * @ingroup request 5181 */ 5182 MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT_MILSEC = 10 5183 , 5184 /** 5185 * Check whether the connection is suspended. 5186 * The result is placed in @a v_connection_suspended_bool member. 5187 * @ingroup request 5188 */ 5189 MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED = 11 5190 , 5191 /** 5192 * Get current version of TLS transport protocol used for connection 5193 * If plain TCP connection is used then #MHD_TLS_VERSION_NO_TLS set in 5194 * the data. 5195 * It TLS handshake is not yet finished then error code #MHD_SC_TOO_EARLY is 5196 * returned. If TLS has failed or being closed then #MHD_SC_TOO_LATE error 5197 * code is returned. 5198 * If TLS version cannot be detected for any reason then error code 5199 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is returned. 5200 * The result is placed in @a v_tls_ver member. 5201 * @ingroup request 5202 */ 5203 MHD_CONNECTION_INFO_DYNAMIC_TLS_VER = 105 5204 , 5205 /** 5206 * Get the TLS backend session handle. 5207 * If plain TCP connection is used then the function returns error code 5208 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE. 5209 * The resulting union has only one valid member. 5210 * The result is placed in @a v_tls_session member. 5211 * @ingroup request 5212 */ 5213 MHD_CONNECTION_INFO_DYNAMIC_TLS_SESSION = 140 5214 , 5215 5216 /* * Sentinel * */ 5217 /** 5218 * The sentinel value. 5219 * This value enforces specific underlying integer type for the enum. 5220 * Do not use. 5221 */ 5222 MHD_CONNECTION_INFO_DYNAMIC_SENTINEL = 65535 5223 }; 5224 5225 5226 /** 5227 * The versions of TLS protocol 5228 */ 5229 enum MHD_FIXED_ENUM_MHD_SET_ MHD_TlsVersion 5230 { 5231 5232 /** 5233 * No TLS / plain socket connection 5234 */ 5235 MHD_TLS_VERSION_NO_TLS = 0 5236 , 5237 /** 5238 * Not supported/failed to negotiate/failed to handshake TLS 5239 */ 5240 MHD_TLS_VERSION_BROKEN = 1 5241 , 5242 /** 5243 * TLS version 1.0 5244 */ 5245 MHD_TLS_VERSION_1_0 = 2 5246 , 5247 /** 5248 * TLS version 1.1 5249 */ 5250 MHD_TLS_VERSION_1_1 = 3 5251 , 5252 /** 5253 * TLS version 1.2 5254 */ 5255 MHD_TLS_VERSION_1_2 = 4 5256 , 5257 /** 5258 * TLS version 1.3 5259 */ 5260 MHD_TLS_VERSION_1_3 = 5 5261 , 5262 /** 5263 * Some unknown TLS version. 5264 * The TLS version is supported by TLS backend, but unknown to MHD. 5265 */ 5266 MHD_TLS_VERSION_UNKNOWN = 1999 5267 }; 5268 5269 /** 5270 * Connection TLS session information. 5271 * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out 5272 * which member should be used. 5273 */ 5274 union MHD_ConnInfoDynamicTlsSess 5275 { 5276 /* Include <gnutls/gnutls.h> before this header to get a better type safety */ 5277 /** 5278 * GnuTLS session handle, of type "gnutls_session_t". 5279 */ 5280 #if defined(GNUTLS_VERSION_MAJOR) && GNUTLS_VERSION_MAJOR >= 3 5281 gnutls_session_t v_gnutls_session; 5282 #else 5283 void * /* gnutls_session_t */ v_gnutls_session; 5284 #endif 5285 5286 /* Include <openssl/types.h> or <openssl/crypto.h> before this header to get 5287 a better type safety */ 5288 /** 5289 * OpenSSL session handle, of type "SSL*". 5290 */ 5291 #if defined(OPENSSL_TYPES_H) && OPENSSL_VERSION_MAJOR >= 3 5292 SSL *v_openssl_session; 5293 #else 5294 void /* SSL */ *v_openssl_session; 5295 #endif 5296 5297 /* Include <mbedtls/ssl.h> before this header to get a better type safety */ 5298 /** 5299 * MbedTLS session handle, of type "mbedtls_ssl_context*". 5300 */ 5301 #if defined(MBEDTLS_SSL_H) 5302 mbedtls_ssl_context *v_mbedtls_session; 5303 #else 5304 void /* mbedtls_ssl_context */ *v_mbedtls_session; 5305 #endif 5306 }; 5307 5308 /** 5309 * Information about a connection. 5310 */ 5311 union MHD_ConnectionInfoDynamicData 5312 { 5313 /** 5314 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER query 5315 */ 5316 enum MHD_HTTP_ProtocolVersion v_http_ver; 5317 5318 /** 5319 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT_MILSEC 5320 * query 5321 */ 5322 uint_fast32_t v_connection_timeout_uint32; 5323 5324 /** 5325 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query 5326 */ 5327 enum MHD_Bool v_connection_suspended_bool; 5328 5329 /** 5330 * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query 5331 */ 5332 enum MHD_TlsVersion v_tls_ver; 5333 5334 /** 5335 * Connection TLS session information. 5336 * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out 5337 * which member should be used. 5338 */ 5339 union MHD_ConnInfoDynamicTlsSess v_tls_session; 5340 }; 5341 5342 /** 5343 * Obtain dynamic information about the given connection. 5344 * This information may be changed during the lifetime of the connection. 5345 * 5346 * The wrapper macro #MHD_connection_get_info_dynamic() may be more convenient. 5347 * 5348 * @param connection the connection to get information about 5349 * @param info_type the type of information requested 5350 * @param[out] output_buf the pointer to union to be set to the requested 5351 * information 5352 * @param output_buf_size the size of the memory area pointed by @a output_buf 5353 * (provided by the caller for storing the requested 5354 * information), in bytes 5355 * @return #MHD_SC_OK if succeed, 5356 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5357 * #MHD_SC_TOO_EARLY if the connection has not reached yet required 5358 * state, 5359 * #MHD_SC_TOO_LATE if the connection is already in state where 5360 * the requested information is not available, 5361 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5362 * is not available for this 5363 * connection due to the connection 5364 * configuration/mode, 5365 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5366 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5367 * should be available for 5368 * the connection, but cannot be 5369 * provided due to some error or 5370 * other reasons, 5371 * other error codes in case of other errors 5372 * @ingroup specialized 5373 */ 5374 MHD_EXTERN_ enum MHD_StatusCode 5375 MHD_connection_get_info_dynamic_sz ( 5376 struct MHD_Connection *MHD_RESTRICT connection, 5377 enum MHD_ConnectionInfoDynamicType info_type, 5378 union MHD_ConnectionInfoDynamicData *MHD_RESTRICT output_buf, 5379 size_t output_buf_size) 5380 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5381 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5382 5383 5384 /** 5385 * Obtain dynamic information about the given connection. 5386 * This information may be changed during the lifetime of the connection. 5387 * 5388 * @param connection the connection to get information about 5389 * @param info_type the type of information requested 5390 * @param[out] output_buf the pointer to union to be set to the requested 5391 * information 5392 * @return #MHD_SC_OK if succeed, 5393 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5394 * #MHD_SC_TOO_EARLY if the connection has not reached yet required 5395 * state, 5396 * #MHD_SC_TOO_LATE if the connection is already in state where 5397 * the requested information is not available, 5398 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information 5399 * is not available for this 5400 * connection due to the connection 5401 * configuration/mode, 5402 * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information 5403 * should be available for 5404 * the connection, but cannot be 5405 * provided due to some error or 5406 * other reasons, 5407 * other error codes in case of other errors 5408 * @ingroup specialized 5409 */ 5410 #define MHD_connection_get_info_dynamic(connection,info_type,output_buf) \ 5411 MHD_connection_get_info_dynamic_sz ((connection),(info_type), \ 5412 (output_buf),sizeof(*(output_buf))) 5413 5414 5415 /** 5416 * Select which fixed information about stream is desired. 5417 * This information is not changed during the lifetime of the connection. 5418 */ 5419 enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoFixedType 5420 { 5421 /** 5422 * Get the `struct MHD_Daemon *` responsible for managing connection which 5423 * is responsible for this stream. 5424 * The result is placed in @a v_daemon member. 5425 * @ingroup request 5426 */ 5427 MHD_STREAM_INFO_FIXED_DAEMON = 20 5428 , 5429 /** 5430 * Get the `struct MHD_Connection *` responsible for managing this stream. 5431 * The result is placed in @a v_connection member. 5432 * @ingroup request 5433 */ 5434 MHD_STREAM_INFO_FIXED_CONNECTION = 21 5435 , 5436 5437 /* * Sentinel * */ 5438 /** 5439 * The sentinel value. 5440 * This value enforces specific underlying integer type for the enum. 5441 * Do not use. 5442 */ 5443 MHD_STREAM_INFO_FIXED_SENTINEL = 65535 5444 }; 5445 5446 5447 /** 5448 * Fixed information about a stream. 5449 */ 5450 union MHD_StreamInfoFixedData 5451 { 5452 /** 5453 * The data for the #MHD_STREAM_INFO_FIXED_DAEMON query 5454 */ 5455 struct MHD_Daemon *v_daemon; 5456 /** 5457 * The data for the #MHD_STREAM_INFO_FIXED_CONNECTION query 5458 */ 5459 struct MHD_Connection *v_connection; 5460 }; 5461 5462 5463 /** 5464 * Obtain fixed information about the given stream. 5465 * This information is not changed for the lifetime of the stream. 5466 * 5467 * The wrapper macro #MHD_stream_get_info_fixed() may be more convenient. 5468 * 5469 * @param stream the stream to get information about 5470 * @param info_type the type of information requested 5471 * @param[out] output_buf the pointer to union to be set to the requested 5472 * information 5473 * @param output_buf_size the size of the memory area pointed by @a output_buf 5474 * (provided by the caller for storing the requested 5475 * information), in bytes 5476 * @return #MHD_SC_OK if succeed, 5477 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5478 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5479 * other error codes in case of other errors 5480 * @ingroup specialized 5481 */ 5482 MHD_EXTERN_ enum MHD_StatusCode 5483 MHD_stream_get_info_fixed_sz ( 5484 struct MHD_Stream *MHD_RESTRICT stream, 5485 enum MHD_StreamInfoFixedType info_type, 5486 union MHD_StreamInfoFixedData *MHD_RESTRICT output_buf, 5487 size_t output_buf_size) 5488 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5489 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5490 5491 5492 /** 5493 * Obtain fixed information about the given stream. 5494 * This information is not changed for the lifetime of the tream. 5495 * 5496 * @param stream the stream to get information about 5497 * @param info_type the type of information requested 5498 * @param[out] output_buf the pointer to union to be set to the requested 5499 * information 5500 * @return #MHD_SC_OK if succeed, 5501 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5502 * other error codes in case of other errors 5503 * @ingroup specialized 5504 */ 5505 #define MHD_stream_get_info_fixed(stream,info_type,output_buf) \ 5506 MHD_stream_get_info_fixed_sz ((stream),(info_type),(output_buf), \ 5507 sizeof(*(output_buf))) 5508 5509 5510 /** 5511 * Select which fixed information about stream is desired. 5512 * This information may be changed during the lifetime of the stream. 5513 */ 5514 enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoDynamicType 5515 { 5516 /** 5517 * Get the `struct MHD_Request *` for current request processed by the stream. 5518 * If no request is being processed, the error code #MHD_SC_TOO_EARLY is 5519 * returned. 5520 * The result is placed in @a v_request member. 5521 * @ingroup request 5522 */ 5523 MHD_STREAM_INFO_DYNAMIC_REQUEST = 20 5524 , 5525 5526 /* * Sentinel * */ 5527 /** 5528 * The sentinel value. 5529 * This value enforces specific underlying integer type for the enum. 5530 * Do not use. 5531 */ 5532 MHD_STREAM_INFO_DYNAMIC_SENTINEL = 65535 5533 }; 5534 5535 5536 /** 5537 * Dynamic information about stream. 5538 * This information may be changed during the lifetime of the connection. 5539 */ 5540 union MHD_StreamInfoDynamicData 5541 { 5542 /** 5543 * The data for the #MHD_STREAM_INFO_DYNAMIC_REQUEST query 5544 */ 5545 struct MHD_Request *v_request; 5546 }; 5547 5548 /** 5549 * Obtain dynamic information about the given stream. 5550 * This information may be changed during the lifetime of the stream. 5551 * 5552 * The wrapper macro #MHD_stream_get_info_dynamic() may be more convenient. 5553 * 5554 * @param stream the stream to get information about 5555 * @param info_type the type of information requested 5556 * @param[out] output_buf the pointer to union to be set to the requested 5557 * information 5558 * @param output_buf_size the size of the memory area pointed by @a output_buf 5559 * (provided by the caller for storing the requested 5560 * information), in bytes 5561 * @return #MHD_SC_OK if succeed, 5562 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5563 * #MHD_SC_TOO_EARLY if the stream has not reached yet required state, 5564 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5565 * other error codes in case of other errors 5566 * @ingroup specialized 5567 */ 5568 MHD_EXTERN_ enum MHD_StatusCode 5569 MHD_stream_get_info_dynamic_sz ( 5570 struct MHD_Stream *MHD_RESTRICT stream, 5571 enum MHD_StreamInfoDynamicType info_type, 5572 union MHD_StreamInfoDynamicData *MHD_RESTRICT output_buf, 5573 size_t output_buf_size) 5574 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5575 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5576 5577 5578 /** 5579 * Obtain dynamic information about the given stream. 5580 * This information may be changed during the lifetime of the stream. 5581 * 5582 * @param stream the stream to get information about 5583 * @param info_type the type of information requested 5584 * @param[out] output_buf the pointer to union to be set to the requested 5585 * information 5586 * @return #MHD_SC_OK if succeed, 5587 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5588 * #MHD_SC_TOO_EARLY if the stream has not reached yet required state, 5589 * other error codes in case of other errors 5590 * @ingroup specialized 5591 */ 5592 #define MHD_stream_get_info_dynamic(stream,info_type,output_buf) \ 5593 MHD_stream_get_info_dynamic_sz ((stream),(info_type),(output_buf), \ 5594 sizeof(*(output_buf))) 5595 5596 5597 /** 5598 * Select which fixed information about request is desired. 5599 * This information is not changed during the lifetime of the request. 5600 */ 5601 enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoFixedType 5602 { 5603 /** 5604 * Get the version of HTTP protocol used for the request. 5605 * If request line has not been fully received yet then #MHD_SC_TOO_EARLY 5606 * error code is returned. 5607 * The result is placed in @a v_http_ver member. 5608 * @ingroup request 5609 */ 5610 MHD_REQUEST_INFO_FIXED_HTTP_VER = 1 5611 , 5612 /** 5613 * Get the HTTP method used for the request (as a enum). 5614 * The result is placed in @a v_http_method member. 5615 * @sa #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR 5616 * @ingroup request 5617 */ 5618 MHD_REQUEST_INFO_FIXED_HTTP_METHOD = 2 5619 , 5620 /** 5621 * Return MHD daemon to which the request belongs to. 5622 * The result is placed in @a v_daemon member. 5623 */ 5624 MHD_REQUEST_INFO_FIXED_DAEMON = 20 5625 , 5626 /** 5627 * Return which connection is associated with the stream which is associated 5628 * with the request. 5629 * The result is placed in @a v_connection member. 5630 */ 5631 MHD_REQUEST_INFO_FIXED_CONNECTION = 21 5632 , 5633 /** 5634 * Return which stream the request is associated with. 5635 * The result is placed in @a v_stream member. 5636 */ 5637 MHD_REQUEST_INFO_FIXED_STREAM = 22 5638 , 5639 /** 5640 * Returns the pointer to a variable pointing to request-specific 5641 * application context data. The same data is provided for 5642 * #MHD_EarlyUriLogCallback and #MHD_RequestTerminationCallback. 5643 * By using provided pointer application may get or set the pointer to 5644 * any data specific for the particular request. 5645 * Note: resulting data is NOT the context pointer itself. 5646 * The result is placed in @a v_app_context_ppvoid member. 5647 * @ingroup request 5648 */ 5649 MHD_REQUEST_INFO_FIXED_APP_CONTEXT = 30 5650 , 5651 5652 /* * Sentinel * */ 5653 /** 5654 * The sentinel value. 5655 * This value enforces specific underlying integer type for the enum. 5656 * Do not use. 5657 */ 5658 MHD_REQUEST_INFO_FIXED_SENTINEL = 65535 5659 }; 5660 5661 5662 /** 5663 * Fixed information about a request. 5664 */ 5665 union MHD_RequestInfoFixedData 5666 { 5667 5668 /** 5669 * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_VER query 5670 */ 5671 enum MHD_HTTP_ProtocolVersion v_http_ver; 5672 5673 /** 5674 * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_METHOD query 5675 */ 5676 enum MHD_HTTP_Method v_http_method; 5677 5678 /** 5679 * The data for the #MHD_REQUEST_INFO_FIXED_DAEMON query 5680 */ 5681 struct MHD_Daemon *v_daemon; 5682 5683 /** 5684 * The data for the #MHD_REQUEST_INFO_FIXED_CONNECTION query 5685 */ 5686 struct MHD_Connection *v_connection; 5687 5688 /** 5689 * The data for the #MHD_REQUEST_INFO_FIXED_STREAM query 5690 */ 5691 struct MHD_Stream *v_stream; 5692 5693 /** 5694 * The data for the #MHD_REQUEST_INFO_FIXED_APP_CONTEXT query 5695 */ 5696 void **v_app_context_ppvoid; 5697 }; 5698 5699 /** 5700 * Obtain fixed information about the given request. 5701 * This information is not changed for the lifetime of the request. 5702 * 5703 * The wrapper macro #MHD_request_get_info_fixed() may be more convenient. 5704 * 5705 * @param request the request to get information about 5706 * @param info_type the type of information requested 5707 * @param[out] output_buf the pointer to union to be set to the requested 5708 * information 5709 * @param output_buf_size the size of the memory area pointed by @a output_buf 5710 * (provided by the caller for storing the requested 5711 * information), in bytes 5712 * @return #MHD_SC_OK if succeed, 5713 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5714 * #MHD_SC_TOO_EARLY if the request processing has not reached yet 5715 * the required state, 5716 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 5717 * other error codes in case of other errors 5718 * @ingroup specialized 5719 */ 5720 MHD_EXTERN_ enum MHD_StatusCode 5721 MHD_request_get_info_fixed_sz ( 5722 struct MHD_Request *MHD_RESTRICT request, 5723 enum MHD_RequestInfoFixedType info_type, 5724 union MHD_RequestInfoFixedData *MHD_RESTRICT output_buf, 5725 size_t output_buf_size) 5726 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 5727 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 5728 5729 5730 /** 5731 * Obtain fixed information about the given request. 5732 * This information is not changed for the lifetime of the request. 5733 * 5734 * @param request the request to get information about 5735 * @param info_type the type of information requested 5736 * @param[out] output_buf the pointer to union to be set to the requested 5737 * information 5738 * @return #MHD_SC_OK if succeed, 5739 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown, 5740 * #MHD_SC_TOO_EARLY if the request processing has not reached yet 5741 * the required state, 5742 * other error codes in case of other errors 5743 * @ingroup specialized 5744 */ 5745 #define MHD_request_get_info_fixed(request,info_type,output_buf) \ 5746 MHD_request_get_info_fixed_sz ((request), (info_type), (output_buf), \ 5747 sizeof(*(output_buf))) 5748 5749 5750 /** 5751 * Select which dynamic information about request is desired. 5752 * This information may be changed during the lifetime of the request. 5753 * Any returned string pointers are valid only until a response is provided. 5754 */ 5755 enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoDynamicType 5756 { 5757 /** 5758 * Get the HTTP method used for the request (as a MHD_String). 5759 * The resulting string pointer in valid only until a response is provided. 5760 * The result is placed in @a v_http_method_string member. 5761 * @sa #MHD_REQUEST_INFO_FIXED_HTTP_METHOD 5762 * @ingroup request 5763 */ 5764 MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING = 1 5765 , 5766 /** 5767 * Get the URI used for the request (as a MHD_String), excluding 5768 * the parameter part (anything after '?'). 5769 * The resulting string pointer in valid only until a response is provided. 5770 * The result is placed in @a v_uri_string member. 5771 * @ingroup request 5772 */ 5773 MHD_REQUEST_INFO_DYNAMIC_URI = 2 5774 , 5775 /** 5776 * Get the number of URI parameters (the decoded part of the original 5777 * URI string after '?'). Sometimes it is called "GET parameters". 5778 * The result is placed in @a v_number_uri_params_sizet member. 5779 * @ingroup request 5780 */ 5781 MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS = 3 5782 , 5783 /** 5784 * Get the number of cookies in the request. 5785 * The result is placed in @a v_number_cookies_sizet member. 5786 * If cookies parsing is disabled in MHD build then the function returns 5787 * error code #MHD_SC_FEATURE_DISABLED. 5788 * If cookies parsing is disabled this daemon then the function returns 5789 * error code #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE. 5790 * @ingroup request 5791 */ 5792 MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES = 4 5793 , 5794 /** 5795 * Return length of the client's HTTP request header. 5796 * This is a total raw size of the header (after TLS decipher if any) 5797 * The result is placed in @a v_header_size_sizet member. 5798 * @ingroup request 5799 */ 5800 MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE = 5 5801 , 5802 /** 5803 * Get the number of decoded POST entries in the request. 5804 * The result is placed in @a v_number_post_params_sizet member. 5805 * @ingroup request 5806 */ 5807 MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS = 6 5808 , 5809 /** 5810 * Get whether the upload content is present in the request. 5811 * The result is #MHD_YES if any upload content is present, even 5812 * if the upload content size is zero. 5813 * The result is placed in @a v_upload_present_bool member. 5814 * @ingroup request 5815 */ 5816 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT = 10 5817 , 5818 /** 5819 * Get whether the chunked upload content is present in the request. 5820 * The result is #MHD_YES if chunked upload content is present. 5821 * The result is placed in @a v_upload_chunked_bool member. 5822 * @ingroup request 5823 */ 5824 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED = 11 5825 , 5826 /** 5827 * Get the total content upload size. 5828 * Resulted in zero if no content upload or upload content size is zero, 5829 * #MHD_SIZE_UNKNOWN if size is not known (chunked upload). 5830 * The result is placed in @a v_upload_size_total_uint64 member. 5831 * @ingroup request 5832 */ 5833 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL = 12 5834 , 5835 /** 5836 * Get the total size of the content upload already received from the client. 5837 * This is the total size received, could be not yet fully processed by the 5838 * application. 5839 * The result is placed in @a v_upload_size_recieved_uint64 member. 5840 * @ingroup request 5841 */ 5842 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED = 13 5843 , 5844 /** 5845 * Get the total size of the content upload left to be received from 5846 * the client. 5847 * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload). 5848 * The result is placed in @a v_upload_size_to_recieve_uint64 member. 5849 * @ingroup request 5850 */ 5851 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE = 14 5852 , 5853 /** 5854 * Get the total size of the content upload already processed (upload callback 5855 * called and completed (if any)). 5856 * If the value is requested from #MHD_UploadCallback, then result does NOT 5857 * include the current data being processed by the callback. 5858 * The result is placed in @a v_upload_size_processed_uint64 member. 5859 * @ingroup request 5860 */ 5861 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED = 15 5862 , 5863 /** 5864 * Get the total size of the content upload left to be processed. 5865 * The resulting value includes the size of the data not yet received from 5866 * the client. 5867 * If the value is requested from #MHD_UploadCallback, then result includes 5868 * the current data being processed by the callback. 5869 * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload). 5870 * The result is placed in @a v_upload_size_to_process_uint64 member. 5871 * @ingroup request 5872 */ 5873 MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS = 16 5874 , 5875 /** 5876 * Returns pointer to information about digest auth in client request. 5877 * The resulting pointer is NULL if no digest auth header is set by 5878 * the client or the format of the digest auth header is broken. 5879 * Pointers in the returned structure (if any) are valid until response 5880 * is provided for the request. 5881 * The result is placed in @a v_auth_digest_info member. 5882 */ 5883 MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO = 42 5884 , 5885 /** 5886 * Returns information about Basic Authentication credentials in the request. 5887 * Pointers in the returned structure (if any) are valid until any MHD_Action 5888 * or MHD_UploadAction is provided. If the data is needed beyond this point, 5889 * it should be copied. 5890 * If #MHD_request_get_info_dynamic_sz() returns #MHD_SC_OK then 5891 * @a v_auth_basic_creds is NOT NULL and at least the username data 5892 * is provided. 5893 * The result is placed in @a v_auth_basic_creds member. 5894 */ 5895 MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS = 51 5896 , 5897 /* * Sentinel * */ 5898 /** 5899 * The sentinel value. 5900 * This value enforces specific underlying integer type for the enum. 5901 * Do not use. 5902 */ 5903 MHD_REQUEST_INFO_DYNAMIC_SENTINEL = 65535 5904 }; 5905 5906 5907 /** 5908 * Dynamic information about a request. 5909 */ 5910 union MHD_RequestInfoDynamicData 5911 { 5912 5913 /** 5914 * The data for the #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING query 5915 */ 5916 struct MHD_String v_http_method_string; 5917 5918 /** 5919 * The data for the #MHD_REQUEST_INFO_DYNAMIC_URI query 5920 */ 5921 struct MHD_String v_uri_string; 5922 5923 /** 5924 * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS query 5925 */ 5926 size_t v_number_uri_params_sizet; 5927 5928 /** 5929 * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES query 5930 */ 5931 size_t v_number_cookies_sizet; 5932 5933 /** 5934 * The data for the #MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE query 5935 */ 5936 size_t v_header_size_sizet; 5937 5938 /** 5939 * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS query 5940 */ 5941 size_t v_number_post_params_sizet; 5942 5943 /** 5944 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT query 5945 */ 5946 enum MHD_Bool v_upload_present_bool; 5947 5948 /** 5949 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED query 5950 */ 5951 enum MHD_Bool v_upload_chunked_bool; 5952 5953 /** 5954 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL query 5955 */ 5956 uint_fast64_t v_upload_size_total_uint64; 5957 5958 /** 5959 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED query 5960 */ 5961 uint_fast64_t v_upload_size_recieved_uint64; 5962 5963 /** 5964 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE query 5965 */ 5966 uint_fast64_t v_upload_size_to_recieve_uint64; 5967 5968 /** 5969 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED query 5970 */ 5971 uint_fast64_t v_upload_size_processed_uint64; 5972 5973 /** 5974 * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS query 5975 */ 5976 uint_fast64_t v_upload_size_to_process_uint64; 5977 5978 /** 5979 * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO query 5980 */ 5981 const struct MHD_AuthDigestInfo *v_auth_digest_info; 5982 5983 /** 5984 * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS query 5985 */ 5986 const struct MHD_AuthBasicCreds *v_auth_basic_creds; 5987 }; 5988 5989 5990 /** 5991 * Obtain dynamic information about the given request. 5992 * This information may be changed during the lifetime of the request. 5993 * Most of the data provided is available only when the request line or complete 5994 * request headers are processed and not available if responding has been 5995 * started. 5996 * 5997 * The wrapper macro #MHD_request_get_info_dynamic() may be more convenient. 5998 * 5999 * Any pointers in the returned data are valid until any MHD_Action or 6000 * MHD_UploadAction is provided. If the data is needed beyond this point, 6001 * it should be copied. 6002 * 6003 * @param request the request to get information about 6004 * @param info_type the type of information requested 6005 * @param[out] output_buf the pointer to union to be set to the requested 6006 * information 6007 * @param output_buf_size the size of the memory area pointed by @a output_buf 6008 * (provided by the caller for storing the requested 6009 * information), in bytes 6010 * @return #MHD_SC_OK if succeed, 6011 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is 6012 * not recognized by MHD, 6013 * #MHD_SC_TOO_LATE if request is already being closed or the response 6014 * is being sent 6015 * #MHD_SC_TOO_EARLY if requested data is not yet ready (for example, 6016 * headers are not yet received), 6017 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is 6018 * not available for this request 6019 * due to used configuration/mode, 6020 * #MHD_SC_FEATURE_DISABLED if requested functionality is not supported 6021 * by this MHD build, 6022 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small, 6023 * #MHD_SC_AUTH_ABSENT if request does not have particular Auth data, 6024 * #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool 6025 * has no space to put decoded 6026 * authentication data, 6027 * #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is 6028 * incorrect or broken, 6029 * other error codes in case of other errors 6030 * @ingroup specialized 6031 */ 6032 MHD_EXTERN_ enum MHD_StatusCode 6033 MHD_request_get_info_dynamic_sz ( 6034 struct MHD_Request *MHD_RESTRICT request, 6035 enum MHD_RequestInfoDynamicType info_type, 6036 union MHD_RequestInfoDynamicData *MHD_RESTRICT output_buf, 6037 size_t output_buf_size) 6038 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1) 6039 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3); 6040 6041 6042 /** 6043 * Obtain dynamic information about the given request. 6044 * This information may be changed during the lifetime of the request. 6045 * Most of the data provided is available only when the request line or complete 6046 * request headers are processed and not available if responding has been 6047 * started. 6048 * 6049 * Any pointers in the returned data are valid until any MHD_Action or 6050 * MHD_UploadAction is provided. If the data is needed beyond this point, 6051 * it should be copied. 6052 * 6053 * @param request the request to get information about 6054 * @param info_type the type of information requested 6055 * @param[out] output_buf the pointer to union to be set to the requested 6056 * information 6057 * @return #MHD_SC_OK if succeed, 6058 * #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is 6059 * not recognized by MHD, 6060 * #MHD_SC_TOO_LATE if request is already being closed or the response 6061 * is being sent 6062 * #MHD_SC_TOO_EARLY if requested data is not yet ready (for example, 6063 * headers are not yet received), 6064 * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is 6065 * not available for this request 6066 * due to used configuration/mode, 6067 * #MHD_SC_FEATURE_DISABLED if requested functionality is not supported 6068 * by this MHD build, 6069 * #MHD_SC_AUTH_ABSENT if request does not have particular Auth data, 6070 * #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool 6071 * has no space to put decoded 6072 * authentication data, 6073 * #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is 6074 * incorrect or broken, 6075 * other error codes in case of other errors 6076 * @ingroup specialized 6077 */ 6078 #define MHD_request_get_info_dynamic(request,info_type,output_buf) \ 6079 MHD_request_get_info_dynamic_sz ((request), (info_type), \ 6080 (output_buf), \ 6081 sizeof(*(output_buf))) 6082 6083 /** 6084 * Callback for serious error condition. The default action is to print 6085 * an error message and `abort()`. 6086 * The callback should not return. 6087 * Some parameters could be empty strings (the strings with zero-termination at 6088 * zero position) if MHD built without log messages (only for embedded 6089 * projects). 6090 * 6091 * @param cls user specified value 6092 * @param file where the error occurred, could be empty 6093 * @param func the name of the function, where the error occurred, may be empty 6094 * @param line where the error occurred 6095 * @param message the error details, could be empty 6096 * @ingroup logging 6097 */ 6098 typedef void 6099 (*MHD_PanicCallback) (void *cls, 6100 const char *file, 6101 const char *func, 6102 unsigned int line, 6103 const char *message); 6104 6105 6106 /** 6107 * Sets the global error handler to a different implementation. 6108 * The @a cb will only be called in the case of typically fatal, serious 6109 * internal consistency issues. 6110 * These issues should only arise in the case of serious memory corruption or 6111 * similar problems with the architecture. 6112 * The @a cb should not return. 6113 * 6114 * The default implementation that is used if no panic function is set 6115 * simply prints an error message and calls `abort()`. Alternative 6116 * implementations might call `exit()` or other similar functions. 6117 * 6118 * @param cb new error handler, NULL to reset to default handler 6119 * @param cls passed to @a cb 6120 * @ingroup logging 6121 */ 6122 MHD_EXTERN_ void 6123 MHD_lib_set_panic_func (MHD_PanicCallback cb, 6124 void *cls); 6125 6126 #define MHD_lib_set_panic_func_default() \ 6127 MHD_lib_set_panic_func (MHD_STATIC_CAST_ (MHD_PanicCallback,NULL),NULL)