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