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