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