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