Coverage Report

Created: 2025-10-13 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mhd2/src/include/microhttpd2.h
Line
Count
Source
1
/* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
2
/*
3
  This file is part of GNU libmicrohttpd.
4
  Copyright (C) 2006-2025 Christian Grothoff, Karlson2k (Evgeny Grin)
5
  (and other contributing authors)
6
7
  GNU libmicrohttpd is free software; you can redistribute it and/or
8
  modify it under the terms of the GNU Lesser General Public
9
  License as published by the Free Software Foundation; either
10
  version 2.1 of the License, or (at your option) any later version.
11
12
  GNU libmicrohttpd is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
  Lesser General Public License for more details.
16
17
  Alternatively, you can redistribute GNU libmicrohttpd and/or
18
  modify it under the terms of the GNU General Public License as
19
  published by the Free Software Foundation; either version 2 of
20
  the License, or (at your option) any later version, together
21
  with the eCos exception, as follows:
22
23
    As a special exception, if other files instantiate templates or
24
    use macros or inline functions from this file, or you compile this
25
    file and link it with other works to produce a work based on this
26
    file, this file does not by itself cause the resulting work to be
27
    covered by the GNU General Public License. However the source code
28
    for this file must still be made available in accordance with
29
    section (3) of the GNU General Public License v2.
30
31
    This exception does not invalidate any other reasons why a work
32
    based on this file might be covered by the GNU General Public
33
    License.
34
35
  You should have received copies of the GNU Lesser General Public
36
  License and the GNU General Public License along with this library;
37
  if not, see <https://www.gnu.org/licenses/>.
38
*/
39
40
/*
41
  Main goals for the libmicrohttpd 2.0 API:
42
43
  - simplify application callbacks by splitting header/upload/post
44
    functionality currently provided by calling the same
45
    MHD_AccessHandlerCallback 3+ times into separate callbacks.
46
  - keep the API very simple for simple requests, but allow
47
    more complex logic to be incrementally introduced
48
    (via new struct MHD_Action construction)
49
  - avoid repeated scans for URL matches via the new
50
    struct MHD_Action construction
51
  - better types, in particular avoid varargs for options
52
  - make it harder to pass inconsistent options
53
  - combine options and flags into more uniform API (at least
54
    exterally!)
55
  - simplify API use by using sane defaults (benefiting from
56
    breaking backwards compatibility) and making all options
57
    really optional, and where applicable avoid having options
58
    where the default works if nothing is specified
59
  - simplify API by moving rarely used http_version into
60
    MHD_request_get_info_fixed()
61
  - avoid 'int' for MHD_YES/MHD_NO by introducing `enum MHD_Bool`
62
  - improve terminology by eliminating confusion between
63
    'request' and 'connection'; add 'session' for HTTP2/3;
64
    use clear separation between connection and request. Do not mix the kind
65
    data in the callbacks.  Currently we are mixing things in
66
    MHD_AccessHandlerCallback and MHD_RequestCompletedCallback. Instead of
67
    pointers to struct MHD_Connection we should use pointers to (new) struct
68
    MHD_Request.
69
  - prepare API for having multiple TLS backends
70
  - use more consistent prefixes for related functions
71
    by using MHD_subject_verb_object naming convention, also
72
    at the same time avoid symbol conflict with legacy names
73
    (so we can have one binary implementing old and new
74
    library API at the same time via compatibility layer).
75
  - make it impossible to queue a response at the wrong time
76
  - make it impossible to suspend a connection/request at the
77
    wrong time (improves thread-safety)
78
  - make it clear which response status codes are "properly"
79
    supported (include the descriptive string) by using an enum;
80
  - simplify API for common-case of one-shot responses by
81
    eliminating need for destroy response in most cases;
82
  - avoid fixed types, like uint32_t. They may not exist on some
83
    platforms. Instead use uint_fast32_t.
84
    It is also better for future-proof.
85
  - check portability for embedded platforms. Some of them support
86
    64 bits, but 'int' could be just 16 bits resulting of silently
87
    dropping enum values higher than 65535.
88
    => in general, more functions, fewer enums for setup
89
  - Avoid returning pointers to internal members. It is not thread-safe and
90
    even in single thread the value could change over the time. Prefer pointers to
91
    app-allocated memory with the size, like MHD_daemon_get_static_info(enum
92
    MHD_enum_name info_type, void *buf, size_t buf_size).
93
    => Except in cases where zero-copy matters.
94
  - Use separate app calls/functions for data the will not change for the
95
    lifetime of the object and dynamic data. The only difference should be the
96
    name. Like MHD_daemon_get_static_info(enum MHD_enum_name info_type, void *buf,
97
    size_t buf_size) MHD_daemon_get_dynamic_info(enum MHD_enum_name info_type,
98
    void *buf, size_t buf_size) Examples of static data: listen socket, number of
99
    workers, daemon flags.  Examples of dynamic data: number of connections,
100
    quiesce status.  It should give a clear idea whether the data could be changed
101
    over the time (could be not obvious for some data) and thus may change the
102
    approach how to use the data in app.  The same for: library, daemon,
103
    connection, request. Not sure that dynamic data makes sense for the library.
104
  - Define response code in response object. There are a very little
105
    chance that response body designed for 404 or 403 codes will be used with
106
    200 code. However, the responses body for 307 and 308 could be the same. So:
107
    Add default response code in response object.
108
  - Make responses unmodifiable after first use. It is not thread-safe.
109
    MHD-generated headers (Date, Connection/Keep-Alive) are again
110
    part of the *request* and do not count as part of the "response" here.
111
  - Remove "footers" from responses. With unmodifiable responses everything should
112
    be "headers". Add footers to *requests* instead.
113
  - Add API for adding request-specific response headers and footers. To
114
    simplify the things it should just copy the strings (to avoid dealing with
115
    complicated deinit of possible dynamic strings).  After this change it should
116
    be possible to simplify DAuth handling as response could be reused (currently
117
    403 responses are modified for each reply).
118
  - Control response behaviour mainly by response flags, not by additional
119
    headers (like MHD_RF_FORCE_CLOSE instead of "Connection: close").
120
    It is easier&faster for both: app and MHD.
121
  - Move response codes from MHD_HTTP_xxx namespace to MHD_HTTP_CODE_xxx
122
    namespace. It already may clash with other HTTP values.
123
  - Postprocessor is unusable night-mare when doing "stream processing"
124
    for tiny values where the application basically has to copy together
125
    the stream back into a single compact heap value, just making the
126
    parsing highly more complicated (see examples in Challenger)
127
  - non-stream processing variant for request bodies, give apps a
128
    way to request the full body in one buffer; give apps a way
129
    to request a 'large new allocation' for such buffers; give apps
130
    a way to specify a global quota for large allocations to ensure
131
    memory usage has a hard bound
132
133
  - Internals: carefully check where locking is really required. Probably
134
    separate locks. Check out-of-thread value reading. Currently code assumes
135
    atomic reading of values used in other threads, which mostly true on x86,
136
    but not OK on other arches. Probably use read/write locking to minimize
137
    the threads interference.
138
  - Internals: figure out how to do portable variant of cork/uncork
139
  - Internals: remove request data from memory pool when response is queued
140
    (IF no callbacks and thus data cannot be used anymore, or IF
141
     application permits explicitly per daemon) to get more space
142
    for building response;
143
  - Internals: Fix TCP FIN graceful closure issue for upgraded
144
    connections (API implications?)
145
146
*/
147
148
#ifndef MICROHTTPD2_H
149
#define MICROHTTPD2_H
150
151
#ifndef __cplusplus
152
#  define MHD_C_DECLRATIONS_START_HERE_   /* Empty */
153
#  define MHD_C_DECLRATIONS_FINISH_HERE_  /* Empty */
154
#else  /* __cplusplus */
155
/* *INDENT-OFF* */
156
#  define MHD_C_DECLRATIONS_START_HERE_   extern "C" {
157
#  define MHD_C_DECLRATIONS_FINISH_HERE_  }
158
/* *INDENT-ON* */
159
#endif /* __cplusplus */
160
161
MHD_C_DECLRATIONS_START_HERE_
162
163
/**
164
 * Current version of the library in packed BCD form.
165
 * (For example, version 1.9.30-1 would be 0x01093001)
166
 */
167
#define MHD_VERSION 0x01990001
168
169
#include "microhttpd2_portability.h"
170
171
/* If generic headers do not work on your platform, include headers that
172
   define 'va_list', 'size_t', 'uint_least16_t', 'uint_fast32_t',
173
   'uint_fast64_t', and 'struct sockaddr', and then
174
   add "#define MHD_HAVE_SYS_HEADERS_INCLUDED" before including "microhttpd2.h".
175
   When 'MHD_HAVE_SYS_HEADERS_INCLUDED' is defined, the following "standard"
176
   includes will not be used (which might be a good idea, especially on
177
   platforms where they do not exist).
178
   */
179
#ifndef MHD_HAVE_SYS_HEADERS_INCLUDED
180
#  include <stdarg.h>
181
#  ifndef MHD_SYS_BASE_TYPES_H
182
/* Headers for uint_fastXX_t, size_t */
183
#    include <stdint.h>
184
#    include <stddef.h>
185
#    include <sys/types.h> /* This header is actually optional */
186
#  endif
187
#  ifndef MHD_SYS_SOCKET_TYPES_H
188
/* Headers for 'struct sockaddr' */
189
#    if ! defined(_WIN32) || defined(__CYGWIN__)
190
#      include <sys/socket.h>
191
#    else
192
/* Prevent conflict of <winsock.h> and <winsock2.h> */
193
#      if ! defined(_WINSOCK2API_) && ! defined(_WINSOCKAPI_)
194
#        ifndef WIN32_LEAN_AND_MEAN
195
/* Do not use unneeded parts of W32 headers. */
196
#          define WIN32_LEAN_AND_MEAN 1
197
#        endif /* !WIN32_LEAN_AND_MEAN */
198
#        include <winsock2.h>
199
#      endif
200
#    endif
201
#  endif
202
#endif
203
204
#ifndef MHD_BOOL_DEFINED
205
206
/**
207
 * Representation of 'bool' in the public API as stdbool.h may not
208
 * always be available and presence of 'bool' keyword may depend on
209
 * used C version.
210
 * It is always safe to cast 'MHD_Bool' variable to 'bool' and vice versa.
211
 * Note: it may be UNSAFE to cast pointers 'MHD_Bool*' to 'bool*' and
212
 *       vice versa.
213
 */
214
enum MHD_Bool
215
{
216
217
  /**
218
   * MHD-internal return code for "NO".
219
   */
220
  MHD_NO = 0
221
  ,
222
  /**
223
   * MHD-internal return code for "YES".  All non-zero values
224
   * will be interpreted as "YES", but MHD will only ever
225
   * return #MHD_YES or #MHD_NO.
226
   */
227
  MHD_YES = 1
228
};
229
230
231
#define MHD_BOOL_DEFINED 1
232
#endif /* ! MHD_BOOL_DEFINED */
233
234
#ifndef MHD_STRINGS_DEFINED
235
236
237
/**
238
 * String with length data.
239
 * This type should always have valid @a cstr pointer.
240
 */
241
struct MHD_String
242
{
243
  /**
244
   * Number of characters in @e str, not counting 0-termination.
245
   */
246
  size_t len;
247
248
  /**
249
   * 0-terminated C-string.
250
   * Must not be NULL.
251
   */
252
  const char *cstr;
253
};
254
255
/**
256
 * String with length data.
257
 * This type of data may have NULL as the @a cstr pointer.
258
 */
259
struct MHD_StringNullable
260
{
261
  /**
262
   * Number of characters in @e cstr, not counting 0-termination.
263
   * If @a cstr is NULL, it must be zero.
264
   */
265
  size_t len;
266
267
  /**
268
   * 0-terminated C-string.
269
   * In some cases it could be NULL.
270
   */
271
  const char *cstr;
272
};
273
274
#define MHD_STRINGS_DEFINED 1
275
#endif /* ! MHD_STRINGS_DEFINED */
276
277
278
#ifndef MHD_INVALID_SOCKET
279
#  if ! defined(_WIN32) || defined(_SYS_TYPES_FD_SET)
280
#    define MHD_SOCKETS_KIND_POSIX 1
281
/**
282
 * MHD_Socket is a type for socket FDs
283
 */
284
typedef int MHD_Socket;
285
#    define MHD_INVALID_SOCKET (-1)
286
#  else /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
287
#    define MHD_SOCKETS_KIND_WINSOCK 1
288
/**
289
 * MHD_Socket is a type for socket FDs
290
 */
291
typedef SOCKET MHD_Socket;
292
#    define MHD_INVALID_SOCKET (INVALID_SOCKET)
293
#  endif /* !defined(_WIN32) || defined(_SYS_TYPES_FD_SET) */
294
#endif /* MHD_INVALID_SOCKET */
295
296
297
/**
298
 * Constant used to indicate unknown size (use when creating a response).
299
 * Any possible larger sizes are interpreted as the same value.
300
 */
301
#ifdef UINT64_MAX
302
800
#  define MHD_SIZE_UNKNOWN UINT64_MAX
303
#else
304
#  define MHD_SIZE_UNKNOWN \
305
        MHD_STATIC_CAST_ (uint_fast64_t,0xffffffffffffffffU)
306
#endif
307
308
309
/**
310
 * Constant used to indicate unlimited wait time.
311
 * Any possible larger values are interpreted as this value.
312
 */
313
#ifdef UINT64_MAX
314
#  define MHD_WAIT_INDEFINITELY UINT64_MAX
315
#else
316
#  define MHD_WAIT_INDEFINITELY \
317
        MHD_STATIC_CAST_ (uint_fast64_t,0xffffffffffffffffU)
318
#endif
319
320
321
/* ********** (a) Core HTTP Processing ************ */
322
323
324
/**
325
 * @brief Handle for a daemon that listens for requests.
326
 *
327
 * Manages the listen socket, event loop, optional threads and server
328
 * settings.
329
 *
330
 * @defgroup daemon HTTP server handling client connections
331
 */
332
struct MHD_Daemon;
333
334
335
/**
336
 * @brief Handle/identifier of a network connection abstraction.
337
 *
338
 * A single network (i.e. TCP) connection can be used for
339
 * a single (in HTTP/1.1) data stream.
340
 *
341
 * @defgroup connection client connection with streams
342
 */
343
struct MHD_Connection;
344
345
346
/**
347
 * @brief Handle/identifier of a data stream over network
348
 * connection.
349
 *
350
 * A data stream may be used for multiple requests, which
351
 * in HTTP/1.1 must be processed sequentially.
352
 *
353
 * @defgroup stream stream of HTTP requests
354
 */
355
struct MHD_Stream;
356
357
/**
358
 * @brief Handle representing an HTTP request.
359
 *
360
 * With HTTP/1.1, multiple requests can be run over the same
361
 * stream.  However, MHD will only show one request per data
362
 * stream to the client at any given time.
363
 *
364
 * Replaces `struct MHD_Connection` in the API prior to version 2.0.0,
365
 * renamed to better reflect what this object truly represents to
366
 * the application using MHD.
367
 *
368
 * @defgroup request HTTP requests
369
 */
370
struct MHD_Request;
371
372
373
/**
374
 * @brief Actions are returned by the application when processed client header
375
 * to drive the request handling of MHD.
376
 *
377
 * @defgroup action Request actions
378
 */
379
struct MHD_Action;
380
381
382
/**
383
 * @brief Actions are returned by the application when processing client upload
384
 * to drive the request handling of MHD.
385
 *
386
 * @defgroup action Request actions
387
 */
388
struct MHD_UploadAction;
389
390
/**
391
 * @defgroup general Primary MHD functions and data
392
 */
393
394
/**
395
 * @defgroup specialized Introspection and other special control
396
 */
397
398
/**
399
 * @defgroup authentication Digest and other HTTP authentications
400
 */
401
402
403
/**
404
 * Return values for reporting errors, also used for logging.
405
 *
406
 * A value of 0 indicates success (as a return value).
407
 * Values between 0 and 10000 must be handled explicitly by the app.
408
 * Values from 10000-19999 are informational.
409
 * Values from 20000-29999 indicate successful operations.
410
 * Values from 30000-39999 indicate unsuccessful (normal) operations.
411
 * Values from 40000-49999 indicate client errors.
412
 * Values from 50000-59999 indicate MHD server errors.
413
 * Values from 60000-65535 indicate application errors.
414
 *
415
 * @ingroup general
416
 */
417
enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
418
{
419
420
  /* 00000-level status codes indicate return values
421
     the application must act on. */
422
423
  /**
424
   * Successful operation (not used for logging).
425
   * The code is guaranteed to be always zero.
426
   */
427
  MHD_SC_OK = 0
428
  ,
429
430
  /* 10000-level status codes indicate intermediate
431
     results of some kind. */
432
433
  /**
434
   * Informational event, MHD started.
435
   */
436
  MHD_SC_DAEMON_STARTED = 10000
437
  ,
438
  /**
439
   * Informational event, we accepted a connection.
440
   */
441
  MHD_SC_CONNECTION_ACCEPTED = 10001
442
  ,
443
  /**
444
   * Informational event, thread processing connection terminates.
445
   */
446
  MHD_SC_THREAD_TERMINATING = 10002
447
  ,
448
  /**
449
   * Informational event, state machine status for a connection.
450
   */
451
  MHD_SC_STATE_MACHINE_STATUS_REPORT = 10003
452
  ,
453
  /**
454
   * accept() returned transient error.
455
   */
456
  MHD_SC_ACCEPT_FAILED_EAGAIN = 10004
457
  ,
458
  /**
459
   * Accepted socket is unknown type (probably non-IP).
460
   */
461
  MHD_SC_ACCEPTED_UNKNOWN_TYPE = 10040
462
  ,
463
  /**
464
   * The sockaddr for the accepted socket does not fit the buffer.
465
   * (Strange)
466
   */
467
  MHD_SC_ACCEPTED_SOCKADDR_TOO_LARGE = 10041
468
  ,
469
470
  /* 20000-level status codes indicate success of some kind. */
471
472
  /**
473
   * MHD is closing a connection after the client closed it
474
   * (perfectly normal end).
475
   */
476
  MHD_SC_CONNECTION_CLOSED = 20000
477
  ,
478
  /**
479
   * MHD is closing a connection because the application
480
   * logic to generate the response data completed.
481
   */
482
  MHD_SC_APPLICATION_DATA_GENERATION_FINISHED = 20001
483
  ,
484
  /**
485
   * The request does not contain a particular type of Authentication
486
   * credentials
487
   */
488
  MHD_SC_AUTH_ABSENT = 20060
489
  ,
490
491
  /* 30000-level status codes indicate transient failures
492
     that might go away if the client tries again. */
493
494
495
  /**
496
   * Resource limit in terms of number of parallel connections
497
   * hit.
498
   */
499
  MHD_SC_LIMIT_CONNECTIONS_REACHED = 30000
500
  ,
501
  /**
502
   * The operation failed because the respective
503
   * daemon is already too deep inside of the shutdown
504
   * activity.
505
   */
506
  MHD_SC_DAEMON_ALREADY_SHUTDOWN = 30020
507
  ,
508
  /**
509
   * Failed to start new thread because of system limits.
510
   */
511
  MHD_SC_CONNECTION_THREAD_SYS_LIMITS_REACHED = 30030
512
  ,
513
  /**
514
   * Failed to start a thread.
515
   */
516
  MHD_SC_CONNECTION_THREAD_LAUNCH_FAILURE = 30031
517
  ,
518
  /**
519
   * The operation failed because we either have no
520
   * listen socket or were already quiesced.
521
   */
522
  MHD_SC_DAEMON_ALREADY_QUIESCED = 30040
523
  ,
524
  /**
525
   * The operation failed because client disconnected
526
   * faster than we could accept().
527
   */
528
  MHD_SC_ACCEPT_FAST_DISCONNECT = 30040
529
  ,
530
  /**
531
   * Operating resource limits hit on accept().
532
   */
533
  MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED = 30060
534
  ,
535
  /**
536
   * Connection was refused by accept policy callback.
537
   */
538
  MHD_SC_ACCEPT_POLICY_REJECTED = 30070
539
  ,
540
  /**
541
   * Failed to allocate memory for the daemon resources.
542
   * TODO: combine similar error codes for daemon
543
   */
544
  MHD_SC_DAEMON_MEM_ALLOC_FAILURE = 30081
545
  ,
546
  /**
547
   * We failed to allocate memory for the connection.
548
   * (May be transient.)
549
   */
550
  MHD_SC_CONNECTION_MEM_ALLOC_FAILURE = 30082
551
  ,
552
  /**
553
   * We failed to allocate memory for the connection's memory pool.
554
   * (May be transient.)
555
   */
556
  MHD_SC_POOL_MEM_ALLOC_FAILURE = 30083
557
  ,
558
  /**
559
   * We failed to forward data from a Web socket to the
560
   * application to the remote side due to the socket
561
   * being closed prematurely. (May be transient.)
562
   */
563
  MHD_SC_UPGRADE_FORWARD_INCOMPLETE = 30100
564
  ,
565
  /**
566
   * Failed to allocate memory from our memory pool for processing
567
   * the request.  Likely the request fields are too large to leave
568
   * enough room.
569
   */
570
  MHD_SC_CONNECTION_POOL_NO_MEM_REQ = 30130
571
  ,
572
  /**
573
   * Failed to allocate memory from our memory pool to store GET parameter.
574
   * Likely the request URI or header fields are too large to leave enough room.
575
   */
576
  MHD_SC_CONNECTION_POOL_NO_MEM_GET_PARAM = 30131
577
  ,
578
  /**
579
   * Failed to allocate memory from our memory pool to store parsed cookie.
580
   */
581
  MHD_SC_CONNECTION_POOL_NO_MEM_COOKIE = 30132
582
  ,
583
  /**
584
   * Failed to allocate memory from connection memory pool to store
585
   * parsed Authentication data.
586
   */
587
  MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA = 30133
588
  ,
589
  /**
590
   * Detected jump back of system clock
591
   */
592
  MHD_SC_SYS_CLOCK_JUMP_BACK_LARGE = 30140
593
  ,
594
  /**
595
   * Detected correctable jump back of system clock
596
   */
597
  MHD_SC_SYS_CLOCK_JUMP_BACK_CORRECTED = 30141
598
  ,
599
  /**
600
   * Timeout waiting for communication operation for HTTP-Upgraded connection
601
   */
602
  MHD_SC_UPGRADED_NET_TIMEOUT = 30161
603
  ,
604
  /**
605
   * Not enough system resources
606
   */
607
  MHD_SC_NO_SYS_RESOURCES = 30180
608
  ,
609
610
  /* 40000-level errors are caused by the HTTP client
611
     (or the network) */
612
613
  /**
614
   * MHD is closing a connection because parsing the
615
   * request failed.
616
   */
617
  MHD_SC_CONNECTION_PARSE_FAIL_CLOSED = 40000
618
  ,
619
  /**
620
   * MHD is returning an error because the header provided
621
   * by the client is too big.
622
   */
623
  MHD_SC_CLIENT_HEADER_TOO_BIG = 40020
624
  ,
625
  /**
626
   * An HTTP/1.1 request was sent without the "Host:" header.
627
   */
628
  MHD_SC_HOST_HEADER_MISSING = 40060
629
  ,
630
  /**
631
   * Request has more than one "Host:" header.
632
   */
633
  MHD_SC_HOST_HEADER_SEVERAL = 40061
634
  ,
635
  /**
636
   * The given content length was not a number.
637
   */
638
  MHD_SC_CONTENT_LENGTH_MALFORMED = 40062
639
  ,
640
  /**
641
   * Request has more than one "Content-Length:" header with the same value.
642
   */
643
  MHD_SC_CONTENT_LENGTH_SEVERAL_SAME = 40063
644
  ,
645
  /**
646
   * Request has more than one "Content-Length:" header with the different
647
   * values.
648
   */
649
  MHD_SC_CONTENT_LENGTH_SEVERAL_DIFFERENT = 40064
650
  ,
651
  /**
652
   * The BOTH Content-Length and Transfer-Encoding headers are used.
653
   */
654
  MHD_SC_CONTENT_LENGTH_AND_TR_ENC = 40065
655
  ,
656
  /**
657
   * The Content-Length is too large to be handled.
658
   */
659
  MHD_SC_CONTENT_LENGTH_TOO_LARGE = 40066
660
  ,
661
  /**
662
   * Transfer encoding in request is unsupported or invalid.
663
   */
664
  MHD_SC_TRANSFER_ENCODING_UNSUPPORTED = 40067
665
  ,
666
  /**
667
   * "Expect:" value in request is unsupported or invalid.
668
   */
669
  MHD_SC_EXPECT_HEADER_VALUE_UNSUPPORTED = 40068
670
  ,
671
  /**
672
   * The given uploaded, chunked-encoded body was malformed.
673
   */
674
  MHD_SC_CHUNKED_ENCODING_MALFORMED = 40080
675
  ,
676
  /**
677
   * The first header line has whitespace at the start
678
   */
679
  MHD_SC_REQ_FIRST_HEADER_LINE_SPACE_PREFIXED = 40100
680
  ,
681
  /**
682
   * The request target (URI) has whitespace character
683
   */
684
  MHD_SC_REQ_TARGET_HAS_WHITESPACE = 40101
685
  ,
686
  /**
687
   * Wrong bare CR characters has been replaced with space.
688
   */
689
  MHD_SC_REQ_HEADER_CR_REPLACED = 40120
690
  ,
691
  /**
692
   * Header line has not colon and skipped.
693
   */
694
  MHD_SC_REQ_HEADER_LINE_NO_COLON = 40121
695
  ,
696
  /**
697
   * Wrong bare CR characters has been replaced with space.
698
   */
699
  MHD_SC_REQ_FOOTER_CR_REPLACED = 40140
700
  ,
701
  /**
702
   * Footer line has not colon and skipped.
703
   */
704
  MHD_SC_REQ_FOOTER_LINE_NO_COLON = 40141
705
  ,
706
  /**
707
   * The request is malformed.
708
   */
709
  MHD_SC_REQ_MALFORMED = 40155
710
  ,
711
  /**
712
   * The cookie string has been parsed, but it is not fully compliant with
713
   * specifications
714
   */
715
  MHD_SC_REQ_COOKIE_PARSED_NOT_COMPLIANT = 40160
716
  ,
717
  /**
718
   * The cookie string has been parsed only partially
719
   */
720
  MHD_SC_REQ_COOKIE_PARSED_PARTIALLY = 40161
721
  ,
722
  /**
723
   * The cookie string is ignored, as it is not fully compliant with
724
   * specifications
725
   */
726
  MHD_SC_REQ_COOKIE_IGNORED_NOT_COMPLIANT = 40162
727
  ,
728
  /**
729
   * The cookie string has been ignored as it is invalid
730
   */
731
  MHD_SC_REQ_COOKIE_INVALID = 40163
732
  ,
733
  /**
734
   * The POST data parsed successfully, but has missing or incorrect
735
   * termination.
736
   * The last parsed field may have incorrect data.
737
   */
738
  MHD_SC_REQ_POST_PARSE_OK_BAD_TERMINATION = 40202
739
  ,
740
  /**
741
   * Parsing of the POST data is incomplete because client used incorrect
742
   * format of POST encoding.
743
   * Some POST data is available or has been provided via callback.
744
   */
745
  MHD_SC_REQ_POST_PARSE_PARTIAL_INVALID_POST_FORMAT = 40203
746
  ,
747
  /**
748
   * The request does not have "Content-Type:" header and POST data cannot
749
   * be parsed
750
   */
751
  MHD_SC_REQ_POST_PARSE_FAILED_NO_CNTN_TYPE = 40280
752
  ,
753
  /**
754
   * The request has unknown POST encoding specified by "Content-Type:" header
755
   */
756
  MHD_SC_REQ_POST_PARSE_FAILED_UNKNOWN_CNTN_TYPE = 40281
757
  ,
758
  /**
759
   * The request has "Content-Type: multipart/form-data" header without
760
   * "boundary" parameter
761
   */
762
  MHD_SC_REQ_POST_PARSE_FAILED_HEADER_NO_BOUNDARY = 40282
763
  ,
764
  /**
765
   * The request has "Content-Type: multipart/form-data" header with misformed
766
   * data
767
   */
768
  MHD_SC_REQ_POST_PARSE_FAILED_HEADER_MISFORMED = 40283
769
  ,
770
  /**
771
   * The POST data cannot be parsed because client used incorrect format
772
   * of POST encoding.
773
   */
774
  MHD_SC_REQ_POST_PARSE_FAILED_INVALID_POST_FORMAT = 40290
775
  ,
776
  /**
777
   * The data in Auth request header has invalid format.
778
   * For example, for Basic Authentication base64 decoding failed.
779
   */
780
  MHD_SC_REQ_AUTH_DATA_BROKEN = 40320
781
  ,
782
  /**
783
   * The request cannot be processed. Sending error reply.
784
   */
785
  MHD_SC_REQ_PROCCESSING_ERR_REPLY = 41000
786
  ,
787
  /**
788
   * MHD is closing a connection because of timeout.
789
   */
790
  MHD_SC_CONNECTION_TIMEOUT = 42000
791
  ,
792
  /**
793
   * MHD is closing a connection because receiving the
794
   * request failed.
795
   */
796
  MHD_SC_CONNECTION_RECV_FAIL_CLOSED = 42020
797
  ,
798
  /**
799
   * MHD is closing a connection because sending the response failed.
800
   */
801
  MHD_SC_CONNECTION_SEND_FAIL_CLOSED = 42021
802
  ,
803
  /**
804
   * MHD is closing a connection because remote client shut down its sending
805
   * side before full request was sent.
806
   */
807
  MHD_SC_CLIENT_SHUTDOWN_EARLY = 42040
808
  ,
809
  /**
810
   * MHD is closing a connection because remote client closed connection
811
   * early.
812
   */
813
  MHD_SC_CLIENT_CLOSED_CONN_EARLY = 42041
814
  ,
815
  /**
816
   * MHD is closing a connection connection has been (remotely) aborted.
817
   */
818
  MHD_SC_CONNECTION_ABORTED = 42042
819
  ,
820
  /**
821
   * MHD is closing a connection because it was reset.
822
   */
823
  MHD_SC_CONNECTION_RESET = 42060
824
  ,
825
  /**
826
   * MHD is closing a connection connection (or connection socket) has
827
   * been broken.
828
   */
829
  MHD_SC_CONNECTION_BROKEN = 42061
830
  ,
831
832
  /* 50000-level errors are because of an error internal
833
     to the MHD logic, possibly including our interaction
834
     with the operating system (but not the application) */
835
836
  /**
837
   * This build of MHD does not support TLS, but the application
838
   * requested TLS.
839
   */
840
  MHD_SC_TLS_DISABLED = 50000
841
  ,
842
  /**
843
   * The selected TLS backend does not yet support this operation.
844
   */
845
  MHD_SC_TLS_BACKEND_OPERATION_UNSUPPORTED = 50004
846
  ,
847
  /**
848
   * Failed to setup ITC channel.
849
   */
850
  MHD_SC_ITC_INITIALIZATION_FAILED = 50005
851
  ,
852
  /**
853
   * File descriptor for ITC cannot be used because the FD number is higher
854
   * than the limit set by FD_SETSIZE (if internal polling with select is used)
855
   * or by application.
856
   */
857
  MHD_SC_ITC_FD_OUTSIDE_OF_SET_RANGE = 50006
858
  ,
859
  /**
860
   * The specified value for the NC length is way too large
861
   * for this platform (integer overflow on `size_t`).
862
   */
863
  MHD_SC_DIGEST_AUTH_NC_LENGTH_TOO_BIG = 50010
864
  ,
865
  /**
866
   * We failed to allocate memory for the specified nonce
867
   * counter array.  The option was not set.
868
   */
869
  MHD_SC_DIGEST_AUTH_NC_ALLOCATION_FAILURE = 50011
870
  ,
871
  /**
872
   * This build of the library does not support
873
   * digest authentication.
874
   */
875
  MHD_SC_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD = 50012
876
  ,
877
  /**
878
   * IPv6 requested but not supported by this build.
879
   * @sa #MHD_SC_AF_NOT_SUPPORTED_BY_BUILD
880
   */
881
  MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD = 50020
882
  ,
883
  /**
884
   * Specified address/protocol family is not supported by this build.
885
   * @sa MHD_SC_IPV6_NOT_SUPPORTED_BY_BUILD
886
   */
887
  MHD_SC_AF_NOT_SUPPORTED_BY_BUILD = 50021
888
  ,
889
  /**
890
   * The requested address/protocol family is rejected by the OS.
891
   * @sa #MHD_SC_AF_NOT_SUPPORTED_BY_BUILD
892
   */
893
  MHD_SC_AF_NOT_AVAILABLE = 500022
894
  ,
895
  /**
896
   * We failed to open the listen socket.
897
   */
898
  MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET = 50040
899
  ,
900
  /**
901
   * Failed to enable listen port reuse.
902
   */
903
  MHD_SC_LISTEN_PORT_REUSE_ENABLE_FAILED = 50041
904
  ,
905
  /**
906
   * Failed to enable listen port reuse.
907
   */
908
  MHD_SC_LISTEN_PORT_REUSE_ENABLE_NOT_SUPPORTED = 50042
909
  ,
910
  /**
911
   * Failed to enable listen address reuse.
912
   */
913
  MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_FAILED = 50043
914
  ,
915
  /**
916
   * Enabling listen address reuse is not supported by this platform.
917
   */
918
  MHD_SC_LISTEN_ADDRESS_REUSE_ENABLE_NOT_SUPPORTED = 50044
919
  ,
920
  /**
921
   * Failed to enable exclusive use of listen address.
922
   */
923
  MHD_SC_LISTEN_ADDRESS_EXCLUSIVE_ENABLE_FAILED = 50045
924
  ,
925
  /**
926
   * Dual stack configuration is not possible for provided sockaddr.
927
   */
928
  MHD_SC_LISTEN_DUAL_STACK_NOT_SUITABLE = 50046
929
  ,
930
  /**
931
   * Failed to enable or disable dual stack for the IPv6 listen socket.
932
   * The OS default dual-stack setting is different from what is requested.
933
   */
934
  MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED = 50047
935
  ,
936
  /**
937
   * Failed to enable or disable dual stack for the IPv6 listen socket.
938
   * The socket will be used in whatever the default is the OS uses.
939
   */
940
  MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_UNKNOWN = 50048
941
  ,
942
  /**
943
   * On this platform, MHD does not support explicitly configuring
944
   * dual stack behaviour.
945
   */
946
  MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_NOT_SUPPORTED = 50049
947
  ,
948
  /**
949
   * Failed to enable TCP FAST OPEN option.
950
   */
951
  MHD_SC_LISTEN_FAST_OPEN_FAILURE = 50050
952
  ,
953
  /**
954
   * TCP FAST OPEN is not supported by the platform or by this MHD build.
955
   */
956
  MHD_SC_FAST_OPEN_NOT_SUPPORTED = 50051
957
  ,
958
  /**
959
   * We failed to set the listen socket to non-blocking.
960
   */
961
  MHD_SC_LISTEN_SOCKET_NONBLOCKING_FAILURE = 50052
962
  ,
963
  /**
964
   * Failed to configure listen socket to be non-inheritable.
965
   */
966
  MHD_SC_LISTEN_SOCKET_NOINHERIT_FAILED = 50053
967
  ,
968
  /**
969
   * Listen socket FD cannot be used because the FD number is higher than
970
   * the limit set by FD_SETSIZE (if internal polling with select is used) or
971
   * by application.
972
   */
973
  MHD_SC_LISTEN_FD_OUTSIDE_OF_SET_RANGE = 50054
974
  ,
975
  /**
976
   * We failed to bind the listen socket.
977
   */
978
  MHD_SC_LISTEN_SOCKET_BIND_FAILED = 50055
979
  ,
980
  /**
981
   * Failed to start listening on listen socket.
982
   */
983
  MHD_SC_LISTEN_FAILURE = 50056
984
  ,
985
  /**
986
   * Failed to detect the port number on the listening socket
987
   */
988
  MHD_SC_LISTEN_PORT_DETECT_FAILURE = 50057
989
  ,
990
  /**
991
   * We failed to create control socket for the epoll().
992
   */
993
  MHD_SC_EPOLL_CTL_CREATE_FAILED = 50060
994
  ,
995
  /**
996
   * We failed to configure control socket for the epoll()
997
   * to be non-inheritable.
998
   */
999
  MHD_SC_EPOLL_CTL_CONFIGURE_NOINHERIT_FAILED = 50061
1000
  ,
1001
  /**
1002
   * The epoll() control FD cannot be used because the FD number is higher
1003
   * than the limit set by application.
1004
   */
1005
  MHD_SC_EPOLL_CTL_OUTSIDE_OF_SET_RANGE = 50062
1006
  ,
1007
  /**
1008
   * Failed to allocate memory for daemon's fd_sets
1009
   */
1010
  MHD_SC_FD_SET_MEMORY_ALLOCATE_FAILURE = 50063
1011
  ,
1012
  /**
1013
   * Failed to allocate memory for poll() structures
1014
   */
1015
  MHD_SC_POLL_FDS_MEMORY_ALLOCATE_FAILURE = 50063
1016
  ,
1017
  /**
1018
   * Failed to allocate memory for epoll data
1019
   */
1020
  MHD_SC_EPOLL_EVENTS_MEMORY_ALLOCATE_FAILURE = 50064
1021
  ,
1022
  /**
1023
   * Failed to add daemon's FDs (ITC and/or listening) to the epoll monitoring
1024
   */
1025
  MHD_SC_EPOLL_ADD_DAEMON_FDS_FAILURE = 50065
1026
  ,
1027
  /**
1028
   * Failed to register daemon's FDs (ITC or listening) in the application
1029
   * (external event) monitoring
1030
   */
1031
  MHD_SC_EXT_EVENT_REG_DAEMON_FDS_FAILURE = 50066
1032
  ,
1033
  /**
1034
   * The select() syscall is not available on this platform or in this MHD
1035
   * build.
1036
   */
1037
  MHD_SC_SELECT_SYSCALL_NOT_AVAILABLE = 50070
1038
  ,
1039
  /**
1040
   * The poll() syscall is not available on this platform or in this MHD
1041
   * build.
1042
   */
1043
  MHD_SC_POLL_SYSCALL_NOT_AVAILABLE = 50071
1044
  ,
1045
  /**
1046
   * The epoll syscalls are not available on this platform or in this MHD
1047
   * build.
1048
   */
1049
  MHD_SC_EPOLL_SYSCALL_NOT_AVAILABLE = 50072
1050
  ,
1051
  /**
1052
   * Failed to obtain our listen port via introspection.
1053
   * FIXME: remove?
1054
   */
1055
  MHD_SC_LISTEN_PORT_INTROSPECTION_FAILURE = 50080
1056
  ,
1057
  /**
1058
   * Failed to obtain our listen port via introspection
1059
   * due to unsupported address family being used.
1060
   */
1061
  MHD_SC_LISTEN_PORT_INTROSPECTION_UNKNOWN_AF = 50081
1062
  ,
1063
  /**
1064
   * Failed to initialise mutex.
1065
   */
1066
  MHD_SC_MUTEX_INIT_FAILURE = 50085
1067
  ,
1068
  /**
1069
   * Failed to allocate memory for the thread pool.
1070
   */
1071
  MHD_SC_THREAD_POOL_MEM_ALLOC_FAILURE = 50090
1072
  ,
1073
  /**
1074
   * We failed to allocate mutex for thread pool worker.
1075
   */
1076
  MHD_SC_THREAD_POOL_CREATE_MUTEX_FAILURE = 50093
1077
  ,
1078
  /**
1079
   * Failed to start the main daemon thread.
1080
   */
1081
  MHD_SC_THREAD_MAIN_LAUNCH_FAILURE = 50095
1082
  ,
1083
  /**
1084
   * Failed to start the daemon thread for listening.
1085
   */
1086
  MHD_SC_THREAD_LISTENING_LAUNCH_FAILURE = 50096
1087
  ,
1088
  /**
1089
   * Failed to start the worker thread for the thread pool.
1090
   */
1091
  MHD_SC_THREAD_WORKER_LAUNCH_FAILURE = 50097
1092
  ,
1093
  /**
1094
   * There was an attempt to upgrade a connection on
1095
   * a daemon where upgrades are disallowed.
1096
   */
1097
  MHD_SC_UPGRADE_ON_DAEMON_WITH_UPGRADE_DISALLOWED = 50100
1098
  ,
1099
  /**
1100
   * Failed to signal via ITC channel.
1101
   */
1102
  MHD_SC_ITC_USE_FAILED = 500101
1103
  ,
1104
  /**
1105
   * Failed to check for the signal on the ITC channel.
1106
   */
1107
  MHD_SC_ITC_CHECK_FAILED = 500102
1108
  ,
1109
  /**
1110
   * System reported error conditions on the ITC FD.
1111
   */
1112
  MHD_SC_ITC_STATUS_ERROR = 500104
1113
  ,
1114
  /**
1115
   * Failed to add a socket to the epoll set.
1116
   */
1117
  MHD_SC_EPOLL_CTL_ADD_FAILED = 500110
1118
  ,
1119
  /**
1120
   * Socket FD cannot be used because the FD number is higher than the limit set
1121
   * by FD_SETSIZE (if internal polling with select is used) or by application.
1122
   */
1123
  MHD_SC_SOCKET_OUTSIDE_OF_SET_RANGE = 500111
1124
  ,
1125
  /**
1126
   * The daemon cannot be started with the specified settings as no space
1127
   * left for the connections sockets within limits set by FD_SETSIZE.
1128
   * Consider use another sockets polling syscall (only select() has such
1129
   * limitations)
1130
   */
1131
  MHD_SC_SYS_FD_SETSIZE_TOO_STRICT = 50112
1132
  ,
1133
  /**
1134
   * This daemon was not configured with options that
1135
   * would allow us to obtain a meaningful timeout.
1136
   */
1137
  MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_TIMEOUT = 50113
1138
  ,
1139
  /**
1140
   * This daemon was not configured with options that
1141
   * would allow us to run with select() data.
1142
   */
1143
  MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_SELECT = 50114
1144
  ,
1145
  /**
1146
   * This daemon was not configured to run with an
1147
   * external event loop.
1148
   */
1149
  MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_EXTERNAL = 50115
1150
  ,
1151
  /**
1152
   * Encountered an unexpected error from select()
1153
   * (should never happen).
1154
   */
1155
  MHD_SC_UNEXPECTED_SELECT_ERROR = 50116
1156
  ,
1157
  /**
1158
   * Failed to remove a socket to the epoll set.
1159
   */
1160
  MHD_SC_EPOLL_CTL_REMOVE_FAILED = 50117
1161
  ,
1162
  /**
1163
   * poll() is not supported.
1164
   */
1165
  MHD_SC_POLL_NOT_SUPPORTED = 50120
1166
  ,
1167
  /**
1168
   * Encountered a (potentially) recoverable error from poll().
1169
   */
1170
  MHD_SC_POLL_SOFT_ERROR = 50121
1171
  ,
1172
  /**
1173
   * Encountered an unrecoverable error from poll().
1174
   */
1175
  MHD_SC_POLL_HARD_ERROR = 50122
1176
  ,
1177
  /**
1178
   * Encountered a (potentially) recoverable error from select().
1179
   */
1180
  MHD_SC_SELECT_SOFT_ERROR = 50123
1181
  ,
1182
  /**
1183
   * Encountered an unrecoverable error from select().
1184
   */
1185
  MHD_SC_SELECT_HARD_ERROR = 50124
1186
  ,
1187
  /**
1188
   * System reported error conditions on the listening socket.
1189
   */
1190
  MHD_SC_LISTEN_STATUS_ERROR = 50129
1191
  ,
1192
  /**
1193
   * Encountered an unrecoverable error from epoll function.
1194
   */
1195
  MHD_SC_EPOLL_HARD_ERROR = 50130
1196
  ,
1197
  /**
1198
   * We failed to configure accepted socket
1199
   * to not use a SIGPIPE.
1200
   */
1201
  MHD_SC_ACCEPT_CONFIGURE_NOSIGPIPE_FAILED = 50140
1202
  ,
1203
  /**
1204
   * We failed to configure accepted socket
1205
   * to be non-inheritable.
1206
   */
1207
  MHD_SC_ACCEPT_CONFIGURE_NOINHERIT_FAILED = 50141
1208
  ,
1209
  /**
1210
   * We failed to configure accepted socket
1211
   * to be non-blocking.
1212
   */
1213
  MHD_SC_ACCEPT_CONFIGURE_NONBLOCKING_FAILED = 50142
1214
  ,
1215
  /**
1216
   * The accepted socket FD value is too large.
1217
   */
1218
  MHD_SC_ACCEPT_OUTSIDE_OF_SET_RANGE = 50143
1219
  ,
1220
  /**
1221
   * accept() returned unexpected error.
1222
   */
1223
  MHD_SC_ACCEPT_FAILED_UNEXPECTEDLY = 50144
1224
  ,
1225
  /**
1226
   * Operating resource limits hit on accept() while
1227
   * zero connections are active. Oopsie.
1228
   */
1229
  MHD_SC_ACCEPT_SYSTEM_LIMIT_REACHED_INSTANTLY = 50145
1230
  ,
1231
  /**
1232
   * The daemon sockets polling mode requires non-blocking sockets.
1233
   */
1234
  MHD_SC_NONBLOCKING_REQUIRED = 50146
1235
  ,
1236
  /**
1237
   * Encountered an unexpected error from epoll_wait()
1238
   * (should never happen).
1239
   */
1240
  MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR = 50150
1241
  ,
1242
  /**
1243
   * epoll file descriptor is invalid (strange)
1244
   */
1245
  MHD_SC_EPOLL_FD_INVALID = 50151
1246
  ,
1247
  /**
1248
   * Unexpected socket error (strange)
1249
   */
1250
  MHD_SC_UNEXPECTED_SOCKET_ERROR = 50152
1251
  ,
1252
  /**
1253
   * Failed to add IP address to per-IP counter for
1254
   * some reason.
1255
   */
1256
  MHD_SC_IP_COUNTER_FAILURE = 50160
1257
  ,
1258
  /**
1259
   * Application violated our API by calling shutdown
1260
   * while having an upgrade connection still open.
1261
   */
1262
  MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION = 50180
1263
  ,
1264
  /**
1265
   * Due to an unexpected internal error with the
1266
   * state machine, we closed the connection.
1267
   */
1268
  MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED = 50200
1269
  ,
1270
  /**
1271
   * Failed to allocate memory in connection's pool
1272
   * to parse the cookie header.
1273
   */
1274
  MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE = 50220
1275
  ,
1276
  /**
1277
   * MHD failed to build the response header.
1278
   */
1279
  MHD_SC_REPLY_FAILED_HEADER_GENERATION = 50230
1280
  ,
1281
  /**
1282
   * Failed to allocate memory in connection's pool for the reply.
1283
   */
1284
  MHD_SC_REPLY_POOL_ALLOCATION_FAILURE = 50231
1285
  ,
1286
  /**
1287
   * Failed to read the file for file-backed response.
1288
   */
1289
  MHD_SC_REPLY_FILE_READ_ERROR = 50232
1290
  ,
1291
  /**
1292
   * Failed to generate the nonce for the Digest Auth.
1293
   */
1294
  MHD_SC_REPLY_NONCE_ERROR = 50233
1295
  ,
1296
  /**
1297
   * Failed to allocate memory in connection's pool for the reply.
1298
   */
1299
  MHD_SC_ERR_RESPONSE_ALLOCATION_FAILURE = 50250
1300
  ,
1301
  /**
1302
   * The request POST data cannot be parsed because stream has not enough
1303
   * pool memory free.
1304
   */
1305
  MHD_SC_REQ_POST_PARSE_FAILED_NO_POOL_MEM = 50260
1306
  ,
1307
  /**
1308
   * The POST data cannot be parsed completely because no "large shared buffer"
1309
   * space is available.
1310
   * Some POST data may be parsed.
1311
   */
1312
  MHD_SC_REQ_POST_PARSE_FAILED_NO_LARGE_BUF_MEM = 50261
1313
  ,
1314
  /**
1315
   * The application set POST encoding to "multipart/form-data", but the request
1316
   * has no "Content-Type: multipart/form-data" header which is required
1317
   * to find "boundary" used in this encoding
1318
   */
1319
  MHD_SC_REQ_POST_PARSE_FAILED_HEADER_NOT_MPART = 50284
1320
  ,
1321
  /**
1322
   * The feature is not supported by this MHD build (either
1323
   * disabled by configure parameters or build platform
1324
   * did not support it, because headers are missing or
1325
   * so kernel does not have such feature).
1326
   * The feature will not be enabled if the same MHD binary
1327
   * will be run on another kernel, computer or system
1328
   * configuration.
1329
   */
1330
  MHD_SC_FEATURE_DISABLED = 50300
1331
  ,
1332
  /**
1333
   * The feature is not supported by this platform, while
1334
   * supported by MHD build.
1335
   * The feature can be enabled by changing the kernel or
1336
   * running on another computer or with other system
1337
   * configuration.
1338
   */
1339
  MHD_SC_FEATURE_NOT_AVAILABLE = 50320
1340
  ,
1341
  /**
1342
   * Failed to stop the thread
1343
   */
1344
  MHD_SC_DAEMON_THREAD_STOP_ERROR = 50350
1345
  ,
1346
  /**
1347
   * Unexpected reasons for thread stop
1348
   */
1349
  MHD_SC_DAEMON_THREAD_STOP_UNEXPECTED = 50351
1350
  ,
1351
  /**
1352
   * Daemon system data is broken (like listen socket was unexpectedly closed).
1353
   * The daemon needs to be closed.
1354
   * A new daemon can be started as a replacement after closing the current
1355
   * daemon.
1356
   */
1357
  MHD_SC_DAEMON_SYS_DATA_BROKEN = 50370
1358
  ,
1359
  /**
1360
   * Failed to acquire response mutex lock
1361
   */
1362
  MHD_SC_RESPONSE_MUTEX_LOCK_FAILED = 50500
1363
  ,
1364
  /**
1365
   * Failed to initialise response mutex
1366
   */
1367
  MHD_SC_RESPONSE_MUTEX_INIT_FAILED = 50501
1368
  ,
1369
  /**
1370
   * Unable to clear "reusable" flag.
1371
   * One this flag set, it cannot be removed for the response lifetime.
1372
   */
1373
  MHD_SC_RESPONSE_CANNOT_CLEAR_REUSE = 50520
1374
  ,
1375
  /**
1376
   * Unable to allocate memory for the response header
1377
   */
1378
  MHD_SC_RESPONSE_HEADER_MEM_ALLOC_FAILED = 50540
1379
  ,
1380
  /**
1381
   * Failed to switch TCP_NODELAY option for the socket
1382
   */
1383
  MHD_SC_SOCKET_TCP_NODELAY_FAILED = 50600
1384
  ,
1385
  /**
1386
   * Failed to switch TCP_CORK or TCP_NOPUSH option for the socket
1387
   */
1388
  MHD_SC_SOCKET_TCP_CORK_NOPUSH_FAILED = 50601
1389
  ,
1390
  /**
1391
   * Failed to force flush the last part of the response header or
1392
   * the response content
1393
   */
1394
  MHD_SC_SOCKET_FLUSH_LAST_PART_FAILED = 50620
1395
  ,
1396
  /**
1397
   * Failed to push buffered data by zero-sized send()
1398
   */
1399
  MHD_SC_SOCKET_ZERO_SEND_FAILED = 50621
1400
  ,
1401
  /**
1402
   * The HTTP-Upgraded network connection has been closed / disconnected
1403
   */
1404
  MHD_SC_UPGRADED_NET_CONN_CLOSED = 50800
1405
  ,
1406
  /**
1407
   * The HTTP-Upgraded network connection has been broken
1408
   */
1409
  MHD_SC_UPGRADED_NET_CONN_BROKEN = 50801
1410
  ,
1411
  /**
1412
   * The TLS communication error on HTTP-Upgraded connection
1413
   */
1414
  MHD_SC_UPGRADED_TLS_ERROR = 50801
1415
  ,
1416
  /**
1417
   * Unrecoverable sockets communication error on HTTP-Upgraded connection
1418
   */
1419
  MHD_SC_UPGRADED_NET_HARD_ERROR = 50840
1420
  ,
1421
  /**
1422
   * MHD cannot wait for the data on the HTTP-Upgraded connection, because
1423
   * current build or the platform does not support required functionality.
1424
   * Communication with zero timeout is fully supported.
1425
   */
1426
  MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED = 50840
1427
  ,
1428
  /**
1429
   * Global initialisation of MHD library failed
1430
   */
1431
  MHD_SC_LIB_INIT_GLOBAL_FAILED = 51000
1432
  ,
1433
  /**
1434
   * Failed to initialise TLS context for the daemon
1435
   */
1436
  MHD_SC_TLS_DAEMON_INIT_FAILED = 51200
1437
  ,
1438
  /**
1439
   * Failed to initialise TLS context for the new connection
1440
   */
1441
  MHD_SC_TLS_CONNECTION_INIT_FAILED = 51201
1442
  ,
1443
  /**
1444
   * Warning about TLS backend configuration
1445
   */
1446
  MHD_SC_TLS_LIB_CONF_WARNING = 51202
1447
  ,
1448
  /**
1449
   * Failed to perform TLS handshake
1450
   */
1451
  MHD_SC_TLS_CONNECTION_HANDSHAKED_FAILED = 51220
1452
  ,
1453
  /**
1454
   * Hashing failed.
1455
   * Internal hashing function can never fail (and this code is never returned
1456
   * for them). External hashing function (like TLS backend-based) may fail
1457
   * for various reasons, like failure of hardware acccelerated hashing.
1458
   */
1459
  MHD_SC_HASH_FAILED = 51260
1460
  ,
1461
  /**
1462
   * Something wrong in the internal MHD logic.
1463
   * This error should be never returned if MHD works as expected.
1464
   * If this code is ever returned, please report to MHD maintainers.
1465
   */
1466
  MHD_SC_INTERNAL_ERROR = 59900
1467
  ,
1468
1469
  /* 60000-level errors are because the application
1470
     logic did something wrong or generated an error. */
1471
1472
  /**
1473
   * The application called function too early.
1474
   * For example, a header value was requested before the headers
1475
   * had been received.
1476
   */
1477
  MHD_SC_TOO_EARLY = 60000
1478
  ,
1479
  /**
1480
   * The application called this function too late.
1481
   * For example, MHD has already started sending reply.
1482
   */
1483
  MHD_SC_TOO_LATE = 60001
1484
  ,
1485
  /**
1486
   * MHD does not support the requested combination of
1487
   * the sockets polling syscall and the work mode.
1488
   */
1489
  MHD_SC_SYSCALL_WORK_MODE_COMBINATION_INVALID = 60010
1490
  ,
1491
  /**
1492
   * MHD does not support quiescing if ITC was disabled
1493
   * and threads are used.
1494
   */
1495
  MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC = 60011
1496
  ,
1497
  /**
1498
   * The option provided or function called can be used only with "external
1499
   * events" modes.
1500
   */
1501
  MHD_SC_EXTERNAL_EVENT_ONLY = 60012
1502
  ,
1503
  /**
1504
   * MHD is closing a connection because the application
1505
   * logic to generate the response data failed.
1506
   */
1507
  MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED = 60015
1508
  ,
1509
  /**
1510
   * MHD is closing a connection because the application
1511
   * callback told it to do so.
1512
   */
1513
  MHD_SC_APPLICATION_CALLBACK_ABORT_ACTION = 60016
1514
  ,
1515
  /**
1516
   * Application only partially processed upload and did
1517
   * not suspend connection. This may result in a hung
1518
   * connection.
1519
   */
1520
  MHD_SC_APPLICATION_HUNG_CONNECTION = 60017
1521
  ,
1522
  /**
1523
   * Application only partially processed upload and did
1524
   * not suspend connection and the read buffer was maxxed
1525
   * out, so MHD closed the connection.
1526
   */
1527
  MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED = 60018
1528
  ,
1529
  /**
1530
   * Attempted to set an option that conflicts with another option
1531
   * already set.
1532
   */
1533
  MHD_SC_OPTIONS_CONFLICT = 60020
1534
  ,
1535
  /**
1536
   * Attempted to set an option that not recognised by MHD.
1537
   */
1538
  MHD_SC_OPTION_UNKNOWN = 60021
1539
  ,
1540
  /**
1541
   * Parameter specified unknown work mode.
1542
   */
1543
  MHD_SC_CONFIGURATION_UNEXPECTED_WM = 60022
1544
  ,
1545
  /**
1546
   * Parameter specified unknown Sockets Polling Syscall (SPS).
1547
   */
1548
  MHD_SC_CONFIGURATION_UNEXPECTED_SPS = 60023
1549
  ,
1550
  /**
1551
   * The size of the provided sockaddr does not match address family.
1552
   */
1553
  MHD_SC_CONFIGURATION_WRONG_SA_SIZE = 60024
1554
  ,
1555
  /**
1556
   * The number set by #MHD_D_O_FD_NUMBER_LIMIT is too strict to run
1557
   * the daemon
1558
   */
1559
  MHD_SC_MAX_FD_NUMBER_LIMIT_TOO_STRICT = 60025
1560
  ,
1561
  /**
1562
   * The number set by #MHD_D_O_GLOBAL_CONNECTION_LIMIT is too for the daemon
1563
   * configuration
1564
   */
1565
  MHD_SC_CONFIGURATION_CONN_LIMIT_TOO_SMALL = 60026
1566
  ,
1567
  /**
1568
   * The application requested an unsupported TLS backend to be used.
1569
   */
1570
  MHD_SC_TLS_BACKEND_UNSUPPORTED = 60030
1571
  ,
1572
  /**
1573
   * The application attempted to setup TLS parameters before
1574
   * enabling TLS.
1575
   */
1576
  MHD_SC_TLS_BACKEND_UNINITIALIZED = 60031
1577
  ,
1578
  /**
1579
   * The application requested a TLS backend which cannot be used due
1580
   * to missing TLS dynamic library or backend initialisation problem.
1581
   */
1582
  MHD_SC_TLS_BACKEND_UNAVAILABLE = 60032
1583
  ,
1584
  /**
1585
   * Provided TLS certificate and/or private key are incorrect
1586
   */
1587
  MHD_SC_TLS_CONF_BAD_CERT = 60033
1588
  ,
1589
  /**
1590
   * The application requested a daemon setting that cannot be used with
1591
   * selected TLS backend
1592
   */
1593
  MHD_SC_TLS_BACKEND_DAEMON_INCOMPATIBLE_SETTINGS = 60034
1594
  ,
1595
  /**
1596
   * The response header name has forbidden characters or token
1597
   */
1598
  MHD_SC_RESP_HEADER_NAME_INVALID = 60050
1599
  ,
1600
  /**
1601
   * The response header value has forbidden characters or token
1602
   */
1603
  MHD_SC_RESP_HEADER_VALUE_INVALID = 60051
1604
  ,
1605
  /**
1606
   * An attempt to add header conflicting with other response header
1607
   */
1608
  MHD_SC_RESP_HEADERS_CONFLICT = 60052
1609
  ,
1610
  /**
1611
   * The pointer to the response object is NULL
1612
   */
1613
  MHD_SC_RESP_POINTER_NULL = 60060
1614
  ,
1615
  /**
1616
   * The response HTTP status code is not suitable
1617
   */
1618
  MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE = 60061
1619
  ,
1620
  /**
1621
   * The provided MHD_Action is invalid
1622
   */
1623
  MHD_SC_ACTION_INVALID = 60080
1624
  ,
1625
  /**
1626
   * The provided MHD_UploadAction is invalid
1627
   */
1628
  MHD_SC_UPLOAD_ACTION_INVALID = 60081
1629
  ,
1630
  /**
1631
   * The provided Dynamic Content Creator action is invalid
1632
   */
1633
  MHD_SC_DCC_ACTION_INVALID = 60082
1634
  ,
1635
  /**
1636
   * The response must be empty
1637
   */
1638
  MHD_SC_REPLY_NOT_EMPTY_RESPONSE = 60101
1639
  ,
1640
  /**
1641
   * The "Content-Length" header is not allowed in the reply
1642
   */
1643
  MHD_SC_REPLY_CONTENT_LENGTH_NOT_ALLOWED = 60102
1644
  ,
1645
  /**
1646
   * The provided reply headers do not fit the connection buffer
1647
   */
1648
  MHD_SC_REPLY_HEADERS_TOO_LARGE = 60103
1649
  ,
1650
  /**
1651
   * Specified offset in file-backed response is too large and not supported
1652
   * by the platform
1653
   */
1654
  MHD_SC_REPLY_FILE_OFFSET_TOO_LARGE = 60104
1655
  ,
1656
  /**
1657
   * File-backed response has file smaller than specified combination of
1658
   * the file offset and the response size.
1659
   */
1660
  MHD_SC_REPLY_FILE_TOO_SHORT = 60105
1661
  ,
1662
  /**
1663
   * The new connection cannot be used because the FD number is higher than
1664
   * the limit set by FD_SETSIZE (if internal polling with select is used) or
1665
   * by application.
1666
   */
1667
  MHD_SC_NEW_CONN_FD_OUTSIDE_OF_SET_RANGE = 60140
1668
  ,
1669
  /**
1670
   * The daemon is being destroyed, while not all HTTP-Upgraded connections
1671
   * has been closed.
1672
   */
1673
  MHD_SC_DAEMON_DESTROYED_WITH_UNCLOSED_UPGRADED = 60160
1674
  ,
1675
  /**
1676
   * The provided pointer to 'struct MHD_UpgradedHandle' is invalid
1677
   */
1678
  MHD_SC_UPGRADED_HANDLE_INVALID = 60161
1679
  ,
1680
  /**
1681
   * The provided output buffer is too small.
1682
   */
1683
  MHD_SC_OUT_BUFF_TOO_SMALL = 60180
1684
  ,
1685
  /**
1686
   * The requested type of information is not recognised.
1687
   */
1688
  MHD_SC_INFO_GET_TYPE_UNKNOWN = 60200
1689
  ,
1690
  /**
1691
   * The information of the requested type is too large to fit into
1692
   * the provided buffer.
1693
   */
1694
  MHD_SC_INFO_GET_BUFF_TOO_SMALL = 60201
1695
  ,
1696
  /**
1697
   * The type of the information is not supported by this MHD build.
1698
   * It can be information not supported on the current platform or related
1699
   * to feature disabled for this build.
1700
   */
1701
  MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD = 60202
1702
  ,
1703
  /**
1704
   * The type of the information is not available due to configuration
1705
   * or state of the object.
1706
   */
1707
  MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE = 60203
1708
  ,
1709
  /**
1710
   * The type of the information should be available for the object, but
1711
   * cannot be provided due to some error or other reasons.
1712
   */
1713
  MHD_SC_INFO_GET_TYPE_UNOBTAINABLE = 60204
1714
  ,
1715
  /**
1716
   * The type of the Digest Auth algorithm is unknown or not supported.
1717
   */
1718
  MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED = 60240
1719
  ,
1720
  /**
1721
   * The Digest Auth QOP value is unknown or not supported.
1722
   */
1723
  MHD_SC_AUTH_DIGEST_QOP_NOT_SUPPORTED = 60241
1724
  ,
1725
  /**
1726
   * The Digest Auth is not supported due to configuration
1727
   */
1728
  MHD_SC_AUTH_DIGEST_UNSUPPORTED = 60242
1729
  ,
1730
  /**
1731
   * The application failed to register FD for the external events monitoring
1732
   */
1733
  MHD_SC_EXTR_EVENT_REG_FAILED = 60243
1734
  ,
1735
  /**
1736
   * The application failed to de-register FD for the external events monitoring
1737
   */
1738
  MHD_SC_EXTR_EVENT_DEREG_FAILED = 60244
1739
  ,
1740
  /**
1741
   * The application called #MHD_daemon_event_update() with broken data
1742
   */
1743
  MHD_SC_EXTR_EVENT_BROKEN_DATA = 60250
1744
  ,
1745
  /**
1746
   * The application called #MHD_daemon_event_update() with status that
1747
   * has not been requested
1748
   */
1749
  MHD_SC_EXTR_EVENT_UNEXPECTED_STATUS = 60251
1750
};
1751
1752
/**
1753
 * Get text description for the MHD error code.
1754
 *
1755
 * This function works for @b MHD error codes, not for @b HTTP status codes.
1756
 * @param code the MHD code to get description for
1757
 * @return the pointer to the text description,
1758
 *         NULL if MHD code in not known.
1759
 *
1760
 * @ingroup general
1761
 */
1762
MHD_EXTERN_ const struct MHD_String *
1763
MHD_status_code_to_string (enum MHD_StatusCode code)
1764
MHD_FN_CONST_;
1765
1766
/**
1767
 * Get the pointer to the C string for the MHD error code, never NULL.
1768
 */
1769
#define MHD_status_code_to_string_lazy(code) \
1770
        (MHD_status_code_to_string ((code)) ? \
1771
         ((MHD_status_code_to_string (code))->cstr) : ("[No code]") )
1772
1773
#ifndef MHD_HTTP_METHOD_DEFINED
1774
1775
/**
1776
 * @brief HTTP request methods
1777
 *
1778
 * @defgroup methods HTTP methods
1779
 *
1780
 * See: https://www.iana.org/assignments/http-methods/http-methods.xml
1781
 * Registry export date: 2023-10-02
1782
 * @{
1783
 */
1784
1785
/**
1786
 * HTTP methods explicitly supported by MHD.  Note that for non-canonical
1787
 * methods, MHD will return #MHD_HTTP_METHOD_OTHER and you can use
1788
 * #MHD_REQUEST_INFO_FIXED_HTTP_METHOD to get the original string.
1789
 *
1790
 * However, applications must check for #MHD_HTTP_METHOD_OTHER *or* any enum-value
1791
 * above those in this list, as future versions of MHD may add additional
1792
 * methods (as per IANA registry), thus even if the API returns
1793
 * #MHD_HTTP_METHOD_OTHER today, it may return a method-specific header in the
1794
 * future!
1795
 */
1796
enum MHD_FIXED_ENUM_MHD_SET_ MHD_HTTP_Method
1797
{
1798
1799
  /**
1800
   * Method did not match any of the methods given below.
1801
   */
1802
  MHD_HTTP_METHOD_OTHER = 255
1803
  ,
1804
  /* Main HTTP methods. */
1805
1806
  /**
1807
   * "GET"
1808
   * Safe.     Idempotent.     RFC9110, Section 9.3.1.
1809
   */
1810
  MHD_HTTP_METHOD_GET = 1
1811
  ,
1812
  /**
1813
   * "HEAD"
1814
   * Safe.     Idempotent.     RFC9110, Section 9.3.2.
1815
   */
1816
  MHD_HTTP_METHOD_HEAD = 2
1817
  ,
1818
  /**
1819
   * "POST"
1820
   * Not safe. Not idempotent. RFC9110, Section 9.3.3.
1821
   */
1822
  MHD_HTTP_METHOD_POST = 3
1823
  ,
1824
  /**
1825
   * "PUT"
1826
   * Not safe. Idempotent.     RFC9110, Section 9.3.4.
1827
   */
1828
  MHD_HTTP_METHOD_PUT = 4
1829
  ,
1830
  /**
1831
   * "DELETE"
1832
   * Not safe. Idempotent.     RFC9110, Section 9.3.5.
1833
   */
1834
  MHD_HTTP_METHOD_DELETE = 5
1835
  ,
1836
  /**
1837
   * "CONNECT"
1838
   * Not safe. Not idempotent. RFC9110, Section 9.3.6.
1839
   */
1840
  MHD_HTTP_METHOD_CONNECT = 6
1841
  ,
1842
  /**
1843
   * "OPTIONS"
1844
   * Safe.     Idempotent.     RFC9110, Section 9.3.7.
1845
   */
1846
  MHD_HTTP_METHOD_OPTIONS = 7
1847
  ,
1848
  /**
1849
   * "TRACE"
1850
   * Safe.     Idempotent.     RFC9110, Section 9.3.8.
1851
   */
1852
  MHD_HTTP_METHOD_TRACE = 8
1853
  ,
1854
  /**
1855
   * "*"
1856
   * Not safe. Not idempotent. RFC9110, Section 18.2.
1857
   */
1858
  MHD_HTTP_METHOD_ASTERISK = 9
1859
};
1860
1861
#define MHD_HTTP_METHOD_DEFINED 1
1862
#endif /* ! MHD_HTTP_METHOD_DEFINED */
1863
1864
/**
1865
 * Get text version of the method name.
1866
 * @param method the method to get the text version
1867
 * @return the pointer to the text version,
1868
 *         NULL if method is MHD_HTTP_METHOD_OTHER
1869
 *         or not known.
1870
 */
1871
MHD_EXTERN_ const struct MHD_String *
1872
MHD_http_method_to_string (enum MHD_HTTP_Method method)
1873
MHD_FN_CONST_;
1874
1875
1876
/* Main HTTP methods. */
1877
/* Safe.     Idempotent.     RFC9110, Section 9.3.1. */
1878
362
#define MHD_HTTP_METHOD_STR_GET      "GET"
1879
/* Safe.     Idempotent.     RFC9110, Section 9.3.2. */
1880
125
#define MHD_HTTP_METHOD_STR_HEAD     "HEAD"
1881
/* Not safe. Not idempotent. RFC9110, Section 9.3.3. */
1882
41
#define MHD_HTTP_METHOD_STR_POST     "POST"
1883
/* Not safe. Idempotent.     RFC9110, Section 9.3.4. */
1884
62
#define MHD_HTTP_METHOD_STR_PUT      "PUT"
1885
/* Not safe. Idempotent.     RFC9110, Section 9.3.5. */
1886
32
#define MHD_HTTP_METHOD_STR_DELETE   "DELETE"
1887
/* Not safe. Not idempotent. RFC9110, Section 9.3.6. */
1888
99
#define MHD_HTTP_METHOD_STR_CONNECT  "CONNECT"
1889
/* Safe.     Idempotent.     RFC9110, Section 9.3.7. */
1890
42
#define MHD_HTTP_METHOD_STR_OPTIONS  "OPTIONS"
1891
/* Safe.     Idempotent.     RFC9110, Section 9.3.8. */
1892
59
#define MHD_HTTP_METHOD_STR_TRACE    "TRACE"
1893
/* Not safe. Not idempotent. RFC9110, Section 18.2. */
1894
#define MHD_HTTP_METHOD_STR_ASTERISK  "*"
1895
1896
/* Additional HTTP methods. */
1897
/* Not safe. Idempotent.     RFC3744, Section 8.1. */
1898
#define MHD_HTTP_METHOD_STR_ACL            "ACL"
1899
/* Not safe. Idempotent.     RFC3253, Section 12.6. */
1900
#define MHD_HTTP_METHOD_STR_BASELINE_CONTROL "BASELINE-CONTROL"
1901
/* Not safe. Idempotent.     RFC5842, Section 4. */
1902
#define MHD_HTTP_METHOD_STR_BIND           "BIND"
1903
/* Not safe. Idempotent.     RFC3253, Section 4.4, Section 9.4. */
1904
#define MHD_HTTP_METHOD_STR_CHECKIN        "CHECKIN"
1905
/* Not safe. Idempotent.     RFC3253, Section 4.3, Section 8.8. */
1906
#define MHD_HTTP_METHOD_STR_CHECKOUT       "CHECKOUT"
1907
/* Not safe. Idempotent.     RFC4918, Section 9.8. */
1908
#define MHD_HTTP_METHOD_STR_COPY           "COPY"
1909
/* Not safe. Idempotent.     RFC3253, Section 8.2. */
1910
#define MHD_HTTP_METHOD_STR_LABEL          "LABEL"
1911
/* Not safe. Idempotent.     RFC2068, Section 19.6.1.2. */
1912
#define MHD_HTTP_METHOD_STR_LINK           "LINK"
1913
/* Not safe. Not idempotent. RFC4918, Section 9.10. */
1914
#define MHD_HTTP_METHOD_STR_LOCK           "LOCK"
1915
/* Not safe. Idempotent.     RFC3253, Section 11.2. */
1916
#define MHD_HTTP_METHOD_STR_MERGE          "MERGE"
1917
/* Not safe. Idempotent.     RFC3253, Section 13.5. */
1918
#define MHD_HTTP_METHOD_STR_MKACTIVITY     "MKACTIVITY"
1919
/* Not safe. Idempotent.     RFC4791, Section 5.3.1; RFC8144, Section 2.3. */
1920
#define MHD_HTTP_METHOD_STR_MKCALENDAR     "MKCALENDAR"
1921
/* Not safe. Idempotent.     RFC4918, Section 9.3; RFC5689, Section 3; RFC8144, Section 2.3. */
1922
#define MHD_HTTP_METHOD_STR_MKCOL          "MKCOL"
1923
/* Not safe. Idempotent.     RFC4437, Section 6. */
1924
#define MHD_HTTP_METHOD_STR_MKREDIRECTREF  "MKREDIRECTREF"
1925
/* Not safe. Idempotent.     RFC3253, Section 6.3. */
1926
#define MHD_HTTP_METHOD_STR_MKWORKSPACE    "MKWORKSPACE"
1927
/* Not safe. Idempotent.     RFC4918, Section 9.9. */
1928
#define MHD_HTTP_METHOD_STR_MOVE           "MOVE"
1929
/* Not safe. Idempotent.     RFC3648, Section 7. */
1930
#define MHD_HTTP_METHOD_STR_ORDERPATCH     "ORDERPATCH"
1931
/* Not safe. Not idempotent. RFC5789, Section 2. */
1932
#define MHD_HTTP_METHOD_STR_PATCH          "PATCH"
1933
/* Safe.     Idempotent.     RFC9113, Section 3.4. */
1934
#define MHD_HTTP_METHOD_STR_PRI            "PRI"
1935
/* Safe.     Idempotent.     RFC4918, Section 9.1; RFC8144, Section 2.1. */
1936
#define MHD_HTTP_METHOD_STR_PROPFIND       "PROPFIND"
1937
/* Not safe. Idempotent.     RFC4918, Section 9.2; RFC8144, Section 2.2. */
1938
#define MHD_HTTP_METHOD_STR_PROPPATCH      "PROPPATCH"
1939
/* Not safe. Idempotent.     RFC5842, Section 6. */
1940
#define MHD_HTTP_METHOD_STR_REBIND         "REBIND"
1941
/* Safe.     Idempotent.     RFC3253, Section 3.6; RFC8144, Section 2.1. */
1942
#define MHD_HTTP_METHOD_STR_REPORT         "REPORT"
1943
/* Safe.     Idempotent.     RFC5323, Section 2. */
1944
#define MHD_HTTP_METHOD_STR_SEARCH         "SEARCH"
1945
/* Not safe. Idempotent.     RFC5842, Section 5. */
1946
#define MHD_HTTP_METHOD_STR_UNBIND         "UNBIND"
1947
/* Not safe. Idempotent.     RFC3253, Section 4.5. */
1948
#define MHD_HTTP_METHOD_STR_UNCHECKOUT     "UNCHECKOUT"
1949
/* Not safe. Idempotent.     RFC2068, Section 19.6.1.3. */
1950
#define MHD_HTTP_METHOD_STR_UNLINK         "UNLINK"
1951
/* Not safe. Idempotent.     RFC4918, Section 9.11. */
1952
#define MHD_HTTP_METHOD_STR_UNLOCK         "UNLOCK"
1953
/* Not safe. Idempotent.     RFC3253, Section 7.1. */
1954
#define MHD_HTTP_METHOD_STR_UPDATE         "UPDATE"
1955
/* Not safe. Idempotent.     RFC4437, Section 7. */
1956
#define MHD_HTTP_METHOD_STR_UPDATEREDIRECTREF "UPDATEREDIRECTREF"
1957
/* Not safe. Idempotent.     RFC3253, Section 3.5. */
1958
#define MHD_HTTP_METHOD_STR_VERSION_CONTROL "VERSION-CONTROL"
1959
1960
/** @} */ /* end of group methods */
1961
1962
#ifndef MHD_HTTP_POSTENCODING_DEFINED
1963
1964
1965
/**
1966
 * @brief Possible encodings for HTML forms submitted as HTTP POST requests
1967
 *
1968
 * @defgroup postenc HTTP POST encodings
1969
 * See also: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-2
1970
 * @{
1971
 */
1972
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_HTTP_PostEncoding
1973
{
1974
  /**
1975
   * No post encoding / broken data / unknown encoding
1976
   */
1977
  MHD_HTTP_POST_ENCODING_OTHER = 0
1978
  ,
1979
  /**
1980
   * "application/x-www-form-urlencoded"
1981
   * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#url-encoded-form-data
1982
   * See https://url.spec.whatwg.org/#application/x-www-form-urlencoded
1983
   * See https://datatracker.ietf.org/doc/html/rfc3986#section-2
1984
   */
1985
  MHD_HTTP_POST_ENCODING_FORM_URLENCODED = 1
1986
  ,
1987
  /**
1988
   * "multipart/form-data"
1989
   * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data
1990
   * See https://www.rfc-editor.org/rfc/rfc7578.html
1991
   */
1992
  MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA = 2
1993
  ,
1994
  /**
1995
   * "text/plain"
1996
   * Introduced by HTML5
1997
   * See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
1998
   * @warning Format is ambiguous. Do not use unless there is a very strong reason.
1999
   */
2000
  MHD_HTTP_POST_ENCODING_TEXT_PLAIN = 3
2001
};
2002
2003
2004
/** @} */ /* end of group postenc */
2005
2006
#define MHD_HTTP_POSTENCODING_DEFINED 1
2007
#endif /* ! MHD_HTTP_POSTENCODING_DEFINED */
2008
2009
2010
/**
2011
 * @brief Standard headers found in HTTP requests and responses.
2012
 *
2013
 * See: https://www.iana.org/assignments/http-fields/http-fields.xhtml
2014
 *
2015
 * @defgroup headers HTTP headers
2016
 * Registry export date: 2023-10-02
2017
 * @{
2018
 */
2019
2020
/* Main HTTP headers. */
2021
/* Permanent.     RFC9110, Section 12.5.1: HTTP Semantics */
2022
#define MHD_HTTP_HEADER_ACCEPT       "Accept"
2023
/* Deprecated.    RFC9110, Section 12.5.2: HTTP Semantics */
2024
#define MHD_HTTP_HEADER_ACCEPT_CHARSET "Accept-Charset"
2025
/* Permanent.     RFC9110, Section 12.5.3: HTTP Semantics */
2026
#define MHD_HTTP_HEADER_ACCEPT_ENCODING "Accept-Encoding"
2027
/* Permanent.     RFC9110, Section 12.5.4: HTTP Semantics */
2028
#define MHD_HTTP_HEADER_ACCEPT_LANGUAGE "Accept-Language"
2029
/* Permanent.     RFC9110, Section 14.3: HTTP Semantics */
2030
#define MHD_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges"
2031
/* Permanent.     RFC9111, Section 5.1: HTTP Caching */
2032
#define MHD_HTTP_HEADER_AGE          "Age"
2033
/* Permanent.     RFC9110, Section 10.2.1: HTTP Semantics */
2034
#define MHD_HTTP_HEADER_ALLOW        "Allow"
2035
/* Permanent.     RFC9110, Section 11.6.3: HTTP Semantics */
2036
#define MHD_HTTP_HEADER_AUTHENTICATION_INFO "Authentication-Info"
2037
/* Permanent.     RFC9110, Section 11.6.2: HTTP Semantics */
2038
#define MHD_HTTP_HEADER_AUTHORIZATION "Authorization"
2039
/* Permanent.     RFC9111, Section 5.2 */
2040
#define MHD_HTTP_HEADER_CACHE_CONTROL "Cache-Control"
2041
/* Permanent.     RFC9112, Section 9.6: HTTP/1.1 */
2042
#define MHD_HTTP_HEADER_CLOSE        "Close"
2043
/* Permanent.     RFC9110, Section 7.6.1: HTTP Semantics */
2044
#define MHD_HTTP_HEADER_CONNECTION   "Connection"
2045
/* Permanent.     RFC9110, Section 8.4: HTTP Semantics */
2046
#define MHD_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding"
2047
/* Permanent.     RFC9110, Section 8.5: HTTP Semantics */
2048
#define MHD_HTTP_HEADER_CONTENT_LANGUAGE "Content-Language"
2049
/* Permanent.     RFC9110, Section 8.6: HTTP Semantics */
2050
#define MHD_HTTP_HEADER_CONTENT_LENGTH "Content-Length"
2051
/* Permanent.     RFC9110, Section 8.7: HTTP Semantics */
2052
#define MHD_HTTP_HEADER_CONTENT_LOCATION "Content-Location"
2053
/* Permanent.     RFC9110, Section 14.4: HTTP Semantics */
2054
#define MHD_HTTP_HEADER_CONTENT_RANGE "Content-Range"
2055
/* Permanent.     RFC9110, Section 8.3: HTTP Semantics */
2056
#define MHD_HTTP_HEADER_CONTENT_TYPE "Content-Type"
2057
/* Permanent.     RFC9110, Section 6.6.1: HTTP Semantics */
2058
#define MHD_HTTP_HEADER_DATE         "Date"
2059
/* Permanent.     RFC9110, Section 8.8.3: HTTP Semantics */
2060
#define MHD_HTTP_HEADER_ETAG         "ETag"
2061
/* Permanent.     RFC9110, Section 10.1.1: HTTP Semantics */
2062
#define MHD_HTTP_HEADER_EXPECT       "Expect"
2063
/* Permanent.     RFC9111, Section 5.3: HTTP Caching */
2064
#define MHD_HTTP_HEADER_EXPIRES      "Expires"
2065
/* Permanent.     RFC9110, Section 10.1.2: HTTP Semantics */
2066
#define MHD_HTTP_HEADER_FROM         "From"
2067
/* Permanent.     RFC9110, Section 7.2: HTTP Semantics */
2068
59
#define MHD_HTTP_HEADER_HOST         "Host"
2069
/* Permanent.     RFC9110, Section 13.1.1: HTTP Semantics */
2070
#define MHD_HTTP_HEADER_IF_MATCH     "If-Match"
2071
/* Permanent.     RFC9110, Section 13.1.3: HTTP Semantics */
2072
#define MHD_HTTP_HEADER_IF_MODIFIED_SINCE "If-Modified-Since"
2073
/* Permanent.     RFC9110, Section 13.1.2: HTTP Semantics */
2074
#define MHD_HTTP_HEADER_IF_NONE_MATCH "If-None-Match"
2075
/* Permanent.     RFC9110, Section 13.1.5: HTTP Semantics */
2076
#define MHD_HTTP_HEADER_IF_RANGE     "If-Range"
2077
/* Permanent.     RFC9110, Section 13.1.4: HTTP Semantics */
2078
#define MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since"
2079
/* Permanent.     RFC9110, Section 8.8.2: HTTP Semantics */
2080
#define MHD_HTTP_HEADER_LAST_MODIFIED "Last-Modified"
2081
/* Permanent.     RFC9110, Section 10.2.2: HTTP Semantics */
2082
0
#define MHD_HTTP_HEADER_LOCATION     "Location"
2083
/* Permanent.     RFC9110, Section 7.6.2: HTTP Semantics */
2084
#define MHD_HTTP_HEADER_MAX_FORWARDS "Max-Forwards"
2085
/* Permanent.     RFC9112, Appendix B.1: HTTP/1.1 */
2086
#define MHD_HTTP_HEADER_MIME_VERSION "MIME-Version"
2087
/* Deprecated.    RFC9111, Section 5.4: HTTP Caching */
2088
#define MHD_HTTP_HEADER_PRAGMA       "Pragma"
2089
/* Permanent.     RFC9110, Section 11.7.1: HTTP Semantics */
2090
#define MHD_HTTP_HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate"
2091
/* Permanent.     RFC9110, Section 11.7.3: HTTP Semantics */
2092
#define MHD_HTTP_HEADER_PROXY_AUTHENTICATION_INFO "Proxy-Authentication-Info"
2093
/* Permanent.     RFC9110, Section 11.7.2: HTTP Semantics */
2094
#define MHD_HTTP_HEADER_PROXY_AUTHORIZATION "Proxy-Authorization"
2095
/* Permanent.     RFC9110, Section 14.2: HTTP Semantics */
2096
#define MHD_HTTP_HEADER_RANGE        "Range"
2097
/* Permanent.     RFC9110, Section 10.1.3: HTTP Semantics */
2098
#define MHD_HTTP_HEADER_REFERER      "Referer"
2099
/* Permanent.     RFC9110, Section 10.2.3: HTTP Semantics */
2100
#define MHD_HTTP_HEADER_RETRY_AFTER  "Retry-After"
2101
/* Permanent.     RFC9110, Section 10.2.4: HTTP Semantics */
2102
#define MHD_HTTP_HEADER_SERVER       "Server"
2103
/* Permanent.     RFC9110, Section 10.1.4: HTTP Semantics */
2104
#define MHD_HTTP_HEADER_TE           "TE"
2105
/* Permanent.     RFC9110, Section 6.6.2: HTTP Semantics */
2106
#define MHD_HTTP_HEADER_TRAILER      "Trailer"
2107
/* Permanent.     RFC9112, Section 6.1: HTTP Semantics */
2108
#define MHD_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding"
2109
/* Permanent.     RFC9110, Section 7.8: HTTP Semantics */
2110
#define MHD_HTTP_HEADER_UPGRADE      "Upgrade"
2111
/* Permanent.     RFC9110, Section 10.1.5: HTTP Semantics */
2112
#define MHD_HTTP_HEADER_USER_AGENT   "User-Agent"
2113
/* Permanent.     RFC9110, Section 12.5.5: HTTP Semantics */
2114
#define MHD_HTTP_HEADER_VARY         "Vary"
2115
/* Permanent.     RFC9110, Section 7.6.3: HTTP Semantics */
2116
#define MHD_HTTP_HEADER_VIA          "Via"
2117
/* Permanent.     RFC9110, Section 11.6.1: HTTP Semantics */
2118
#define MHD_HTTP_HEADER_WWW_AUTHENTICATE "WWW-Authenticate"
2119
/* Permanent.     RFC9110, Section 12.5.5: HTTP Semantics */
2120
#define MHD_HTTP_HEADER_ASTERISK     "*"
2121
2122
/* Additional HTTP headers. */
2123
/* Permanent.     RFC 3229: Delta encoding in HTTP */
2124
#define MHD_HTTP_HEADER_A_IM         "A-IM"
2125
/* Permanent.     RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) */
2126
#define MHD_HTTP_HEADER_ACCEPT_ADDITIONS "Accept-Additions"
2127
/* Permanent.     RFC 8942, Section 3.1: HTTP Client Hints */
2128
#define MHD_HTTP_HEADER_ACCEPT_CH    "Accept-CH"
2129
/* Permanent.     RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */
2130
#define MHD_HTTP_HEADER_ACCEPT_DATETIME "Accept-Datetime"
2131
/* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
2132
#define MHD_HTTP_HEADER_ACCEPT_FEATURES "Accept-Features"
2133
/* Permanent.     RFC 5789: PATCH Method for HTTP */
2134
#define MHD_HTTP_HEADER_ACCEPT_PATCH "Accept-Patch"
2135
/* Permanent.     Linked Data Platform 1.0 */
2136
#define MHD_HTTP_HEADER_ACCEPT_POST  "Accept-Post"
2137
/* Permanent.     RFC-ietf-httpbis-message-signatures-19, Section 5.1: HTTP Message Signatures */
2138
#define MHD_HTTP_HEADER_ACCEPT_SIGNATURE "Accept-Signature"
2139
/* Permanent.     Fetch */
2140
#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS \
2141
        "Access-Control-Allow-Credentials"
2142
/* Permanent.     Fetch */
2143
#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS \
2144
        "Access-Control-Allow-Headers"
2145
/* Permanent.     Fetch */
2146
#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_METHODS \
2147
        "Access-Control-Allow-Methods"
2148
/* Permanent.     Fetch */
2149
#define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN \
2150
        "Access-Control-Allow-Origin"
2151
/* Permanent.     Fetch */
2152
#define MHD_HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS \
2153
        "Access-Control-Expose-Headers"
2154
/* Permanent.     Fetch */
2155
#define MHD_HTTP_HEADER_ACCESS_CONTROL_MAX_AGE "Access-Control-Max-Age"
2156
/* Permanent.     Fetch */
2157
#define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_HEADERS \
2158
        "Access-Control-Request-Headers"
2159
/* Permanent.     Fetch */
2160
#define MHD_HTTP_HEADER_ACCESS_CONTROL_REQUEST_METHOD \
2161
        "Access-Control-Request-Method"
2162
/* Permanent.     RFC 7639, Section 2: The ALPN HTTP Header Field */
2163
#define MHD_HTTP_HEADER_ALPN         "ALPN"
2164
/* Permanent.     RFC 7838: HTTP Alternative Services */
2165
#define MHD_HTTP_HEADER_ALT_SVC      "Alt-Svc"
2166
/* Permanent.     RFC 7838: HTTP Alternative Services */
2167
#define MHD_HTTP_HEADER_ALT_USED     "Alt-Used"
2168
/* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
2169
#define MHD_HTTP_HEADER_ALTERNATES   "Alternates"
2170
/* Permanent.     RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */
2171
#define MHD_HTTP_HEADER_APPLY_TO_REDIRECT_REF "Apply-To-Redirect-Ref"
2172
/* Permanent.     RFC 8053, Section 4: HTTP Authentication Extensions for Interactive Clients */
2173
#define MHD_HTTP_HEADER_AUTHENTICATION_CONTROL "Authentication-Control"
2174
/* Permanent.     RFC9211: The Cache-Status HTTP Response Header Field */
2175
#define MHD_HTTP_HEADER_CACHE_STATUS "Cache-Status"
2176
/* Permanent.     RFC 8607, Section 5.1: Calendaring Extensions to WebDAV (CalDAV): Managed Attachments */
2177
#define MHD_HTTP_HEADER_CAL_MANAGED_ID "Cal-Managed-ID"
2178
/* Permanent.     RFC 7809, Section 7.1: Calendaring Extensions to WebDAV (CalDAV): Time Zones by Reference */
2179
#define MHD_HTTP_HEADER_CALDAV_TIMEZONES "CalDAV-Timezones"
2180
/* Permanent.     RFC9297 */
2181
#define MHD_HTTP_HEADER_CAPSULE_PROTOCOL "Capsule-Protocol"
2182
/* Permanent.     RFC9213: Targeted HTTP Cache Control */
2183
#define MHD_HTTP_HEADER_CDN_CACHE_CONTROL "CDN-Cache-Control"
2184
/* Permanent.     RFC 8586: Loop Detection in Content Delivery Networks (CDNs) */
2185
#define MHD_HTTP_HEADER_CDN_LOOP     "CDN-Loop"
2186
/* Permanent.     RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */
2187
#define MHD_HTTP_HEADER_CERT_NOT_AFTER "Cert-Not-After"
2188
/* Permanent.     RFC 8739, Section 3.3: Support for Short-Term, Automatically Renewed (STAR) Certificates in the Automated Certificate Management Environment (ACME) */
2189
#define MHD_HTTP_HEADER_CERT_NOT_BEFORE "Cert-Not-Before"
2190
/* Permanent.     Clear Site Data */
2191
#define MHD_HTTP_HEADER_CLEAR_SITE_DATA "Clear-Site-Data"
2192
/* Permanent.     RFC9440, Section 2: Client-Cert HTTP Header Field */
2193
#define MHD_HTTP_HEADER_CLIENT_CERT  "Client-Cert"
2194
/* Permanent.     RFC9440, Section 2: Client-Cert HTTP Header Field */
2195
#define MHD_HTTP_HEADER_CLIENT_CERT_CHAIN "Client-Cert-Chain"
2196
/* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 2: Digest Fields */
2197
#define MHD_HTTP_HEADER_CONTENT_DIGEST "Content-Digest"
2198
/* Permanent.     RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP) */
2199
#define MHD_HTTP_HEADER_CONTENT_DISPOSITION "Content-Disposition"
2200
/* Permanent.     The HTTP Distribution and Replication Protocol */
2201
#define MHD_HTTP_HEADER_CONTENT_ID   "Content-ID"
2202
/* Permanent.     Content Security Policy Level 3 */
2203
#define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY "Content-Security-Policy"
2204
/* Permanent.     Content Security Policy Level 3 */
2205
#define MHD_HTTP_HEADER_CONTENT_SECURITY_POLICY_REPORT_ONLY \
2206
        "Content-Security-Policy-Report-Only"
2207
/* Permanent.     RFC 6265: HTTP State Management Mechanism */
2208
#define MHD_HTTP_HEADER_COOKIE       "Cookie"
2209
/* Permanent.     HTML */
2210
#define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY \
2211
        "Cross-Origin-Embedder-Policy"
2212
/* Permanent.     HTML */
2213
#define MHD_HTTP_HEADER_CROSS_ORIGIN_EMBEDDER_POLICY_REPORT_ONLY \
2214
        "Cross-Origin-Embedder-Policy-Report-Only"
2215
/* Permanent.     HTML */
2216
#define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY "Cross-Origin-Opener-Policy"
2217
/* Permanent.     HTML */
2218
#define MHD_HTTP_HEADER_CROSS_ORIGIN_OPENER_POLICY_REPORT_ONLY \
2219
        "Cross-Origin-Opener-Policy-Report-Only"
2220
/* Permanent.     Fetch */
2221
#define MHD_HTTP_HEADER_CROSS_ORIGIN_RESOURCE_POLICY \
2222
        "Cross-Origin-Resource-Policy"
2223
/* Permanent.     RFC 5323: Web Distributed Authoring and Versioning (WebDAV) SEARCH */
2224
#define MHD_HTTP_HEADER_DASL         "DASL"
2225
/* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
2226
#define MHD_HTTP_HEADER_DAV          "DAV"
2227
/* Permanent.     RFC 3229: Delta encoding in HTTP */
2228
#define MHD_HTTP_HEADER_DELTA_BASE   "Delta-Base"
2229
/* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
2230
#define MHD_HTTP_HEADER_DEPTH        "Depth"
2231
/* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
2232
#define MHD_HTTP_HEADER_DESTINATION  "Destination"
2233
/* Permanent.     The HTTP Distribution and Replication Protocol */
2234
#define MHD_HTTP_HEADER_DIFFERENTIAL_ID "Differential-ID"
2235
/* Permanent.     RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */
2236
#define MHD_HTTP_HEADER_DPOP         "DPoP"
2237
/* Permanent.     RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP) */
2238
#define MHD_HTTP_HEADER_DPOP_NONCE   "DPoP-Nonce"
2239
/* Permanent.     RFC 8470: Using Early Data in HTTP */
2240
#define MHD_HTTP_HEADER_EARLY_DATA   "Early-Data"
2241
/* Permanent.     RFC9163: Expect-CT Extension for HTTP */
2242
#define MHD_HTTP_HEADER_EXPECT_CT    "Expect-CT"
2243
/* Permanent.     RFC 7239: Forwarded HTTP Extension */
2244
#define MHD_HTTP_HEADER_FORWARDED    "Forwarded"
2245
/* Permanent.     RFC 7486, Section 6.1.1: HTTP Origin-Bound Authentication (HOBA) */
2246
#define MHD_HTTP_HEADER_HOBAREG      "Hobareg"
2247
/* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
2248
#define MHD_HTTP_HEADER_IF           "If"
2249
/* Permanent.      RFC 6338: Scheduling Extensions to CalDAV */
2250
#define MHD_HTTP_HEADER_IF_SCHEDULE_TAG_MATCH "If-Schedule-Tag-Match"
2251
/* Permanent.     RFC 3229: Delta encoding in HTTP */
2252
#define MHD_HTTP_HEADER_IM           "IM"
2253
/* Permanent.     RFC 8473: Token Binding over HTTP */
2254
#define MHD_HTTP_HEADER_INCLUDE_REFERRED_TOKEN_BINDING_ID \
2255
        "Include-Referred-Token-Binding-ID"
2256
/* Permanent.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
2257
#define MHD_HTTP_HEADER_KEEP_ALIVE   "Keep-Alive"
2258
/* Permanent.     RFC 3253: Versioning Extensions to WebDAV: (Web Distributed Authoring and Versioning) */
2259
#define MHD_HTTP_HEADER_LABEL        "Label"
2260
/* Permanent.     HTML */
2261
#define MHD_HTTP_HEADER_LAST_EVENT_ID "Last-Event-ID"
2262
/* Permanent.     RFC 8288: Web Linking */
2263
#define MHD_HTTP_HEADER_LINK         "Link"
2264
/* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
2265
#define MHD_HTTP_HEADER_LOCK_TOKEN   "Lock-Token"
2266
/* Permanent.     RFC 7089: HTTP Framework for Time-Based Access to Resource States -- Memento */
2267
#define MHD_HTTP_HEADER_MEMENTO_DATETIME "Memento-Datetime"
2268
/* Permanent.     RFC 2227: Simple Hit-Metering and Usage-Limiting for HTTP */
2269
#define MHD_HTTP_HEADER_METER        "Meter"
2270
/* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
2271
#define MHD_HTTP_HEADER_NEGOTIATE    "Negotiate"
2272
/* Permanent.     Network Error Logging */
2273
#define MHD_HTTP_HEADER_NEL          "NEL"
2274
/* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
2275
#define MHD_HTTP_HEADER_ODATA_ENTITYID "OData-EntityId"
2276
/* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
2277
#define MHD_HTTP_HEADER_ODATA_ISOLATION "OData-Isolation"
2278
/* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
2279
#define MHD_HTTP_HEADER_ODATA_MAXVERSION "OData-MaxVersion"
2280
/* Permanent.     OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
2281
#define MHD_HTTP_HEADER_ODATA_VERSION "OData-Version"
2282
/* Permanent.     RFC 8053, Section 3: HTTP Authentication Extensions for Interactive Clients */
2283
#define MHD_HTTP_HEADER_OPTIONAL_WWW_AUTHENTICATE "Optional-WWW-Authenticate"
2284
/* Permanent.     RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */
2285
#define MHD_HTTP_HEADER_ORDERING_TYPE "Ordering-Type"
2286
/* Permanent.     RFC 6454: The Web Origin Concept */
2287
#define MHD_HTTP_HEADER_ORIGIN       "Origin"
2288
/* Permanent.     HTML */
2289
#define MHD_HTTP_HEADER_ORIGIN_AGENT_CLUSTER "Origin-Agent-Cluster"
2290
/* Permanent.     RFC 8613, Section 11.1: Object Security for Constrained RESTful Environments (OSCORE) */
2291
#define MHD_HTTP_HEADER_OSCORE       "OSCORE"
2292
/* Permanent.     OASIS Project Specification 01; OASIS; Chet_Ensign */
2293
#define MHD_HTTP_HEADER_OSLC_CORE_VERSION "OSLC-Core-Version"
2294
/* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
2295
#define MHD_HTTP_HEADER_OVERWRITE    "Overwrite"
2296
/* Permanent.     HTML */
2297
#define MHD_HTTP_HEADER_PING_FROM    "Ping-From"
2298
/* Permanent.     HTML */
2299
#define MHD_HTTP_HEADER_PING_TO      "Ping-To"
2300
/* Permanent.     RFC 3648: Web Distributed Authoring and Versioning (WebDAV) Ordered Collections Protocol */
2301
#define MHD_HTTP_HEADER_POSITION     "Position"
2302
/* Permanent.     RFC 7240: Prefer Header for HTTP */
2303
#define MHD_HTTP_HEADER_PREFER       "Prefer"
2304
/* Permanent.     RFC 7240: Prefer Header for HTTP */
2305
#define MHD_HTTP_HEADER_PREFERENCE_APPLIED "Preference-Applied"
2306
/* Permanent.     RFC9218: Extensible Prioritization Scheme for HTTP */
2307
#define MHD_HTTP_HEADER_PRIORITY     "Priority"
2308
/* Permanent.     RFC9209: The Proxy-Status HTTP Response Header Field */
2309
#define MHD_HTTP_HEADER_PROXY_STATUS "Proxy-Status"
2310
/* Permanent.     RFC 7469: Public Key Pinning Extension for HTTP */
2311
#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS "Public-Key-Pins"
2312
/* Permanent.     RFC 7469: Public Key Pinning Extension for HTTP */
2313
#define MHD_HTTP_HEADER_PUBLIC_KEY_PINS_REPORT_ONLY \
2314
        "Public-Key-Pins-Report-Only"
2315
/* Permanent.     RFC 4437: Web Distributed Authoring and Versioning (WebDAV) Redirect Reference Resources */
2316
#define MHD_HTTP_HEADER_REDIRECT_REF "Redirect-Ref"
2317
/* Permanent.     HTML */
2318
#define MHD_HTTP_HEADER_REFRESH      "Refresh"
2319
/* Permanent.     RFC 8555, Section 6.5.1: Automatic Certificate Management Environment (ACME) */
2320
#define MHD_HTTP_HEADER_REPLAY_NONCE "Replay-Nonce"
2321
/* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 3: Digest Fields */
2322
#define MHD_HTTP_HEADER_REPR_DIGEST  "Repr-Digest"
2323
/* Permanent.     RFC 6638: Scheduling Extensions to CalDAV */
2324
#define MHD_HTTP_HEADER_SCHEDULE_REPLY "Schedule-Reply"
2325
/* Permanent.     RFC 6338: Scheduling Extensions to CalDAV */
2326
#define MHD_HTTP_HEADER_SCHEDULE_TAG "Schedule-Tag"
2327
/* Permanent.     Fetch */
2328
#define MHD_HTTP_HEADER_SEC_PURPOSE  "Sec-Purpose"
2329
/* Permanent.     RFC 8473: Token Binding over HTTP */
2330
#define MHD_HTTP_HEADER_SEC_TOKEN_BINDING "Sec-Token-Binding"
2331
/* Permanent.     RFC 6455: The WebSocket Protocol */
2332
#define MHD_HTTP_HEADER_SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept"
2333
/* Permanent.     RFC 6455: The WebSocket Protocol */
2334
#define MHD_HTTP_HEADER_SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions"
2335
/* Permanent.     RFC 6455: The WebSocket Protocol */
2336
#define MHD_HTTP_HEADER_SEC_WEBSOCKET_KEY "Sec-WebSocket-Key"
2337
/* Permanent.     RFC 6455: The WebSocket Protocol */
2338
#define MHD_HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol"
2339
/* Permanent.     RFC 6455: The WebSocket Protocol */
2340
#define MHD_HTTP_HEADER_SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version"
2341
/* Permanent.     Server Timing */
2342
#define MHD_HTTP_HEADER_SERVER_TIMING "Server-Timing"
2343
/* Permanent.     RFC 6265: HTTP State Management Mechanism */
2344
#define MHD_HTTP_HEADER_SET_COOKIE   "Set-Cookie"
2345
/* Permanent.     RFC-ietf-httpbis-message-signatures-19, Section 4.2: HTTP Message Signatures */
2346
#define MHD_HTTP_HEADER_SIGNATURE    "Signature"
2347
/* Permanent.     RFC-ietf-httpbis-message-signatures-19, Section 4.1: HTTP Message Signatures */
2348
#define MHD_HTTP_HEADER_SIGNATURE_INPUT "Signature-Input"
2349
/* Permanent.     RFC 5023: The Atom Publishing Protocol */
2350
#define MHD_HTTP_HEADER_SLUG         "SLUG"
2351
/* Permanent.     Simple Object Access Protocol (SOAP) 1.1 */
2352
#define MHD_HTTP_HEADER_SOAPACTION   "SoapAction"
2353
/* Permanent.     RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV */
2354
#define MHD_HTTP_HEADER_STATUS_URI   "Status-URI"
2355
/* Permanent.     RFC 6797: HTTP Strict Transport Security (HSTS) */
2356
#define MHD_HTTP_HEADER_STRICT_TRANSPORT_SECURITY "Strict-Transport-Security"
2357
/* Permanent.     RFC 8594: The Sunset HTTP Header Field */
2358
#define MHD_HTTP_HEADER_SUNSET       "Sunset"
2359
/* Permanent.     Edge Architecture Specification */
2360
#define MHD_HTTP_HEADER_SURROGATE_CAPABILITY "Surrogate-Capability"
2361
/* Permanent.     Edge Architecture Specification */
2362
#define MHD_HTTP_HEADER_SURROGATE_CONTROL "Surrogate-Control"
2363
/* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
2364
#define MHD_HTTP_HEADER_TCN          "TCN"
2365
/* Permanent.     RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) */
2366
#define MHD_HTTP_HEADER_TIMEOUT      "Timeout"
2367
/* Permanent.     RFC 8030, Section 5.4: Generic Event Delivery Using HTTP Push */
2368
#define MHD_HTTP_HEADER_TOPIC        "Topic"
2369
/* Permanent.     Trace Context */
2370
#define MHD_HTTP_HEADER_TRACEPARENT  "Traceparent"
2371
/* Permanent.     Trace Context */
2372
#define MHD_HTTP_HEADER_TRACESTATE   "Tracestate"
2373
/* Permanent.     RFC 8030, Section 5.2: Generic Event Delivery Using HTTP Push */
2374
#define MHD_HTTP_HEADER_TTL          "TTL"
2375
/* Permanent.     RFC 8030, Section 5.3: Generic Event Delivery Using HTTP Push */
2376
#define MHD_HTTP_HEADER_URGENCY      "Urgency"
2377
/* Permanent.     RFC 2295: Transparent Content Negotiation in HTTP */
2378
#define MHD_HTTP_HEADER_VARIANT_VARY "Variant-Vary"
2379
/* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */
2380
#define MHD_HTTP_HEADER_WANT_CONTENT_DIGEST "Want-Content-Digest"
2381
/* Permanent.     RFC-ietf-httpbis-digest-headers-13, Section 4: Digest Fields */
2382
#define MHD_HTTP_HEADER_WANT_REPR_DIGEST "Want-Repr-Digest"
2383
/* Permanent.     Fetch */
2384
#define MHD_HTTP_HEADER_X_CONTENT_TYPE_OPTIONS "X-Content-Type-Options"
2385
/* Permanent.     HTML */
2386
#define MHD_HTTP_HEADER_X_FRAME_OPTIONS "X-Frame-Options"
2387
/* Provisional.   AMP-Cache-Transform HTTP request header */
2388
#define MHD_HTTP_HEADER_AMP_CACHE_TRANSFORM "AMP-Cache-Transform"
2389
/* Provisional.   OSLC Configuration Management Version 1.0. Part 3: Configuration Specification */
2390
#define MHD_HTTP_HEADER_CONFIGURATION_CONTEXT "Configuration-Context"
2391
/* Provisional.   RFC 6017: Electronic Data Interchange - Internet Integration (EDIINT) Features Header Field */
2392
#define MHD_HTTP_HEADER_EDIINT_FEATURES "EDIINT-Features"
2393
/* Provisional.   OData Version 4.01 Part 1: Protocol; OASIS; Chet_Ensign */
2394
#define MHD_HTTP_HEADER_ISOLATION    "Isolation"
2395
/* Provisional.   Permissions Policy */
2396
#define MHD_HTTP_HEADER_PERMISSIONS_POLICY "Permissions-Policy"
2397
/* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
2398
#define MHD_HTTP_HEADER_REPEATABILITY_CLIENT_ID "Repeatability-Client-ID"
2399
/* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
2400
#define MHD_HTTP_HEADER_REPEATABILITY_FIRST_SENT "Repeatability-First-Sent"
2401
/* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
2402
#define MHD_HTTP_HEADER_REPEATABILITY_REQUEST_ID "Repeatability-Request-ID"
2403
/* Provisional.   Repeatable Requests Version 1.0; OASIS; Chet_Ensign */
2404
#define MHD_HTTP_HEADER_REPEATABILITY_RESULT "Repeatability-Result"
2405
/* Provisional.   Reporting API */
2406
#define MHD_HTTP_HEADER_REPORTING_ENDPOINTS "Reporting-Endpoints"
2407
/* Provisional.   Global Privacy Control (GPC) */
2408
#define MHD_HTTP_HEADER_SEC_GPC      "Sec-GPC"
2409
/* Provisional.   Resource Timing Level 1 */
2410
#define MHD_HTTP_HEADER_TIMING_ALLOW_ORIGIN "Timing-Allow-Origin"
2411
/* Deprecated.    PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */
2412
#define MHD_HTTP_HEADER_C_PEP_INFO   "C-PEP-Info"
2413
/* Deprecated.    White Paper: Joint Electronic Payment Initiative */
2414
#define MHD_HTTP_HEADER_PROTOCOL_INFO "Protocol-Info"
2415
/* Deprecated.    White Paper: Joint Electronic Payment Initiative */
2416
#define MHD_HTTP_HEADER_PROTOCOL_QUERY "Protocol-Query"
2417
/* Obsoleted.     Access Control for Cross-site Requests */
2418
#define MHD_HTTP_HEADER_ACCESS_CONTROL "Access-Control"
2419
/* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
2420
#define MHD_HTTP_HEADER_C_EXT        "C-Ext"
2421
/* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
2422
#define MHD_HTTP_HEADER_C_MAN        "C-Man"
2423
/* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
2424
#define MHD_HTTP_HEADER_C_OPT        "C-Opt"
2425
/* Obsoleted.     PEP - an Extension Mechanism for HTTP; status-change-http-experiments-to-historic */
2426
#define MHD_HTTP_HEADER_C_PEP        "C-PEP"
2427
/* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1; RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1 */
2428
#define MHD_HTTP_HEADER_CONTENT_BASE "Content-Base"
2429
/* Obsoleted.     RFC 2616, Section 14.15: Hypertext Transfer Protocol -- HTTP/1.1; RFC 7231, Appendix B: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content */
2430
#define MHD_HTTP_HEADER_CONTENT_MD5  "Content-MD5"
2431
/* Obsoleted.     HTML 4.01 Specification */
2432
#define MHD_HTTP_HEADER_CONTENT_SCRIPT_TYPE "Content-Script-Type"
2433
/* Obsoleted.     HTML 4.01 Specification */
2434
#define MHD_HTTP_HEADER_CONTENT_STYLE_TYPE "Content-Style-Type"
2435
/* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
2436
#define MHD_HTTP_HEADER_CONTENT_VERSION "Content-Version"
2437
/* Obsoleted.     RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */
2438
#define MHD_HTTP_HEADER_COOKIE2      "Cookie2"
2439
/* Obsoleted.     HTML 4.01 Specification */
2440
#define MHD_HTTP_HEADER_DEFAULT_STYLE "Default-Style"
2441
/* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
2442
#define MHD_HTTP_HEADER_DERIVED_FROM "Derived-From"
2443
/* Obsoleted.     RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */
2444
#define MHD_HTTP_HEADER_DIGEST       "Digest"
2445
/* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
2446
#define MHD_HTTP_HEADER_EXT          "Ext"
2447
/* Obsoleted.     Implementation of OPS Over HTTP */
2448
#define MHD_HTTP_HEADER_GETPROFILE   "GetProfile"
2449
/* Obsoleted.     RFC 7540, Section 3.2.1: Hypertext Transfer Protocol Version 2 (HTTP/2) */
2450
#define MHD_HTTP_HEADER_HTTP2_SETTINGS "HTTP2-Settings"
2451
/* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
2452
#define MHD_HTTP_HEADER_MAN          "Man"
2453
/* Obsoleted.     Access Control for Cross-site Requests */
2454
#define MHD_HTTP_HEADER_METHOD_CHECK "Method-Check"
2455
/* Obsoleted.     Access Control for Cross-site Requests */
2456
#define MHD_HTTP_HEADER_METHOD_CHECK_EXPIRES "Method-Check-Expires"
2457
/* Obsoleted.     RFC 2774: An HTTP Extension Framework; status-change-http-experiments-to-historic */
2458
#define MHD_HTTP_HEADER_OPT          "Opt"
2459
/* Obsoleted.     The Platform for Privacy Preferences 1.0 (P3P1.0) Specification */
2460
#define MHD_HTTP_HEADER_P3P          "P3P"
2461
/* Obsoleted.     PEP - an Extension Mechanism for HTTP */
2462
#define MHD_HTTP_HEADER_PEP          "PEP"
2463
/* Obsoleted.     PEP - an Extension Mechanism for HTTP */
2464
#define MHD_HTTP_HEADER_PEP_INFO     "Pep-Info"
2465
/* Obsoleted.     PICS Label Distribution Label Syntax and Communication Protocols */
2466
#define MHD_HTTP_HEADER_PICS_LABEL   "PICS-Label"
2467
/* Obsoleted.     Implementation of OPS Over HTTP */
2468
#define MHD_HTTP_HEADER_PROFILEOBJECT "ProfileObject"
2469
/* Obsoleted.     PICS Label Distribution Label Syntax and Communication Protocols */
2470
#define MHD_HTTP_HEADER_PROTOCOL     "Protocol"
2471
/* Obsoleted.     PICS Label Distribution Label Syntax and Communication Protocols */
2472
#define MHD_HTTP_HEADER_PROTOCOL_REQUEST "Protocol-Request"
2473
/* Obsoleted.     Notification for Proxy Caches */
2474
#define MHD_HTTP_HEADER_PROXY_FEATURES "Proxy-Features"
2475
/* Obsoleted.     Notification for Proxy Caches */
2476
#define MHD_HTTP_HEADER_PROXY_INSTRUCTION "Proxy-Instruction"
2477
/* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
2478
#define MHD_HTTP_HEADER_PUBLIC       "Public"
2479
/* Obsoleted.     Access Control for Cross-site Requests */
2480
#define MHD_HTTP_HEADER_REFERER_ROOT "Referer-Root"
2481
/* Obsoleted.     RFC 2310: The Safe Response Header Field; status-change-http-experiments-to-historic */
2482
#define MHD_HTTP_HEADER_SAFE         "Safe"
2483
/* Obsoleted.     RFC 2660: The Secure HyperText Transfer Protocol; status-change-http-experiments-to-historic */
2484
#define MHD_HTTP_HEADER_SECURITY_SCHEME "Security-Scheme"
2485
/* Obsoleted.     RFC 2965: HTTP State Management Mechanism; RFC 6265: HTTP State Management Mechanism */
2486
#define MHD_HTTP_HEADER_SET_COOKIE2  "Set-Cookie2"
2487
/* Obsoleted.     Implementation of OPS Over HTTP */
2488
#define MHD_HTTP_HEADER_SETPROFILE   "SetProfile"
2489
/* Obsoleted.     RFC 2068: Hypertext Transfer Protocol -- HTTP/1.1 */
2490
#define MHD_HTTP_HEADER_URI          "URI"
2491
/* Obsoleted.     RFC 3230: Instance Digests in HTTP; RFC-ietf-httpbis-digest-headers-13, Section 1.3: Digest Fields */
2492
#define MHD_HTTP_HEADER_WANT_DIGEST  "Want-Digest"
2493
/* Obsoleted.     RFC9111, Section 5.5: HTTP Caching */
2494
#define MHD_HTTP_HEADER_WARNING      "Warning"
2495
2496
/* Headers removed from the registry. Do not use! */
2497
/* Obsoleted.     RFC4229 */
2498
#define MHD_HTTP_HEADER_COMPLIANCE   "Compliance"
2499
/* Obsoleted.     RFC4229 */
2500
#define MHD_HTTP_HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding"
2501
/* Obsoleted.     RFC4229 */
2502
#define MHD_HTTP_HEADER_COST         "Cost"
2503
/* Obsoleted.     RFC4229 */
2504
#define MHD_HTTP_HEADER_MESSAGE_ID   "Message-ID"
2505
/* Obsoleted.     RFC4229 */
2506
#define MHD_HTTP_HEADER_NON_COMPLIANCE "Non-Compliance"
2507
/* Obsoleted.     RFC4229 */
2508
#define MHD_HTTP_HEADER_OPTIONAL     "Optional"
2509
/* Obsoleted.     RFC4229 */
2510
#define MHD_HTTP_HEADER_RESOLUTION_HINT "Resolution-Hint"
2511
/* Obsoleted.     RFC4229 */
2512
#define MHD_HTTP_HEADER_RESOLVER_LOCATION "Resolver-Location"
2513
/* Obsoleted.     RFC4229 */
2514
#define MHD_HTTP_HEADER_SUBOK        "SubOK"
2515
/* Obsoleted.     RFC4229 */
2516
#define MHD_HTTP_HEADER_SUBST        "Subst"
2517
/* Obsoleted.     RFC4229 */
2518
#define MHD_HTTP_HEADER_TITLE        "Title"
2519
/* Obsoleted.     RFC4229 */
2520
#define MHD_HTTP_HEADER_UA_COLOR     "UA-Color"
2521
/* Obsoleted.     RFC4229 */
2522
#define MHD_HTTP_HEADER_UA_MEDIA     "UA-Media"
2523
/* Obsoleted.     RFC4229 */
2524
#define MHD_HTTP_HEADER_UA_PIXELS    "UA-Pixels"
2525
/* Obsoleted.     RFC4229 */
2526
#define MHD_HTTP_HEADER_UA_RESOLUTION "UA-Resolution"
2527
/* Obsoleted.     RFC4229 */
2528
#define MHD_HTTP_HEADER_UA_WINDOWPIXELS "UA-Windowpixels"
2529
/* Obsoleted.     RFC4229 */
2530
#define MHD_HTTP_HEADER_VERSION      "Version"
2531
/* Obsoleted.     W3C Mobile Web Best Practices Working Group */
2532
#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT "X-Device-Accept"
2533
/* Obsoleted.     W3C Mobile Web Best Practices Working Group */
2534
#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_CHARSET "X-Device-Accept-Charset"
2535
/* Obsoleted.     W3C Mobile Web Best Practices Working Group */
2536
#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_ENCODING "X-Device-Accept-Encoding"
2537
/* Obsoleted.     W3C Mobile Web Best Practices Working Group */
2538
#define MHD_HTTP_HEADER_X_DEVICE_ACCEPT_LANGUAGE "X-Device-Accept-Language"
2539
/* Obsoleted.     W3C Mobile Web Best Practices Working Group */
2540
#define MHD_HTTP_HEADER_X_DEVICE_USER_AGENT "X-Device-User-Agent"
2541
2542
2543
/**
2544
 * Predefined list of headers
2545
 * To be filled with HPACK static data
2546
 */
2547
enum MHD_PredefinedHeader
2548
{
2549
  MHD_PREDEF_ACCEPT_CHARSET = 15,
2550
  MHD_PREDEF_ACCEPT_LANGUAGE = 17
2551
};
2552
2553
/**
2554
 * Get text version of the predefined header.
2555
 * @param stk the code of the predefined header
2556
 * @return the pointer to the text version,
2557
 *         NULL if method is MHD_HTTP_METHOD_OTHER
2558
 *         or not known.
2559
 */
2560
MHD_EXTERN_ const struct MHD_String *
2561
MHD_predef_header_to_string (enum MHD_PredefinedHeader stk)
2562
MHD_FN_CONST_;
2563
2564
/** @} */ /* end of group headers */
2565
2566
/**
2567
 * A client has requested the given url using the given method
2568
 * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
2569
 * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc).
2570
 * If @a upload_size is not zero and response action is provided by this
2571
 * callback, then upload will be discarded and the stream (the connection for
2572
 * HTTP/1.1) will be closed after sending the response.
2573
 *
2574
 * @param cls argument given together with the function
2575
 *        pointer when the handler was registered with MHD
2576
 * @param request the request object
2577
 * @param path the requested uri (without arguments after "?")
2578
 * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
2579
 *        #MHD_HTTP_METHOD_PUT, etc.)
2580
 * @param upload_size the size of the message upload content payload,
2581
 *                    #MHD_SIZE_UNKNOWN for chunked uploads (if the
2582
 *                    final chunk has not been processed yet)
2583
 * @return action how to proceed, NULL
2584
 *         if the request must be aborted due to a serious
2585
 *         error while handling the request (implies closure
2586
 *         of underling data stream, for HTTP/1.1 it means
2587
 *         socket closure).
2588
 */
2589
typedef const struct MHD_Action *
2590
(MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3)
2591
 *MHD_RequestCallback)(void *cls,
2592
                       struct MHD_Request *MHD_RESTRICT request,
2593
                       const struct MHD_String *MHD_RESTRICT path,
2594
                       enum MHD_HTTP_Method method,
2595
                       uint_fast64_t upload_size);
2596
2597
2598
/**
2599
 * Create (but do not yet start) an MHD daemon.
2600
 * Usually, various options are set before
2601
 * starting the daemon with #MHD_daemon_start().
2602
 *
2603
 * @param req_cb the function to be called for incoming requests
2604
 * @param req_cb_cls the closure for @a cb
2605
 * @return the pointer to the new object on success,
2606
 *         NULL on error (like out-of-memory)
2607
 */
2608
MHD_EXTERN_ struct MHD_Daemon *
2609
MHD_daemon_create (MHD_RequestCallback req_cb,
2610
                   void *req_cb_cls)
2611
MHD_FN_MUST_CHECK_RESULT_;
2612
2613
2614
/**
2615
 * Start a webserver.
2616
 * This function:
2617
 * + checks the combination of set options,
2618
 * + initialises the TLS library (if TLS is requested),
2619
 * + creates the listen socket (if not provided and if allowed),
2620
 * + starts the daemon internal threads (if allowed)
2621
 *
2622
 * @param[in,out] daemon daemon to start; you can no longer set
2623
 *        options on this daemon after this call!
2624
 * @return #MHD_SC_OK on success
2625
 * @ingroup daemon
2626
 */
2627
MHD_EXTERN_ enum MHD_StatusCode
2628
MHD_daemon_start (struct MHD_Daemon *daemon)
2629
MHD_FN_PAR_NONNULL_ (1) MHD_FN_MUST_CHECK_RESULT_;
2630
2631
2632
/**
2633
 * Stop accepting connections from the listening socket.  Allows
2634
 * clients to continue processing, but stops accepting new
2635
 * connections.  Note that the caller is responsible for closing the
2636
 * returned socket; however, if MHD is run using threads (anything but
2637
 * external select mode), it must not be closed until AFTER
2638
 * #MHD_daemon_destroy() has been called (as it is theoretically possible
2639
 * that an existing thread is still using it).
2640
 *
2641
 * @param[in,out] daemon the daemon to stop accepting new connections for
2642
 * @return the old listen socket on success, #MHD_INVALID_SOCKET if
2643
 *         the daemon was already not listening anymore, or
2644
 *         was never started, or has no listen socket.
2645
 * @ingroup daemon
2646
 */
2647
MHD_EXTERN_ MHD_Socket
2648
MHD_daemon_quiesce (struct MHD_Daemon *daemon)
2649
MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1);
2650
2651
2652
/**
2653
 * Shutdown and destroy an HTTP daemon.
2654
 *
2655
 * @param[in] daemon daemon to stop
2656
 * @ingroup daemon
2657
 */
2658
MHD_EXTERN_ void
2659
MHD_daemon_destroy (struct MHD_Daemon *daemon)
2660
MHD_FN_PAR_NONNULL_ALL_;
2661
2662
/* ******************* External event loop ************************ */
2663
2664
/**
2665
 * @defgroup event External network events processing
2666
 */
2667
2668
/**
2669
 * The network status of the socket.
2670
 * When set by MHD (by #MHD_SocketRegistrationUpdateCallback or
2671
 * similar) it indicates a request to watch for specific socket state:
2672
 * watch for readiness for receiving the data, watch for readiness for sending
2673
 * the data and/or watch for exception state of the socket.
2674
 * When set by application (and provided for #MHD_daemon_event_update() and
2675
 * similar) it must indicate the actual status of the socket.
2676
 *
2677
 * Any actual state is a bitwise OR combination of #MHD_FD_STATE_RECV,
2678
 * #MHD_FD_STATE_SEND, #MHD_FD_STATE_EXCEPT.
2679
 * @ingroup event
2680
 */
2681
enum MHD_FIXED_ENUM_ MHD_FdState
2682
{
2683
  /**
2684
   * The socket is not ready for receiving or sending and
2685
   * does not have any exceptional state.
2686
   * The state never set by MHD, except de-registration of the sockets
2687
   * in a #MHD_SocketRegistrationUpdateCallback.
2688
   */
2689
  MHD_FD_STATE_NONE = 0
2690
  ,
2691
  /* ** Three bit-flags ** */
2692
2693
  /**
2694
   * Indicates that socket should be watched for incoming data
2695
   * (when set by #MHD_SocketRegistrationUpdateCallback)
2696
   * / socket has incoming data ready to read (when used for
2697
   * #MHD_daemon_event_update())
2698
   */
2699
  MHD_FD_STATE_RECV = 1 << 0
2700
  ,
2701
  /**
2702
   * Indicates that socket should be watched for availability for sending
2703
   * (when set by #MHD_SocketRegistrationUpdateCallback)
2704
   * / socket has ability to send data (when used for
2705
   * #MHD_daemon_event_update())
2706
   */
2707
  MHD_FD_STATE_SEND = 1 << 1
2708
  ,
2709
  /**
2710
   * Indicates that socket should be watched for disconnect, out-of-band
2711
   * data available or high priority data available (when set by
2712
   * #MHD_SocketRegistrationUpdateCallback)
2713
   * / socket has been disconnected, has out-of-band data available or
2714
   * has high priority data available (when used for
2715
   * #MHD_daemon_event_update()). This status must not include "remote
2716
   * peer shut down writing" status.
2717
   * Note: #MHD_SocketRegistrationUpdateCallback() always set it as exceptions
2718
   * must be always watched.
2719
   */
2720
  MHD_FD_STATE_EXCEPT = 1 << 2
2721
  ,
2722
2723
  /* The rest of the list is a bit-wise combination of three main
2724
   * states. Application may use three main states directly as
2725
   * a bit-mask instead of using of the following values
2726
   */
2727
2728
  /**
2729
   * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_SEND states.
2730
   */
2731
  MHD_FD_STATE_RECV_SEND = MHD_FD_STATE_RECV | MHD_FD_STATE_SEND
2732
  ,
2733
  /**
2734
   * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
2735
   */
2736
  MHD_FD_STATE_RECV_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT
2737
  ,
2738
  /**
2739
   * Combination of #MHD_FD_STATE_RECV and #MHD_FD_STATE_EXCEPT states.
2740
   */
2741
  MHD_FD_STATE_SEND_EXCEPT = MHD_FD_STATE_RECV | MHD_FD_STATE_EXCEPT
2742
  ,
2743
  /**
2744
   * Combination of #MHD_FD_STATE_RECV, #MHD_FD_STATE_SEND and
2745
   * #MHD_FD_STATE_EXCEPT states.
2746
   */
2747
  MHD_FD_STATE_RECV_SEND_EXCEPT = \
2748
    MHD_FD_STATE_RECV | MHD_FD_STATE_SEND | MHD_FD_STATE_EXCEPT
2749
};
2750
2751
/**
2752
 * Checks whether specific @a state is enabled/set in the @a var
2753
 */
2754
#define MHD_FD_STATE_IS_SET(var,state)               \
2755
        (MHD_FD_STATE_NONE !=                        \
2756
         ((enum MHD_FdState) (((unsigned int) (var)) \
2757
                              & ((unsigned int) (state)))))
2758
2759
/**
2760
 * Checks whether RECV is enabled/set in the @a var
2761
 */
2762
#define MHD_FD_STATE_IS_SET_RECV(var) \
2763
        MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_RECV)
2764
/**
2765
 * Checks whether SEND is enabled/set in the @a var
2766
 */
2767
#define MHD_FD_STATE_IS_SET_SEND(var) \
2768
        MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_SEND)
2769
/**
2770
 * Checks whether EXCEPT is enabled/set in the @a var
2771
 */
2772
#define MHD_FD_STATE_IS_SET_EXCEPT(var) \
2773
        MHD_FD_STATE_IS_SET ((var),MHD_FD_STATE_EXCEPT)
2774
2775
2776
/**
2777
 * Set/enable specific @a state in the @a var
2778
 */
2779
#define MHD_FD_STATE_SET(var,state) \
2780
        ((var) =                    \
2781
           (enum MHD_FdState) (((unsigned int) var) | ((unsigned int) state)))
2782
/**
2783
 * Set/enable RECV state in the @a var
2784
 */
2785
#define MHD_FD_STATE_SET_RECV(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_RECV)
2786
/**
2787
 * Set/enable SEND state in the @a var
2788
 */
2789
#define MHD_FD_STATE_SET_SEND(var) MHD_FD_STATE_SET ((var),MHD_FD_STATE_SEND)
2790
/**
2791
 * Set/enable EXCEPT state in the @a var
2792
 */
2793
#define MHD_FD_STATE_SET_EXCEPT(var) \
2794
        MHD_FD_STATE_SET ((var),MHD_FD_STATE_EXCEPT)
2795
2796
/**
2797
 * Clear/disable specific @a state in the @a var
2798
 */
2799
#define MHD_FD_STATE_CLEAR(var,state) \
2800
        ( (var) =                     \
2801
            (enum MHD_FdState)        \
2802
            (((unsigned int) var)     \
2803
             & ((enum MHD_FdState) (~((unsigned int) state)))) \
2804
        )
2805
/**
2806
 * Clear/disable RECV state in the @a var
2807
 */
2808
#define MHD_FD_STATE_CLEAR_RECV(var) \
2809
        MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_RECV)
2810
/**
2811
 * Clear/disable SEND state in the @a var
2812
 */
2813
#define MHD_FD_STATE_CLEAR_SEND(var) \
2814
        MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_SEND)
2815
/**
2816
 * Clear/disable EXCEPT state in the @a var
2817
 */
2818
#define MHD_FD_STATE_CLEAR_EXCEPT(var) \
2819
        MHD_FD_STATE_CLEAR ((var),MHD_FD_STATE_EXCEPT)
2820
2821
2822
/**
2823
 * The context data to be used for updates of the socket state
2824
 */
2825
struct MHD_EventUpdateContext;
2826
2827
2828
/* Define MHD_APP_SOCKET_CNTX_TYPE to the socket context type before
2829
 * including this header.
2830
 * This is optional, but improves the types safety.
2831
 * For example:
2832
 * #define MHD_APP_SOCKET_CNTX_TYPE struct my_structure
2833
 */
2834
#ifndef MHD_APP_SOCKET_CNTX_TYPE
2835
#  define MHD_APP_SOCKET_CNTX_TYPE void
2836
#endif
2837
2838
/**
2839
 * The callback for registration/de-registration of the sockets to watch.
2840
 *
2841
 * This callback must not call #MHD_daemon_destroy(), #MHD_daemon_quiesce(),
2842
 * #MHD_daemon_add_connection().
2843
 *
2844
 * @param cls the closure
2845
 * @param fd the socket to watch
2846
 * @param watch_for the states of the @a fd to watch, if set to
2847
 *                  #MHD_FD_STATE_NONE the socket must be de-registred
2848
 * @param app_cntx_old the old application defined context for the socket,
2849
 *                     NULL if @a fd socket was not registered before
2850
 * @param ecb_cntx the context handle to be used
2851
 *                 with #MHD_daemon_event_update()
2852
 * @return must be NULL for the removed (de-registred) sockets,
2853
 *         for new and updated sockets: NULL in case of error (the connection
2854
 *         will be aborted or daemon failed to start if FD does not belong to
2855
 *         connection)
2856
 *         or the new socket context (opaque for MHD, must be non-NULL)
2857
 * @sa #MHD_D_OPTION_REREGISTER_ALL
2858
 * @ingroup event
2859
 */
2860
typedef MHD_APP_SOCKET_CNTX_TYPE *
2861
(MHD_FN_PAR_NONNULL_ (5)
2862
 *MHD_SocketRegistrationUpdateCallback)(
2863
  void *cls,
2864
  MHD_Socket fd,
2865
  enum MHD_FdState watch_for,
2866
  MHD_APP_SOCKET_CNTX_TYPE *app_cntx_old,
2867
  struct MHD_EventUpdateContext *ecb_cntx);
2868
2869
2870
/**
2871
 * Update the sockets state.
2872
 * Must be called for every socket that got state updated.
2873
 * For #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL() mode
2874
 * this function must be called for each socket between any two calls of
2875
 * #MHD_daemon_process_reg_events() function.
2876
 * Available only for daemons started in
2877
 * #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
2878
 * #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
2879
 * @param daemon the daemon handle
2880
 * @param ecb_cntx the context handle provided
2881
 *                 for #MHD_SocketRegistrationUpdateCallback
2882
 * @param fd_current_state the current state of the socket
2883
 * @ingroup event
2884
 */
2885
MHD_EXTERN_ void
2886
MHD_daemon_event_update (
2887
  struct MHD_Daemon *MHD_RESTRICT daemon,
2888
  struct MHD_EventUpdateContext *MHD_RESTRICT ecb_cntx,
2889
  enum MHD_FdState fd_current_state)
2890
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2);
2891
2892
2893
/**
2894
 * Perform all daemon activities based on FDs events provided earlier by
2895
 * application via #MHD_daemon_event_update().
2896
 *
2897
 * This function accepts new connections (if any), performs HTTP communications
2898
 * on all active connections, closes connections as needed and performs FDs
2899
 * registration updates by calling #MHD_SocketRegistrationUpdateCallback
2900
 * callback for every socket that needs to be added/updated/removed.
2901
 *
2902
 * Available only for daemons started in #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL or
2903
 * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes.
2904
 *
2905
 * When used in #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL mode, application must
2906
 * provide all updates by calling #MHD_daemon_event_update() for every
2907
 * registered FD between any two calls of this function.
2908
 *
2909
 * @param daemon the daemon handle
2910
 * @param[out] next_max_wait the optional pointer to receive the next maximum
2911
 *                           wait time in microseconds to be used for sockets
2912
 *                           polling function, can be NULL
2913
 * @return #MHD_SC_OK on success,
2914
 *         error code otherwise
2915
 * @sa #MHD_D_OPTION_REREGISTER_ALL
2916
 * @ingroup event
2917
 */
2918
MHD_EXTERN_ enum MHD_StatusCode
2919
MHD_daemon_process_reg_events (struct MHD_Daemon *MHD_RESTRICT daemon,
2920
                               uint_fast64_t *MHD_RESTRICT next_max_wait)
2921
MHD_FN_PAR_NONNULL_ (1);
2922
2923
/* ********************* daemon options ************** */
2924
2925
2926
/**
2927
 * Which threading and polling mode should be used by MHD?
2928
 */
2929
enum MHD_FIXED_ENUM_APP_SET_ MHD_WorkMode
2930
{
2931
  /**
2932
   * Work mode with no internal threads.
2933
   * The application periodically calls #MHD_daemon_process_blocking(), where
2934
   * MHD internally checks all sockets automatically.
2935
   * This is the default mode.
2936
   * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_PERIODIC() to enable
2937
   * this mode.
2938
   */
2939
  MHD_WM_EXTERNAL_PERIODIC = 0
2940
  ,
2941
  /**
2942
   * Work mode with an external event loop with level triggers.
2943
   * MHD provides registration of all FDs to be monitored by using
2944
   * #MHD_SocketRegistrationUpdateCallback, application performs level triggered
2945
   * FDs polling (like select() or poll()), calls function
2946
   * #MHD_daemon_event_update() for every registered FD and then calls main
2947
   * function MHD_daemon_process_reg_events() to process the data.
2948
   * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL() to enable
2949
   * this mode.
2950
   * @sa #MHD_D_OPTION_REREGISTER_ALL
2951
   */
2952
  MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL = 8
2953
  ,
2954
  /**
2955
   * Work mode with an external event loop with edge triggers.
2956
   * MHD provides registration of all FDs to be monitored by using
2957
   * #MHD_SocketRegistrationUpdateCallback, application performs edge triggered
2958
   * sockets polling (like epoll with EPOLLET), calls function
2959
   * #MHD_daemon_event_update() for FDs with updated states and then calls main
2960
   * function MHD_daemon_process_reg_events() to process the data.
2961
   * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE() to enable
2962
   * this mode.
2963
   * @sa #MHD_D_OPTION_REREGISTER_ALL
2964
   */
2965
  MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE = 9
2966
  ,
2967
  /**
2968
   * Work mode with no internal threads and aggregate watch FD.
2969
   * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
2970
   * that gets triggered by any MHD event.
2971
   * This FD can be watched as an aggregate indicator for all MHD events.
2972
   * This mode is available only on selected platforms (currently
2973
   * GNU/Linux and OpenIndiana only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
2974
   * When the FD is triggered, #MHD_daemon_process_nonblocking() should
2975
   * be called.
2976
   * Use helper macro #MHD_D_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH() to enable
2977
   * this mode.
2978
   */
2979
  MHD_WM_EXTERNAL_SINGLE_FD_WATCH = 16
2980
  ,
2981
  /**
2982
   * Work mode with one or more worker threads.
2983
   * If specified number of threads is one, then daemon starts with single
2984
   * worker thread that handles all connections.
2985
   * If number of threads is larger than one, then that number of worker
2986
   * threads, and handling of connection is distributed among the workers.
2987
   * Use helper macro #MHD_D_OPTION_WM_WORKER_THREADS() to enable
2988
   * this mode.
2989
   */
2990
  MHD_WM_WORKER_THREADS = 24
2991
  ,
2992
  /**
2993
   * Work mode with one internal thread for listening and additional threads
2994
   * per every connection.  Use this if handling requests is CPU-intensive or
2995
   * blocking, your application is thread-safe and you have plenty of
2996
   * memory (per connection).
2997
   * Use helper macro #MHD_D_OPTION_WM_THREAD_PER_CONNECTION() to enable
2998
   * this mode.
2999
   */
3000
  MHD_WM_THREAD_PER_CONNECTION = 32
3001
};
3002
3003
/**
3004
 * Work mode parameters for #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL and
3005
 * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes
3006
 */
3007
struct MHD_WorkModeExternalEventLoopCBParam
3008
{
3009
  /**
3010
   * Socket registration callback
3011
   */
3012
  MHD_SocketRegistrationUpdateCallback reg_cb;
3013
  /**
3014
   * Closure for the @a reg_cb
3015
   */
3016
  void *reg_cb_cls;
3017
};
3018
3019
/**
3020
 * MHD work mode parameters
3021
 */
3022
union MHD_WorkModeParam
3023
{
3024
  /**
3025
   * Work mode parameters for #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL and
3026
   * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE modes
3027
   */
3028
  struct MHD_WorkModeExternalEventLoopCBParam v_external_event_loop_cb;
3029
  /**
3030
   * Number of worker threads for #MHD_WM_WORKER_THREADS.
3031
   * If set to one, then daemon starts with single worker thread that process
3032
   * all connections.
3033
   * If set to value larger than one, then that number of worker threads
3034
   * and distributed handling of requests among the workers.
3035
   * Zero is treated as one.
3036
   */
3037
  unsigned int num_worker_threads;
3038
};
3039
3040
/**
3041
 * Parameter for #MHD_D_O_WORK_MODE().
3042
 * Not recommended to be used directly, better use macro/functions to create it:
3043
 * #MHD_WM_OPTION_EXTERNAL_PERIODIC(),
3044
 * #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(),
3045
 * #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(),
3046
 * #MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH(),
3047
 * #MHD_WM_OPTION_WORKER_THREADS(),
3048
 * #MHD_WM_OPTION_THREAD_PER_CONNECTION()
3049
 */
3050
struct MHD_WorkModeWithParam
3051
{
3052
  /**
3053
   * The work mode for MHD
3054
   */
3055
  enum MHD_WorkMode mode;
3056
  /**
3057
   * The parameters used for specified work mode
3058
   */
3059
  union MHD_WorkModeParam params;
3060
};
3061
3062
3063
#if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)
3064
/**
3065
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3066
 * no internal threads.
3067
 * The application periodically calls #MHD_daemon_process_blocking(), where
3068
 * MHD internally checks all sockets automatically.
3069
 * This is the default mode.
3070
 * @return the object of struct MHD_WorkModeWithParam with requested values
3071
 */
3072
#  define MHD_WM_OPTION_EXTERNAL_PERIODIC()     \
3073
        MHD_NOWARN_COMPOUND_LITERALS_                 \
3074
          (const struct MHD_WorkModeWithParam)          \
3075
        {                                             \
3076
          .mode = (MHD_WM_EXTERNAL_PERIODIC)          \
3077
        }                                             \
3078
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
3079
3080
/**
3081
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3082
 * an external event loop with level triggers.
3083
 * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
3084
 * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
3085
 * @param cb_val the callback for sockets registration
3086
 * @param cb_cls_val the closure for the @a cv_val callback
3087
 * @return the object of struct MHD_WorkModeWithParam with requested values
3088
 */
3089
#  define MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(cb_val,cb_cls_val) \
3090
        MHD_NOWARN_COMPOUND_LITERALS_                                         \
3091
          (const struct MHD_WorkModeWithParam)                                  \
3092
        {                                                                     \
3093
          .mode = (MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL),                      \
3094
          .params.v_external_event_loop_cb.reg_cb = (cb_val),                 \
3095
          .params.v_external_event_loop_cb.reg_cb_cls = (cb_cls_val)          \
3096
        }                                                                     \
3097
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
3098
3099
/**
3100
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3101
 * an external event loop with edge triggers.
3102
 * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
3103
 * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
3104
 * @param cb_val the callback for sockets registration
3105
 * @param cb_cls_val the closure for the @a cv_val callback
3106
 * @return the object of struct MHD_WorkModeWithParam with requested values
3107
 */
3108
#  define MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(cb_val,cb_cls_val)  \
3109
        MHD_NOWARN_COMPOUND_LITERALS_                                         \
3110
          (const struct MHD_WorkModeWithParam)                                  \
3111
        {                                                                     \
3112
          .mode = (MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE),                       \
3113
          .params.v_external_event_loop_cb.reg_cb = (cb_val),                 \
3114
          .params.v_external_event_loop_cb.reg_cb_cls = (cb_cls_val)          \
3115
        }                                                                     \
3116
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
3117
3118
/**
3119
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3120
 * no internal threads and aggregate watch FD.
3121
 * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
3122
 * that gets triggered by any MHD event.
3123
 * This FD can be watched as an aggregate indicator for all MHD events.
3124
 * This mode is available only on selected platforms (currently
3125
 * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
3126
 * When the FD is triggered, #MHD_daemon_process_nonblocking() should
3127
 * be called.
3128
 * @return the object of struct MHD_WorkModeWithParam with requested values
3129
 */
3130
#  define MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH()      \
3131
        MHD_NOWARN_COMPOUND_LITERALS_                         \
3132
          (const struct MHD_WorkModeWithParam)                  \
3133
        {                                                     \
3134
          .mode = (MHD_WM_EXTERNAL_SINGLE_FD_WATCH)           \
3135
        }                                                     \
3136
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
3137
3138
/**
3139
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3140
 * one or more worker threads.
3141
 * If number of threads is one, then daemon starts with single worker thread
3142
 * that handles all connections.
3143
 * If number of threads is larger than one, then that number of worker threads,
3144
 * and handling of connection is distributed among the workers.
3145
 * @param num_workers the number of worker threads, zero is treated as one
3146
 * @return the object of struct MHD_WorkModeWithParam with requested values
3147
 */
3148
#  define MHD_WM_OPTION_WORKER_THREADS(num_workers)     \
3149
        MHD_NOWARN_COMPOUND_LITERALS_                         \
3150
          (const struct MHD_WorkModeWithParam)                  \
3151
        {                                                     \
3152
          .mode = (MHD_WM_WORKER_THREADS),                    \
3153
          .params.num_worker_threads = (num_workers)          \
3154
        }                                                     \
3155
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
3156
3157
/**
3158
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3159
 * one internal thread for listening and additional threads per every
3160
 * connection.  Use this if handling requests is CPU-intensive or blocking,
3161
 * your application is thread-safe and you have plenty of memory (per
3162
 * connection).
3163
 * @return the object of struct MHD_WorkModeWithParam with requested values
3164
 */
3165
#  define MHD_WM_OPTION_THREAD_PER_CONNECTION() \
3166
        MHD_NOWARN_COMPOUND_LITERALS_                 \
3167
          (const struct MHD_WorkModeWithParam)          \
3168
        {                                             \
3169
          .mode = (MHD_WM_THREAD_PER_CONNECTION)      \
3170
        }                                             \
3171
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
3172
3173
#else  /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
3174
MHD_NOWARN_UNUSED_FUNC_
3175
3176
/**
3177
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3178
 * no internal threads.
3179
 * The application periodically calls #MHD_daemon_process_blocking(), where
3180
 * MHD internally checks all sockets automatically.
3181
 * This is the default mode.
3182
 * @return the object of struct MHD_WorkModeWithParam with requested values
3183
 */
3184
static MHD_INLINE struct MHD_WorkModeWithParam
3185
MHD_WM_OPTION_EXTERNAL_PERIODIC (void)
3186
0
{
3187
0
  struct MHD_WorkModeWithParam wm_val;
3188
0
3189
0
  wm_val.mode = MHD_WM_EXTERNAL_PERIODIC;
3190
0
3191
0
  return wm_val;
3192
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_WM_OPTION_EXTERNAL_PERIODIC()
Unexecuted instantiation: connection_helper.cpp:MHD_WM_OPTION_EXTERNAL_PERIODIC()
3193
3194
3195
/**
3196
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3197
 * an external event loop with level triggers.
3198
 * Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
3199
 * sockets polling (like select() or poll()) and #MHD_daemon_event_update().
3200
 * @param cb_val the callback for sockets registration
3201
 * @param cb_cls_val the closure for the @a cv_val callback
3202
 * @return the object of struct MHD_WorkModeWithParam with requested values
3203
 */
3204
static MHD_INLINE struct MHD_WorkModeWithParam
3205
MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL (
3206
  MHD_SocketRegistrationUpdateCallback cb_val,
3207
  void *cb_cls_val)
3208
0
{
3209
0
  struct MHD_WorkModeWithParam wm_val;
3210
0
3211
0
  wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL;
3212
0
  wm_val.params.v_external_event_loop_cb.reg_cb = cb_val;
3213
0
  wm_val.params.v_external_event_loop_cb.reg_cb_cls = cb_cls_val;
3214
0
3215
0
  return wm_val;
3216
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(void* (*)(void*, int, MHD_FdState, void*, MHD_EventUpdateContext*), void*)
Unexecuted instantiation: connection_helper.cpp:MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(void* (*)(void*, int, MHD_FdState, void*, MHD_EventUpdateContext*), void*)
3217
3218
3219
/**
3220
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3221
 * an external event loop with edge triggers.
3222
 * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
3223
 * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
3224
 * @param cb_val the callback for sockets registration
3225
 * @param cb_cls_val the closure for the @a cv_val callback
3226
 * @return the object of struct MHD_WorkModeWithParam with requested values
3227
 */
3228
static MHD_INLINE struct MHD_WorkModeWithParam
3229
MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE (
3230
  MHD_SocketRegistrationUpdateCallback cb_val,
3231
  void *cb_cls_val)
3232
0
{
3233
0
  struct MHD_WorkModeWithParam wm_val;
3234
0
3235
0
  wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE;
3236
0
  wm_val.params.v_external_event_loop_cb.reg_cb = cb_val;
3237
0
  wm_val.params.v_external_event_loop_cb.reg_cb_cls = cb_cls_val;
3238
0
3239
0
  return wm_val;
3240
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(void* (*)(void*, int, MHD_FdState, void*, MHD_EventUpdateContext*), void*)
Unexecuted instantiation: connection_helper.cpp:MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(void* (*)(void*, int, MHD_FdState, void*, MHD_EventUpdateContext*), void*)
3241
3242
3243
/**
3244
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3245
 * no internal threads and aggregate watch FD.
3246
 * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
3247
 * that gets triggered by any MHD event.
3248
 * This FD can be watched as an aggregate indicator for all MHD events.
3249
 * This mode is available only on selected platforms (currently
3250
 * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
3251
 * When the FD is triggered, #MHD_daemon_process_nonblocking() should
3252
 * be called.
3253
 * @return the object of struct MHD_WorkModeWithParam with requested values
3254
 */
3255
static MHD_INLINE struct MHD_WorkModeWithParam
3256
MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH (void)
3257
0
{
3258
0
  struct MHD_WorkModeWithParam wm_val;
3259
0
3260
0
  wm_val.mode = MHD_WM_EXTERNAL_SINGLE_FD_WATCH;
3261
0
3262
0
  return wm_val;
3263
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH()
Unexecuted instantiation: connection_helper.cpp:MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH()
3264
3265
3266
/**
3267
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3268
 * one or more worker threads.
3269
 * If number of threads is one, then daemon starts with single worker thread
3270
 * that handles all connections.
3271
 * If number of threads is larger than one, then that number of worker threads,
3272
 * and handling of connection is distributed among the workers.
3273
 * @param num_workers the number of worker threads, zero is treated as one
3274
 * @return the object of struct MHD_WorkModeWithParam with requested values
3275
 */
3276
static MHD_INLINE struct MHD_WorkModeWithParam
3277
MHD_WM_OPTION_WORKER_THREADS (unsigned int num_workers)
3278
0
{
3279
0
  struct MHD_WorkModeWithParam wm_val;
3280
0
3281
0
  wm_val.mode = MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE;
3282
0
  wm_val.params.num_worker_threads = num_workers;
3283
0
3284
0
  return wm_val;
3285
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_WM_OPTION_WORKER_THREADS(unsigned int)
Unexecuted instantiation: connection_helper.cpp:MHD_WM_OPTION_WORKER_THREADS(unsigned int)
3286
3287
3288
/**
3289
 * Create parameter for #MHD_D_O_WORK_MODE() for work mode with
3290
 * one internal thread for listening and additional threads per every
3291
 * connection.  Use this if handling requests is CPU-intensive or blocking,
3292
 * your application is thread-safe and you have plenty of memory (per
3293
 * connection).
3294
 * @return the object of struct MHD_WorkModeWithParam with requested values
3295
 */
3296
static MHD_INLINE struct MHD_WorkModeWithParam
3297
MHD_WM_OPTION_THREAD_PER_CONNECTION (void)
3298
0
{
3299
0
  struct MHD_WorkModeWithParam wm_val;
3300
0
3301
0
  wm_val.mode = MHD_WM_THREAD_PER_CONNECTION;
3302
0
3303
0
  return wm_val;
3304
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_WM_OPTION_THREAD_PER_CONNECTION()
Unexecuted instantiation: connection_helper.cpp:MHD_WM_OPTION_THREAD_PER_CONNECTION()
3305
3306
3307
MHD_RESTORE_WARN_UNUSED_FUNC_
3308
#endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
3309
3310
/**
3311
 * @defgroup logging Log events and control
3312
 */
3313
3314
3315
/**
3316
 * Type of a callback function used for logging by MHD.
3317
 *
3318
 * @param cls closure
3319
 * @param sc status code of the event
3320
 * @param fm format string (`printf()`-style)
3321
 * @param ap arguments to @a fm
3322
 * @ingroup logging
3323
 */
3324
typedef void
3325
(MHD_FN_PAR_NONNULL_ (3)
3326
 MHD_FN_PAR_CSTR_ (3)
3327
 *MHD_LoggingCallback)(void *cls,
3328
                       enum MHD_StatusCode sc,
3329
                       const char *fm,
3330
                       va_list ap);
3331
3332
/**
3333
 * Parameter for listen socket binding type
3334
 */
3335
enum MHD_FIXED_ENUM_APP_SET_ MHD_DaemonOptionBindType
3336
{
3337
  /**
3338
   * The listen socket bind to the networks address with sharing the address.
3339
   * Several sockets can bind to the same address.
3340
   */
3341
  MHD_D_OPTION_BIND_TYPE_SHARED = -1
3342
  ,
3343
  /**
3344
   * The listen socket bind to the networks address without sharing the address,
3345
   * except allowing binding to port/address which has TIME_WAIT state (the
3346
   * state after closing connection).
3347
   * On some platforms it may also allow to bind to specific address if other
3348
   * socket already bond to the same port of wildcard address (or bind to
3349
   * wildcard address when other socket already bond to specific address
3350
   * with the same port).
3351
   * Typically achieved by enabling 'SO_REUSEADDR' socket option.
3352
   * Default.
3353
   */
3354
  MHD_D_OPTION_BIND_TYPE_NOT_SHARED = 0
3355
  ,
3356
  /**
3357
   * The listen socket bind to the networks address without sharing the address.
3358
   * The daemon way fail to start when any sockets still in "TIME_WAIT" state
3359
   * on the same port, which effectively prevents quick restart of the daemon
3360
   * on the same port.
3361
   * On W32 systems it works like #MHD_D_OPTION_BIND_TYPE_NOT_SHARED due to
3362
   * the OS limitations.
3363
   */
3364
  MHD_D_OPTION_BIND_TYPE_NOT_SHARED_STRICTER = 1
3365
  ,
3366
  /**
3367
   * The list socket bind to the networks address in explicit exclusive mode.
3368
   * Works as #MHD_D_OPTION_BIND_TYPE_NOT_SHARED_STRICTER on platforms without
3369
   * support for the explicit exclusive socket use.
3370
   */
3371
  MHD_D_OPTION_BIND_TYPE_EXCLUSIVE = 2
3372
};
3373
3374
3375
/**
3376
 * Possible levels of enforcement for TCP_FASTOPEN.
3377
 */
3378
enum MHD_FIXED_ENUM_APP_SET_ MHD_TCPFastOpenType
3379
{
3380
  /**
3381
   * Disable use of TCP_FASTOPEN.
3382
   */
3383
  MHD_FOM_DISABLE = -1
3384
  ,
3385
  /**
3386
   * Enable TCP_FASTOPEN where supported.
3387
   * On GNU/Linux it works with a kernel >= 3.6.
3388
   * This is the default.
3389
   */
3390
  MHD_FOM_AUTO = 0
3391
  ,
3392
  /**
3393
   * Require TCP_FASTOPEN.
3394
   * Also causes #MHD_daemon_start() to fail if TCP_FASTOPEN cannot be enabled.
3395
   */
3396
  MHD_FOM_REQUIRE = 1
3397
};
3398
3399
3400
/**
3401
 * Address family to be used by MHD.
3402
 */
3403
enum MHD_FIXED_ENUM_APP_SET_ MHD_AddressFamily
3404
{
3405
  /**
3406
   * Option not given, do not listen at all
3407
   * (unless listen socket or address specified by
3408
   * other means).
3409
   */
3410
  MHD_AF_NONE = 0
3411
  ,
3412
  /**
3413
   * Pick "best" available method automatically.
3414
   */
3415
  MHD_AF_AUTO = 1
3416
  ,
3417
  /**
3418
   * Use IPv4 only.
3419
   */
3420
  MHD_AF_INET4 = 2
3421
  ,
3422
  /**
3423
   * Use IPv6 only.
3424
   */
3425
  MHD_AF_INET6 = 3
3426
  ,
3427
  /**
3428
   * Use dual stack (IPv4 and IPv6 on the same socket).
3429
   */
3430
  MHD_AF_DUAL = 4
3431
  ,
3432
  /**
3433
   * Use dual stack (IPv4 and IPv6 on the same socket),
3434
   * fallback to pure IPv6 if dual stack is not possible.
3435
   */
3436
  MHD_AF_DUAL_v4_OPTIONAL = 5
3437
  ,
3438
  /**
3439
   * Use dual stack (IPv4 and IPv6 on the same socket),
3440
   * fallback to pure IPv4 if dual stack is not possible.
3441
   */
3442
  MHD_AF_DUAL_v6_OPTIONAL = 6
3443
3444
};
3445
3446
3447
/**
3448
 * Sockets polling internal syscalls used by MHD.
3449
 */
3450
enum MHD_FIXED_ENUM_APP_SET_ MHD_SockPollSyscall
3451
{
3452
  /**
3453
   * Automatic selection of best-available method. This is also the
3454
   * default.
3455
   */
3456
  MHD_SPS_AUTO = 0
3457
  ,
3458
  /**
3459
   * Use select().
3460
   */
3461
  MHD_SPS_SELECT = 1
3462
  ,
3463
  /**
3464
   * Use poll().
3465
   */
3466
  MHD_SPS_POLL = 2
3467
  ,
3468
  /**
3469
   * Use epoll.
3470
   */
3471
  MHD_SPS_EPOLL = 3
3472
};
3473
3474
3475
/**
3476
 * Protocol strictness levels enforced by MHD on clients.
3477
 * Each level applies different parsing settings for HTTP headers and other
3478
 * protocol elements.
3479
 */
3480
enum MHD_FIXED_ENUM_APP_SET_ MHD_ProtocolStrictLevel
3481
{
3482
3483
  /* * Basic levels * */
3484
  /**
3485
   * A sane default level of protocol enforcement for production use.
3486
   * Provides a balance between enhanced security and broader compatibility,
3487
   * as permitted by RFCs for HTTP servers.
3488
   */
3489
  MHD_PSL_DEFAULT = 0
3490
  ,
3491
  /**
3492
   * Apply stricter protocol interpretation while remaining within
3493
   * RFC-defined limits for HTTP servers.
3494
   *
3495
   * At this level (and stricter), using a bare LF instead of CRLF is forbidden,
3496
   * and requests that include both a "Transfer-Encoding:" and
3497
   * a "Content-Length:" headers are rejected.
3498
   *
3499
   * Suitable for public servers.
3500
   */
3501
  MHD_PSL_STRICT = 1
3502
  ,
3503
  /**
3504
   * Be more permissive in interpreting the protocol, while still
3505
   * operating within the RFC-defined limits for HTTP servers.
3506
   */
3507
  MHD_PSL_PERMISSIVE = -1
3508
  ,
3509
  /* * Special levels * */
3510
  /**
3511
   * A stricter protocol interpretation than what is allowed by RFCs for HTTP
3512
   * servers. However, it should remain fully compatible with clients correctly
3513
   * following all RFC "MUST" requirements for HTTP clients.
3514
   *
3515
   * For chunked encoding, this level (and more restrictive ones) forbids
3516
   * whitespace in chunk extensions.
3517
   * For cookie parsing, this level (and more restrictive ones) rejects
3518
   * the entire cookie if even a single value within it is incorrectly encoded.
3519
   *
3520
   * Recommended for testing clients against MHD. Can also be used for
3521
   * security-centric applications, though doing so slightly violates
3522
   * relevant RFC requirements for HTTP servers.
3523
   */
3524
  MHD_PSL_VERY_STRICT = 2
3525
  ,
3526
  /**
3527
   * The strictest interpretation of the HTTP protocol, even stricter than
3528
   * allowed by RFCs for HTTP servers.
3529
   * However, it should remain fully compatible with clients complying with both
3530
   * RFC "SHOULD" and "MUST" requirements for HTTP clients.
3531
   *
3532
   * This level can be used for testing clients against MHD.
3533
   * It is not recommended for public services, as it may reject legitimate
3534
   * clients that do not follow RFC "SHOULD" requirements.
3535
   */
3536
  MHD_PSL_EXTRA_STRICT = 3
3537
  ,
3538
  /**
3539
   * A more relaxed protocol interpretation that violates some RFC "SHOULD"
3540
   * restrictions for HTTP servers.
3541
   * For cookie parsing, this level (and more permissive levels) allows
3542
   * whitespace in cookie values.
3543
   *
3544
   * This level may be used in isolated environments.
3545
   */
3546
  MHD_PSL_VERY_PERMISSIVE = -2
3547
  ,
3548
  /**
3549
   * The most flexible protocol interpretation, going beyond RFC "MUST"
3550
   * requirements for HTTP servers.
3551
   *
3552
   * This level allows HTTP/1.1 requests without a "Host:" header.
3553
   * For cookie parsing, whitespace is allowed before and after
3554
   * the '=' character.
3555
   *
3556
   * Not recommended unless absolutely necessary to communicate with clients
3557
   * that have severely broken HTTP implementations.
3558
   */
3559
  MHD_PSL_EXTRA_PERMISSIVE = -3,
3560
};
3561
3562
/**
3563
 * The way Strict Level is enforced.
3564
 * MHD can be compiled with limited set of strictness levels.
3565
 * These values instructs MHD how to apply the request level.
3566
 */
3567
enum MHD_FIXED_ENUM_APP_SET_ MHD_UseStictLevel
3568
{
3569
  /**
3570
   * Use requested level if available or the nearest stricter
3571
   * level.
3572
   * Fail if only more permissive levels available.
3573
   * Recommended value.
3574
   */
3575
  MHD_USL_THIS_OR_STRICTER = 0
3576
  ,
3577
  /**
3578
   * Use requested level only.
3579
   * Fail if this level is not available.
3580
   */
3581
  MHD_USL_PRECISE = 1
3582
  ,
3583
  /**
3584
   * Use requested level if available or the nearest level (stricter
3585
   * or more permissive).
3586
   */
3587
  MHD_USL_NEAREST = 2
3588
};
3589
3590
3591
/**
3592
 * Connection memory buffer zeroing mode.
3593
 * Works as a hardening measure.
3594
 */
3595
enum MHD_FIXED_ENUM_APP_SET_ MHD_ConnBufferZeroingMode
3596
{
3597
  /**
3598
   * Do not perform zeroing of connection memory buffer.
3599
   * Default mode.
3600
   */
3601
  MHD_CONN_BUFFER_ZEROING_DISABLED = 0
3602
  ,
3603
  /**
3604
   * Perform connection memory buffer zeroing before processing request.
3605
   */
3606
  MHD_CONN_BUFFER_ZEROING_BASIC = 1
3607
  ,
3608
  /**
3609
   * Perform connection memory buffer zeroing before processing request and
3610
   * when reusing buffer memory areas during processing request.
3611
   */
3612
  MHD_CONN_BUFFER_ZEROING_HEAVY = 2
3613
};
3614
3615
3616
/* ********************** (d) TLS support ********************** */
3617
3618
/**
3619
 * The TLS backend choice
3620
 */
3621
enum MHD_FIXED_ENUM_APP_SET_ MHD_TlsBackend
3622
{
3623
  /**
3624
   * Disable TLS, use plain TCP connections (default)
3625
   */
3626
  MHD_TLS_BACKEND_NONE = 0
3627
  ,
3628
  /**
3629
   * Use best available TLS backend.
3630
   */
3631
  MHD_TLS_BACKEND_ANY = 1
3632
  ,
3633
  /**
3634
   * Use GnuTLS as TLS backend.
3635
   */
3636
  MHD_TLS_BACKEND_GNUTLS = 2
3637
  ,
3638
  /**
3639
   * Use OpenSSL as TLS backend.
3640
   */
3641
  MHD_TLS_BACKEND_OPENSSL = 3
3642
};
3643
3644
/**
3645
 * Values for #MHD_D_O_DAUTH_NONCE_BIND_TYPE.
3646
 *
3647
 * These values can limit the scope of validity of MHD-generated nonces.
3648
 * Values can be combined with bitwise OR.
3649
 * Any value, except #MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_NONE, enforce function
3650
 * #MHD_digest_auth_check() (and similar functions) to check nonce by
3651
 * re-generating it again with the same parameters, which is CPU-intensive
3652
 * operation.
3653
 */
3654
enum MHD_FIXED_FLAGS_ENUM_APP_SET_ MHD_DaemonOptionValueDAuthBindNonce
3655
{
3656
  /**
3657
   * Generated nonces are valid for any request from any client until expired.
3658
   * This is default and recommended value.
3659
   * #MHD_digest_auth_check() (and similar functions) would check only whether
3660
   * the nonce value that is used by client has been generated by MHD and not
3661
   * expired yet.
3662
   * It is recommended because RFC 7616 allows clients to use the same nonce
3663
   * for any request in the same "protection space".
3664
   * When checking client's authorisation requests CPU is loaded less if this
3665
   * value is used.
3666
   * This mode gives MHD maximum flexibility for nonces generation and can
3667
   * prevent possible nonce collisions (and corresponding log warning messages)
3668
   * when clients' requests are intensive.
3669
   * This value cannot be biwise-OR combined with other values.
3670
   */
3671
  MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_NONE = 0
3672
  ,
3673
  /**
3674
   * Generated nonces are valid only for the same realm.
3675
   */
3676
  MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_REALM = (1 << 0)
3677
  ,
3678
  /**
3679
   * Generated nonces are valid only for the same URI (excluding parameters
3680
   * after '?' in URI) and request method (GET, POST etc).
3681
   * Not recommended unless "protection space" is limited to a single URI as
3682
   * RFC 7616 allows clients to reuse server-generated nonces for any URI
3683
   * in the same "protection space" which by default consists of all server
3684
   * URIs.
3685
   */
3686
  MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI = (1 << 1)
3687
  ,
3688
3689
  /**
3690
   * Generated nonces are valid only for the same URI including URI parameters
3691
   * and request method (GET, POST etc).
3692
   * This value implies #MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI.
3693
   * Not recommended for that same reasons as
3694
   * #MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI.
3695
   */
3696
  MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_URI_PARAMS = (1 << 2)
3697
  ,
3698
3699
  /**
3700
   * Generated nonces are valid only for the single client's IP.
3701
   * While it looks like security improvement, in practice the same client may
3702
   * jump from one IP to another (mobile or Wi-Fi handover, DHCP re-assignment,
3703
   * Multi-NAT, different proxy chain and other reasons), while IP address
3704
   * spoofing could be used relatively easily.
3705
   */
3706
  MHD_D_OPTION_VALUE_DAUTH_BIND_NONCE_CLIENT_IP = (1 << 3)
3707
};
3708
3709
3710
struct MHD_ServerCredentialsContext;
3711
3712
3713
/**
3714
 * Context required to provide a pre-shared key to the
3715
 * server.
3716
 *
3717
 * @param mscc the context
3718
 * @param psk_size the number of bytes in @a psk
3719
 * @param psk the pre-shared-key; should be allocated with malloc(),
3720
 *                 will be freed by MHD
3721
 */
3722
MHD_EXTERN_ enum MHD_StatusCode
3723
MHD_connection_set_psk (
3724
  struct MHD_ServerCredentialsContext *mscc,
3725
  size_t psk_size,
3726
  const /*void? */ char psk[MHD_FN_PAR_DYN_ARR_SIZE_ (psk_size)]);
3727
3728
#define MHD_connection_set_psk_unavailable(mscc) \
3729
        MHD_connection_set_psk (mscc, 0, NULL)
3730
3731
3732
/**
3733
 * Function called to lookup the pre-shared key (PSK) for a given
3734
 * HTTP connection based on the @a username.  MHD will suspend handling of
3735
 * the @a connection until the application calls #MHD_connection_set_psk().
3736
 * If looking up the PSK fails, the application must still call
3737
 * #MHD_connection_set_psk_unavailable().
3738
 *
3739
 * @param cls closure
3740
 * @param connection the HTTPS connection
3741
 * @param username the user name claimed by the other side
3742
 * @param mscc context to pass to #MHD_connection_set_psk().
3743
 */
3744
typedef void
3745
(*MHD_PskServerCredentialsCallback)(
3746
  void *cls,
3747
  const struct MHD_Connection *MHD_RESTRICT connection,
3748
  const struct MHD_String *MHD_RESTRICT username,
3749
  struct MHD_ServerCredentialsContext *mscc);
3750
3751
3752
/**
3753
 * The specified callback will be called one time,
3754
 * after network initialisation, TLS pre-initialisation, but before
3755
 * the start of the internal threads (if allowed).
3756
 *
3757
 * This callback may use introspection call to retrieve and adjust
3758
 * some of the daemon aspects. For example, TLS backend handler can be used
3759
 * to configure some TLS aspects.
3760
 * @param cls the callback closure
3761
 */
3762
typedef void
3763
(*MHD_DaemonReadyCallback)(void *cls);
3764
3765
3766
/**
3767
 * Allow or deny a client to connect.
3768
 *
3769
 * @param cls closure
3770
 * @param addr_len length of @a addr
3771
 * @param addr address information from the client
3772
 * @see #MHD_D_OPTION_ACCEPT_POLICY()
3773
 * @return #MHD_YES if connection is allowed, #MHD_NO if not
3774
 */
3775
typedef enum MHD_Bool
3776
(*MHD_AcceptPolicyCallback)(void *cls,
3777
                            size_t addr_len,
3778
                            const struct sockaddr *addr);
3779
3780
3781
/**
3782
 * The data for the #MHD_EarlyUriLogCallback
3783
 */
3784
struct MHD_EarlyUriCbData
3785
{
3786
  /**
3787
   * The request handle.
3788
   * Headers are not yet available.
3789
   */
3790
  struct MHD_Request *request;
3791
3792
  /**
3793
   * The full URI ("request target") from the HTTP request, including URI
3794
   * parameters (the part after '?')
3795
   */
3796
  struct MHD_String full_uri;
3797
3798
  /**
3799
   * The request HTTP method
3800
   */
3801
  enum MHD_HTTP_Method method;
3802
};
3803
3804
/**
3805
 * Function called by MHD to allow the application to log the @a full_uri
3806
 * of the new request.
3807
 * This is the only moment when unmodified URI is provided.
3808
 * After this callback MHD parses the URI and modifies it by extracting
3809
 * GET parameters in-place.
3810
 *
3811
 * If this callback is set then it is the first application function called
3812
 * for the new request.
3813
 *
3814
 * If #MHD_RequestEndedCallback is also set then it is guaranteed that
3815
 * #MHD_RequestEndedCallback is called for the same request. Application
3816
 * may allocate request specific data in this callback and de-allocate
3817
 * the data in #MHD_RequestEndedCallback.
3818
 *
3819
 * @param cls client-defined closure
3820
 * @param req_data the request data
3821
 * @param request_app_context_ptr the pointer to variable that can be set to
3822
 *                                the application context for the request;
3823
 *                                initially the variable set to NULL
3824
 */
3825
typedef void
3826
(MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (3)
3827
 *MHD_EarlyUriLogCallback)(void *cls,
3828
                           const struct MHD_EarlyUriCbData *req_data,
3829
                           void **request_app_context_ptr);
3830
3831
3832
/**
3833
 * The `enum MHD_ConnectionNotificationCode` specifies types
3834
 * of connection notifications.
3835
 * @ingroup request
3836
 */
3837
enum MHD_FIXED_ENUM_MHD_SET_ MHD_ConnectionNotificationCode
3838
{
3839
3840
  /**
3841
   * A new connection has been started.
3842
   * @ingroup request
3843
   */
3844
  MHD_CONNECTION_NOTIFY_STARTED = 0
3845
  ,
3846
  /**
3847
   * A connection is closed.
3848
   * @ingroup request
3849
   */
3850
  MHD_CONNECTION_NOTIFY_CLOSED = 1
3851
3852
};
3853
3854
/**
3855
 * Extra details for connection notifications.
3856
 * Currently not used
3857
 */
3858
union MHD_ConnectionNotificationDetails
3859
{
3860
  /**
3861
   * Unused
3862
   */
3863
  int reserved1;
3864
};
3865
3866
3867
/**
3868
 * The connection notification data structure
3869
 */
3870
struct MHD_ConnectionNotificationData
3871
{
3872
  /**
3873
   * The connection handle
3874
   */
3875
  struct MHD_Connection *connection;
3876
  /**
3877
   * The connection-specific application context data (opaque for MHD).
3878
   * Initially set to NULL (for connections added by MHD) or set by
3879
   * @a connection_cntx parameter for connections added by
3880
   * #MHD_daemon_add_connection().
3881
   */
3882
  void *application_context;
3883
  /**
3884
   * The code of the event
3885
   */
3886
  enum MHD_ConnectionNotificationCode code;
3887
  /**
3888
   * Event details
3889
   */
3890
  union MHD_ConnectionNotificationDetails details;
3891
};
3892
3893
3894
/**
3895
 * Signature of the callback used by MHD to notify the
3896
 * application about started/stopped network connections
3897
 *
3898
 * @param cls client-defined closure
3899
 * @param[in,out]  data the details about the event
3900
 * @see #MHD_D_OPTION_NOTIFY_CONNECTION()
3901
 * @ingroup request
3902
 */
3903
typedef void
3904
(MHD_FN_PAR_NONNULL_ (2)
3905
 *MHD_NotifyConnectionCallback)(void *cls,
3906
                                struct MHD_ConnectionNotificationData *data);
3907
3908
3909
/**
3910
 * The type of stream notifications.
3911
 * @ingroup request
3912
 */
3913
enum MHD_FIXED_ENUM_MHD_SET_ MHD_StreamNotificationCode
3914
{
3915
  /**
3916
   * A new stream has been started.
3917
   * @ingroup request
3918
   */
3919
  MHD_STREAM_NOTIFY_STARTED = 0
3920
  ,
3921
  /**
3922
   * A stream is closed.
3923
   * @ingroup request
3924
   */
3925
  MHD_STREAM_NOTIFY_CLOSED = 1
3926
};
3927
3928
/**
3929
 * Additional information about stream started event
3930
 */
3931
struct MHD_StreamNotificationDetailStarted
3932
{
3933
  /**
3934
   * Set to #MHD_YES of the stream was started by client
3935
   */
3936
  enum MHD_Bool by_client;
3937
};
3938
3939
/**
3940
 * Additional information about stream events
3941
 */
3942
union MHD_StreamNotificationDetail
3943
{
3944
  /**
3945
   * Information for event #MHD_STREAM_NOTIFY_STARTED
3946
   */
3947
  struct MHD_StreamNotificationDetailStarted started;
3948
};
3949
3950
/**
3951
 * Stream notification data structure
3952
 */
3953
struct MHD_StreamNotificationData
3954
{
3955
  /**
3956
   * The handle of the stream
3957
   */
3958
  struct MHD_Stream *stream;
3959
  /**
3960
   * The code of the event
3961
   */
3962
  enum MHD_StreamNotificationCode code;
3963
  /**
3964
   * Detailed information about notification event
3965
   */
3966
  union MHD_StreamNotificationDetail details;
3967
};
3968
3969
3970
/**
3971
 * Signature of the callback used by MHD to notify the
3972
 * application about started/stopped data stream
3973
 * For HTTP/1.1 it is the same like network connection
3974
 * with 1:1 match.
3975
 *
3976
 * @param cls client-defined closure
3977
 * @param data the details about the event
3978
 * @see #MHD_D_OPTION_NOTIFY_STREAM()
3979
 * @ingroup request
3980
 */
3981
typedef void
3982
(MHD_FN_PAR_NONNULL_ (2)
3983
 *MHD_NotifyStreamCallback)(
3984
  void *cls,
3985
  const struct MHD_StreamNotificationData *data);
3986
3987
#include "microhttpd2_generated_daemon_options.h"
3988
3989
3990
/**
3991
 * The `enum MHD_RequestEndedCode` specifies reasons
3992
 * why a request has been ended.
3993
 * @ingroup request
3994
 */
3995
enum MHD_FIXED_ENUM_MHD_SET_ MHD_RequestEndedCode
3996
{
3997
3998
  /**
3999
   * The response was successfully sent.
4000
   * @ingroup request
4001
   */
4002
  MHD_REQUEST_ENDED_COMPLETED_OK = 0
4003
  ,
4004
  /**
4005
   * The response was successfully sent and connection is being switched
4006
   * to another protocol.
4007
   * @ingroup request
4008
   */
4009
  MHD_REQUEST_ENDED_COMPLETED_OK_UPGRADE = 1
4010
  ,
4011
  /**
4012
   * No activity on the connection for the number of seconds specified using
4013
   * #MHD_C_OPTION_TIMEOUT().
4014
   * @ingroup request
4015
   */
4016
  MHD_REQUEST_ENDED_TIMEOUT_REACHED = 10
4017
  ,
4018
  /**
4019
   * The connection was broken or TLS protocol error.
4020
   * @ingroup request
4021
   */
4022
  MHD_REQUEST_ENDED_CONNECTION_ERROR = 20
4023
  ,
4024
  /**
4025
   * The client terminated the connection by closing the socket either
4026
   * completely or for writing (TCP half-closed) before sending complete
4027
   * request.
4028
   * @ingroup request
4029
   */
4030
  MHD_REQUEST_ENDED_CLIENT_ABORT = 30
4031
  ,
4032
  /**
4033
   * The request is not valid according to HTTP specifications.
4034
   * @ingroup request
4035
   */
4036
  MHD_REQUEST_ENDED_HTTP_PROTOCOL_ERROR = 31
4037
  ,
4038
  /**
4039
   * The application aborted request without response.
4040
   * @ingroup request
4041
   */
4042
  MHD_REQUEST_ENDED_BY_APP_ABORT = 40
4043
  ,
4044
  /**
4045
   * The request was aborted due to the application failed to provide a valid
4046
   * response.
4047
   * @ingroup request
4048
   */
4049
  MHD_REQUEST_ENDED_BY_APP_ERROR = 41
4050
  ,
4051
  /**
4052
   * The request was aborted due to the application failed to register external
4053
   * event monitoring for the connection.
4054
   * @ingroup request
4055
   */
4056
  MHD_REQUEST_ENDED_BY_EXT_EVENT_ERROR = 42
4057
  ,
4058
  /**
4059
   * Error handling the connection due to resources exhausted.
4060
   * @ingroup request
4061
   */
4062
  MHD_REQUEST_ENDED_NO_RESOURCES = 50
4063
  ,
4064
  /**
4065
   * The request was aborted due to error reading file for file-backed response
4066
   * @ingroup request
4067
   */
4068
  MHD_REQUEST_ENDED_FILE_ERROR = 51
4069
  ,
4070
  /**
4071
   * The request was aborted due to error generating valid nonce for Digest Auth
4072
   * @ingroup request
4073
   */
4074
  MHD_REQUEST_ENDED_NONCE_ERROR = 52
4075
  ,
4076
  /**
4077
   * Closing the session since MHD is being shut down.
4078
   * @ingroup request
4079
   */
4080
  MHD_REQUEST_ENDED_DAEMON_SHUTDOWN = 60
4081
};
4082
4083
/**
4084
 * Additional information about request ending
4085
 */
4086
union MHD_RequestEndedDetail
4087
{
4088
  /**
4089
   * Reserved member.
4090
   * Do not use.
4091
   */
4092
  void *reserved;
4093
};
4094
4095
/**
4096
 * Request termination data structure
4097
 */
4098
struct MHD_RequestEndedData
4099
{
4100
  /**
4101
   * The request handle.
4102
   * Note that most of the request data may be already unvailable.
4103
   */
4104
  struct MHD_Request *req;
4105
  /**
4106
   * The code of the event
4107
   */
4108
  enum MHD_RequestEndedCode code;
4109
  /**
4110
   * Detailed information about the event
4111
   */
4112
  union MHD_RequestEndedDetail details;
4113
};
4114
4115
4116
/**
4117
 * Signature of the callback used by MHD to notify the application
4118
 * about completed requests.
4119
 *
4120
 * This is the last callback called for any request (if provided by
4121
 * the application).
4122
 *
4123
 * @param cls client-defined closure
4124
 * @param data the details about the event
4125
 * @param request_app_context the application request context, as possibly set
4126
                              by the #MHD_EarlyUriLogCallback
4127
 * @see #MHD_R_OPTION_TERMINATION_CALLBACK()
4128
 * @ingroup request
4129
 */
4130
typedef void
4131
(*MHD_RequestEndedCallback) (void *cls,
4132
                             const struct MHD_RequestEndedData *data,
4133
                             void *request_app_context);
4134
4135
4136
#include "microhttpd2_generated_response_options.h"
4137
/* Beginning of generated code documenting how to use options.
4138
   You should treat the following functions *as if* they were
4139
   part of the header/API. The actual declarations are more
4140
   complex, so these here are just for documentation!
4141
   We do not actually *build* this code... */
4142
#if 0
4143
4144
/**
4145
 * Set MHD work (threading and polling) mode.
4146
 * Consider use of #MHD_D_OPTION_WM_EXTERNAL_PERIODIC(), #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL(), #MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE(), #MHD_D_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH(), #MHD_D_OPTION_WM_WORKER_THREADS() or #MHD_D_OPTION_WM_THREAD_PER_CONNECTION() instead of direct use of this parameter.
4147
 * @param wmp the object created by one of the next functions/macros: #MHD_WM_OPTION_EXTERNAL_PERIODIC(), #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL(), #MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE(), #MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH(), #MHD_WM_OPTION_WORKER_THREADS(), #MHD_WM_OPTION_THREAD_PER_CONNECTION()
4148
 * @return structure with the requested setting
4149
 */
4150
struct MHD_DaemonOptionAndValue
4151
MHD_D_OPTION_WORK_MODE (
4152
  struct MHD_WorkModeWithParam wmp
4153
  );
4154
4155
/**
4156
 * Select a sockets watch system call used for internal polling.
4157
 * @param els FIXME
4158
 * @return structure with the requested setting
4159
 */
4160
struct MHD_DaemonOptionAndValue
4161
MHD_D_OPTION_POLL_SYSCALL (
4162
  enum MHD_SockPollSyscall els
4163
  );
4164
4165
/**
4166
 * Instruct MHD to register all sockets every processing round.
4167
 *
4168
By default (this options is not enabled) every processing round (every time
4169
 * when #MHD_daemon_event_update() is called) MHD calls
4170
 * #MHD_SocketRegistrationUpdateCallback only for the new sockets, for
4171
 * the removed sockets and for the updated sockets.
4172
 * Some sockets are registered when #MHD_daemon_start() is called.
4173
 *
4174
If this options is enabled, then #MHD_SocketRegistrationUpdateCallback is
4175
 * called for every socket each processing round. No sockets are registered when
4176
 * the daemon is being started.
4177
 * @param value the value of the parameter * @return structure with the requested setting
4178
 */
4179
struct MHD_DaemonOptionAndValue
4180
MHD_D_OPTION_REREGISTER_ALL (
4181
  enum MHD_Bool value
4182
  );
4183
4184
/**
4185
 * Set a callback to use for logging
4186
 * @param log_cb the callback to use for logging,
4187
 *   NULL to disable logging.
4188
 *   The logging to stderr is enabled by default.
4189
 * @param log_cb_cls the closure for the logging callback
4190
 * @return structure with the requested setting
4191
 */
4192
struct MHD_DaemonOptionAndValue
4193
MHD_D_OPTION_LOG_CALLBACK (
4194
  MHD_LoggingCallback log_cb,
4195
  void *log_cb_cls
4196
  );
4197
4198
/**
4199
 * Bind to the given TCP port and address family.
4200
 *
4201
Does not work with #MHD_D_OPTION_BIND_SA() or #MHD_D_OPTION_LISTEN_SOCKET().
4202
 *
4203
If no listen socket optins (#MHD_D_OPTION_BIND_PORT(), #MHD_D_OPTION_BIND_SA(), #MHD_D_OPTION_LISTEN_SOCKET()) are used, MHD does not listen for incoming connection.
4204
 * @param af the address family to use,
4205
 *   the #MHD_AF_NONE to disable listen socket (the same effect as if this option is not used)
4206
 * @param port port to use, 0 to let system assign any free port,
4207
 *   ignored if @a af is #MHD_AF_NONE
4208
 * @return structure with the requested setting
4209
 */
4210
struct MHD_DaemonOptionAndValue
4211
MHD_D_OPTION_BIND_PORT (
4212
  enum MHD_AddressFamily af,
4213
  uint_least16_t port
4214
  );
4215
4216
/**
4217
 * Bind to the given socket address.
4218
 *
4219
Does not work with #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_LISTEN_SOCKET().
4220
 *
4221
If no listen socket optins (#MHD_D_OPTION_BIND_PORT(), #MHD_D_OPTION_BIND_SA(), #MHD_D_OPTION_LISTEN_SOCKET()) are used, MHD does not listen for incoming connection.
4222
 * @param sa_len the size of the socket address pointed by @a sa.
4223
 * @param sa the address to bind to; can be IPv4 (AF_INET), IPv6 (AF_INET6) or even a UNIX domain socket (AF_UNIX)
4224
 * @param dual When a previous version of the protocol exist (like IPv4 when @a v_sa is IPv6) bind to both protocols (IPv6 and IPv4).
4225
 * @return structure with the requested setting
4226
 */
4227
struct MHD_DaemonOptionAndValue
4228
MHD_D_OPTION_BIND_SA (
4229
  size_t sa_len,
4230
  /* const */ struct sockaddr *sa,
4231
  enum MHD_Bool dual
4232
  );
4233
4234
/**
4235
 * Accept connections from the given socket.  Socket
4236
 * must be a TCP or UNIX domain (SOCK_STREAM) socket.
4237
 *
4238
Does not work with #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA().
4239
 *
4240
If no listen socket optins (#MHD_D_OPTION_BIND_PORT(), #MHD_D_OPTION_BIND_SA(), #MHD_D_OPTION_LISTEN_SOCKET()) are used, MHD does not listen for incoming connection.
4241
 * @param listen_fd the listen socket to use, ignored if set to #MHD_INVALID_SOCKET
4242
 * @return structure with the requested setting
4243
 */
4244
struct MHD_DaemonOptionAndValue
4245
MHD_D_OPTION_LISTEN_SOCKET (
4246
  MHD_Socket listen_fd
4247
  );
4248
4249
/**
4250
 * Select mode of reusing address:port listen address.
4251
 *
4252
Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
4253
 * @param reuse_type FIXME
4254
 * @return structure with the requested setting
4255
 */
4256
struct MHD_DaemonOptionAndValue
4257
MHD_D_OPTION_LISTEN_ADDR_REUSE (
4258
  enum MHD_DaemonOptionBindType reuse_type
4259
  );
4260
4261
/**
4262
 * Configure TCP_FASTOPEN option, including setting a
4263
 * custom @a queue_length.
4264
 *
4265
Note that having a larger queue size can cause resource exhaustion
4266
 * attack as the TCP stack has to now allocate resources for the SYN
4267
 * packet along with its DATA.
4268
 *
4269
Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
4270
 * @param option the type use of of TCP FastOpen
4271
 * @param queue_length the length of the queue, zero to use system or MHD default,
4272
 *   silently ignored on platforms without support for custom queue size
4273
 * @return structure with the requested setting
4274
 */
4275
struct MHD_DaemonOptionAndValue
4276
MHD_D_OPTION_TCP_FASTOPEN (
4277
  enum MHD_TCPFastOpenType option,
4278
  unsigned int queue_length
4279
  );
4280
4281
/**
4282
 * Use the given backlog for the listen() call.
4283
 *
4284
Works only when #MHD_D_OPTION_BIND_PORT() or #MHD_D_OPTION_BIND_SA() are used.
4285
 * Zero parameter treated as MHD/system default.
4286
 * @param backlog_size FIXME
4287
 * @return structure with the requested setting
4288
 */
4289
struct MHD_DaemonOptionAndValue
4290
MHD_D_OPTION_LISTEN_BACKLOG (
4291
  unsigned int backlog_size
4292
  );
4293
4294
/**
4295
 * Inform that SIGPIPE is suppressed or handled by application.
4296
 * If suppressed/handled, MHD uses network functions that could generate SIGPIPE, like `sendfile()`.
4297
 * Silently ignored when MHD creates internal threads as for them SIGPIPE is suppressed automatically.
4298
 * @param value the value of the parameter * @return structure with the requested setting
4299
 */
4300
struct MHD_DaemonOptionAndValue
4301
MHD_D_OPTION_SIGPIPE_SUPPRESSED (
4302
  enum MHD_Bool value
4303
  );
4304
4305
/**
4306
 * Enable TLS (HTTPS) and select TLS backend
4307
 * @param backend the TLS backend to use,
4308
 *   #MHD_TLS_BACKEND_NONE for non-TLS (plain TCP) connections
4309
 * @return structure with the requested setting
4310
 */
4311
struct MHD_DaemonOptionAndValue
4312
MHD_D_OPTION_TLS (
4313
  enum MHD_TlsBackend backend
4314
  );
4315
4316
/**
4317
 * Provide TLS key and certificate data in-memory.
4318
 * Works only if TLS mode is enabled.
4319
 * @param mem_cert The X.509 certificates chain in PEM format loaded into memory (not a filename).
4320
 *   The first certificate must be the server certificate, following by the chain of signing
4321
 *   certificates up to (but not including) CA root certificate.
4322
 * @param mem_key the private key in PEM format loaded into memory (not a filename)
4323
 * @param mem_pass the option passphrase phrase to decrypt the private key,
4324
 *   could be NULL if private key does not need a password
4325
 * @return structure with the requested setting
4326
 */
4327
struct MHD_DaemonOptionAndValue
4328
MHD_D_OPTION_TLS_CERT_KEY (
4329
  /* const */ char *mem_cert,
4330
  const char *mem_key,
4331
  const char *mem_pass
4332
  );
4333
4334
/**
4335
 * Provide the certificate of the certificate authority (CA) to be used by the MHD daemon for client authentication.
4336
 * Works only if TLS mode is enabled.
4337
 * @param mem_client_ca the CA certificate in memory (not a filename)
4338
 * @return structure with the requested setting
4339
 */
4340
struct MHD_DaemonOptionAndValue
4341
MHD_D_OPTION_TLS_CLIENT_CA (
4342
  const char *mem_client_ca
4343
  );
4344
4345
/**
4346
 * Configure PSK to use for the TLS key exchange.
4347
 * @param psk_cb the function to call to obtain pre-shared key
4348
 * @param psk_cb_cls the closure for @a psk_cb
4349
 * @return structure with the requested setting
4350
 */
4351
struct MHD_DaemonOptionAndValue
4352
MHD_D_OPTION_TLS_PSK_CALLBACK (
4353
  MHD_PskServerCredentialsCallback psk_cb,
4354
  void *psk_cb_cls
4355
  );
4356
4357
/**
4358
 * Control ALPN for TLS connection.
4359
 * Silently ignored for non-TLS.
4360
 * By default ALPN is automatically used for TLS connections.
4361
 * @param value the value of the parameter * @return structure with the requested setting
4362
 */
4363
struct MHD_DaemonOptionAndValue
4364
MHD_D_OPTION_NO_ALPN (
4365
  enum MHD_Bool value
4366
  );
4367
4368
/**
4369
 * Specify inactivity timeout for connection.
4370
 * When no activity for specified time on connection, it is closed
4371
 * automatically.
4372
 * Use zero for no timeout, which is also the (unsafe!) default.
4373
 * Very large values (years) can be silently truncated to smaller values.
4374
 * @param timeout the in seconds, zero for no timeout
4375
 * @return structure with the requested setting
4376
 */
4377
struct MHD_DaemonOptionAndValue
4378
MHD_D_OPTION_DEFAULT_TIMEOUT (
4379
  unsigned int timeout
4380
  );
4381
4382
/**
4383
 * Maximum number of (concurrent) network connections served by daemon.
4384
 * @note The real maximum number of network connections could be smaller
4385
 *       than requested due to the system limitations, like FD_SETSIZE when
4386
 *       polling by select() is used.
4387
 * @param glob_limit FIXME
4388
 * @return structure with the requested setting
4389
 */
4390
struct MHD_DaemonOptionAndValue
4391
MHD_D_OPTION_GLOBAL_CONNECTION_LIMIT (
4392
  unsigned int glob_limit
4393
  );
4394
4395
/**
4396
 * Limit on the number of (concurrent) network connections made to the server from the same IP address.
4397
 * Can be used to prevent one IP from taking over all of the allowed connections. If the same IP tries to establish more than the specified number of connections, they will be immediately rejected.
4398
 * @param limit FIXME
4399
 * @return structure with the requested setting
4400
 */
4401
struct MHD_DaemonOptionAndValue
4402
MHD_D_OPTION_PER_IP_LIMIT (
4403
  unsigned int limit
4404
  );
4405
4406
/**
4407
 * Set a policy callback that accepts/rejects connections based on the client's IP address.  The callbeck function will be called before servicing any new incoming connection.
4408
 * @param apc the accept policy callback
4409
 * @param apc_cls the closure for the callback
4410
 * @return structure with the requested setting
4411
 */
4412
struct MHD_DaemonOptionAndValue
4413
MHD_D_OPTION_ACCEPT_POLICY (
4414
  MHD_AcceptPolicyCallback apc,
4415
  void *apc_cls
4416
  );
4417
4418
/**
4419
 * Set mode of connection memory buffer zeroing
4420
 * @param buff_zeroing buffer zeroing mode
4421
 * @return structure with the requested setting
4422
 */
4423
struct MHD_DaemonOptionAndValue
4424
MHD_D_OPTION_CONN_BUFF_ZEROING (
4425
  enum MHD_ConnBufferZeroingMode buff_zeroing
4426
  );
4427
4428
/**
4429
 * Set how strictly MHD will enforce the HTTP protocol.
4430
 * @param sl the level of strictness
4431
 * @param how the way how to use the requested level
4432
 * @return structure with the requested setting
4433
 */
4434
struct MHD_DaemonOptionAndValue
4435
MHD_D_OPTION_PROTOCOL_STRICT_LEVEL (
4436
  enum MHD_ProtocolStrictLevel sl,
4437
  enum MHD_UseStictLevel how
4438
  );
4439
4440
/**
4441
 * Set a callback to be called first for every request when the request line is received (before any parsing of the header).
4442
 * This callback is the only way to get raw (unmodified) request URI as URI is parsed and modified by MHD in-place.
4443
 * Mandatory URI modification may apply before this call, like binary zero replacement, as required by RFCs.
4444
 * @param cb the early URI callback
4445
 * @param cls the closure for the callback
4446
 * @return structure with the requested setting
4447
 */
4448
struct MHD_DaemonOptionAndValue
4449
MHD_D_OPTION_EARLY_URI_LOGGER (
4450
  MHD_EarlyUriLogCallback cb,
4451
  void *cls
4452
  );
4453
4454
/**
4455
 * Disable converting plus ('+') character to space in GET parameters (URI part after '?').
4456
 * Plus conversion is not required by HTTP RFCs, however it required by HTML specifications, see https://url.spec.whatwg.org/#application/x-www-form-urlencoded for details.
4457
 * By default plus is converted to space in the query part of URI.
4458
 * @param value the value of the parameter * @return structure with the requested setting
4459
 */
4460
struct MHD_DaemonOptionAndValue
4461
MHD_D_OPTION_DISABLE_URI_QUERY_PLUS_AS_SPACE (
4462
  enum MHD_Bool value
4463
  );
4464
4465
/**
4466
 * Suppresse use of 'Date:' header.
4467
 * According to RFC should be suppressed only if the system has no RTC.
4468
 * The 'Date:' is not suppressed (the header is enabled) by default.
4469
 * @param value the value of the parameter * @return structure with the requested setting
4470
 */
4471
struct MHD_DaemonOptionAndValue
4472
MHD_D_OPTION_SUPPRESS_DATE_HEADER (
4473
  enum MHD_Bool value
4474
  );
4475
4476
/**
4477
 * Use SHOUTcast for responses.
4478
 * This will cause *all* responses to begin with the SHOUTcast 'ICY' line instead of 'HTTP'.
4479
 * @param value the value of the parameter * @return structure with the requested setting
4480
 */
4481
struct MHD_DaemonOptionAndValue
4482
MHD_D_OPTION_ENABLE_SHOUTCAST (
4483
  enum MHD_Bool value
4484
  );
4485
4486
/**
4487
 * Maximum memory size per connection.
4488
 * Default is 32kb.
4489
 * Values above 128kb are unlikely to result in much performance benefit, as half of the memory will be typically used for IO, and TCP buffers are unlikely to support window sizes above 64k on most systems.
4490
 * The size should be large enough to fit all request headers (together with internal parsing information).
4491
 * @param value the value of the parameter * @return structure with the requested setting
4492
 */
4493
struct MHD_DaemonOptionAndValue
4494
MHD_D_OPTION_CONN_MEMORY_LIMIT (
4495
  size_t value
4496
  );
4497
4498
/**
4499
 * The size of the shared memory pool for accamulated upload processing.
4500
 * The same large pool is shared for all connections server by MHD and used when application requests avoiding of incremental upload processing to accamulate complete content upload before giving it to the application.
4501
 * Default is 8Mb.
4502
 * Can be set to zero to disable share pool.
4503
 * @param value the value of the parameter * @return structure with the requested setting
4504
 */
4505
struct MHD_DaemonOptionAndValue
4506
MHD_D_OPTION_LARGE_POOL_SIZE (
4507
  size_t value
4508
  );
4509
4510
/**
4511
 * Desired size of the stack for the threads started by MHD.
4512
 * Use 0 for system default, which is also MHD default.
4513
 * Works only with #MHD_D_OPTION_WM_WORKER_THREADS() or #MHD_D_OPTION_WM_THREAD_PER_CONNECTION().
4514
 * @param value the value of the parameter * @return structure with the requested setting
4515
 */
4516
struct MHD_DaemonOptionAndValue
4517
MHD_D_OPTION_STACK_SIZE (
4518
  size_t value
4519
  );
4520
4521
/**
4522
 * The the maximum FD value.
4523
 * The limit is applied to all sockets used by MHD.
4524
 * If listen socket FD is equal or higher that specified value, the daemon fail to start.
4525
 * If new connection FD is equal or higher that specified value, the connection is rejected.
4526
 * Useful if application uses select() for polling the sockets, system FD_SETSIZE is good value for this option in such case.
4527
 * Silently ignored on W32 (WinSock sockets).
4528
 * @param max_fd FIXME
4529
 * @return structure with the requested setting
4530
 */
4531
struct MHD_DaemonOptionAndValue
4532
MHD_D_OPTION_FD_NUMBER_LIMIT (
4533
  MHD_Socket max_fd
4534
  );
4535
4536
/**
4537
 * Enable `turbo`.
4538
 * Disables certain calls to `shutdown()`, enables aggressive non-blocking optimistic reads and other potentially unsafe optimisations.
4539
 * Most effects only happen with internal threads with epoll.
4540
 * The 'turbo' mode is not enabled (mode is disabled) by default.
4541
 * @param value the value of the parameter * @return structure with the requested setting
4542
 */
4543
struct MHD_DaemonOptionAndValue
4544
MHD_D_OPTION_TURBO (
4545
  enum MHD_Bool value
4546
  );
4547
4548
/**
4549
 * Disable some internal thread safety.
4550
 * Indicates that MHD daemon will be used by application in single-threaded mode only.  When this flag is set then application must call any MHD function only within a single thread.
4551
 * This flag turns off some internal thread-safety and allows MHD making some of the internal optimisations suitable only for single-threaded environment.
4552
 * Not compatible with any internal threads modes.
4553
 * If MHD is compiled with custom configuration for embedded projects without threads support, this option is mandatory.
4554
 * Thread safety is not disabled (safety is enabled) by default.
4555
 * @param value the value of the parameter * @return structure with the requested setting
4556
 */
4557
struct MHD_DaemonOptionAndValue
4558
MHD_D_OPTION_DISABLE_THREAD_SAFETY (
4559
  enum MHD_Bool value
4560
  );
4561
4562
/**
4563
 * You need to set this option if you want to disable use of HTTP Upgrade.
4564
 * Upgrade may require usage of additional internal resources, which we can avoid providing if they will not be used.
4565
 * You should only use this option if you do not use upgrade functionality and need a generally minor boost in performance and resources saving.
4566
 * The upgrade is not disallowed (upgrade is allowed) by default.
4567
 * @param value the value of the parameter * @return structure with the requested setting
4568
 */
4569
struct MHD_DaemonOptionAndValue
4570
MHD_D_OPTION_DISALLOW_UPGRADE (
4571
  enum MHD_Bool value
4572
  );
4573
4574
/**
4575
 * Disable #MHD_action_suspend() functionality.
4576
 *
4577
You should only use this function if you do not use suspend functionality and need a generally minor boost in performance.
4578
 * The suspend is not disallowed (suspend is allowed) by default.
4579
 * @param value the value of the parameter * @return structure with the requested setting
4580
 */
4581
struct MHD_DaemonOptionAndValue
4582
MHD_D_OPTION_DISALLOW_SUSPEND_RESUME (
4583
  enum MHD_Bool value
4584
  );
4585
4586
/**
4587
 * Disable cookies parsing.
4588
 *
4589
Disable automatic cookies processing if cookies are not used.
4590
 * Cookies are automatically parsed by default.
4591
 * @param value the value of the parameter * @return structure with the requested setting
4592
 */
4593
struct MHD_DaemonOptionAndValue
4594
MHD_D_OPTION_DISABLE_COOKIES (
4595
  enum MHD_Bool value
4596
  );
4597
4598
/**
4599
 * Set a callback to be called for pre-start finalisation.
4600
 *
4601
The specified callback will be called one time, after network initialisation, TLS pre-initialisation, but before the start of the internal threads (if allowed)
4602
 * @param cb the pre-start callback
4603
 * @param cb_cls the closure for the callback
4604
 * @return structure with the requested setting
4605
 */
4606
struct MHD_DaemonOptionAndValue
4607
MHD_D_OPTION_DAEMON_READY_CALLBACK (
4608
  MHD_DaemonReadyCallback cb,
4609
  void *cb_cls
4610
  );
4611
4612
/**
4613
 * Set a function that should be called whenever a connection is started or closed.
4614
 * @param ncc the callback for notifications
4615
 * @param cls the closure for the callback
4616
 * @return structure with the requested setting
4617
 */
4618
struct MHD_DaemonOptionAndValue
4619
MHD_D_OPTION_NOTIFY_CONNECTION (
4620
  MHD_NotifyConnectionCallback ncc,
4621
  void *cls
4622
  );
4623
4624
/**
4625
 * Register a function that should be called whenever a stream is started or closed.
4626
 * For HTTP/1.1 this callback is called one time for every connection.
4627
 * @param nsc the callback for notifications
4628
 * @param cls the closure for the callback
4629
 * @return structure with the requested setting
4630
 */
4631
struct MHD_DaemonOptionAndValue
4632
MHD_D_OPTION_NOTIFY_STREAM (
4633
  MHD_NotifyStreamCallback nsc,
4634
  void *cls
4635
  );
4636
4637
/**
4638
 * Set strong random data to be used by MHD.
4639
 * Currently the data is only needed for Digest Auth module.
4640
 * Daemon support for Digest Auth is enabled automatically if this option is used.
4641
 * The recommended size is between 8 and 32 bytes. Security can be lower for sizes less or equal four.
4642
 * Sizes larger then 32 (or, probably, larger than 16 - debatable) will not increase the security.
4643
 * @param buf_size the size of the buffer
4644
 * @param buf the buffer with strong random data, the content will be copied by MHD
4645
 * @return structure with the requested setting
4646
 */
4647
struct MHD_DaemonOptionAndValue
4648
MHD_D_OPTION_RANDOM_ENTROPY (
4649
  size_t buf_size,
4650
  /* const */ void *buf
4651
  );
4652
4653
/**
4654
 * Specify the size of the internal hash map array that tracks generated digest nonces usage.
4655
 * When the size of the map is too small then need to handle concurrent DAuth requests, a lot of stale nonce results will be produced.
4656
 * By default the size is 1000 entries.
4657
 * @param size the size of the map array
4658
 * @return structure with the requested setting
4659
 */
4660
struct MHD_DaemonOptionAndValue
4661
MHD_D_OPTION_AUTH_DIGEST_MAP_SIZE (
4662
  size_t size
4663
  );
4664
4665
/**
4666
 * Nonce validity time (in seconds) used for Digest Auth.
4667
 * If followed by zero value the value is silently ignored.
4668
 * @see #MHD_digest_auth_check(), MHD_digest_auth_check_digest()
4669
 * @param timeout FIXME
4670
 * @return structure with the requested setting
4671
 */
4672
struct MHD_DaemonOptionAndValue
4673
MHD_D_OPTION_AUTH_DIGEST_NONCE_TIMEOUT (
4674
  unsigned int timeout
4675
  );
4676
4677
/**
4678
 * Default maximum nc (nonce count) value used for Digest Auth.
4679
 * If followed by zero value the value is silently ignored.
4680
 * @see #MHD_digest_auth_check(), MHD_digest_auth_check_digest()
4681
 * @param max_nc FIXME
4682
 * @return structure with the requested setting
4683
 */
4684
struct MHD_DaemonOptionAndValue
4685
MHD_D_OPTION_AUTH_DIGEST_DEF_MAX_NC (
4686
  uint_fast32_t max_nc
4687
  );
4688
4689
/* End of generated code documenting how to use options */
4690
#endif
4691
4692
/* Beginning of generated code documenting how to use options.
4693
   You should treat the following functions *as if* they were
4694
   part of the header/API. The actual declarations are more
4695
   complex, so these here are just for documentation!
4696
   We do not actually *build* this code... */
4697
#if 0
4698
4699
/**
4700
 * Make the response object re-usable.
4701
 * The response will not be consumed by MHD_action_from_response() and must be destroyed by MHD_response_destroy().
4702
 * Useful if the same response is often used to reply.
4703
 * @param value the value of the parameter * @return structure with the requested setting
4704
 */
4705
struct MHD_ResponseOptionAndValue
4706
MHD_R_OPTION_REUSABLE (
4707
  enum MHD_Bool value
4708
  );
4709
4710
/**
4711
 * Enable special processing of the response as body-less (with undefined body size). No automatic 'Content-Length' or 'Transfer-Encoding: chunked' headers are added when the response is used with #MHD_HTTP_STATUS_NOT_MODIFIED code or to respond to HEAD request.
4712
 * The flag also allow to set arbitrary 'Content-Length' by #MHD_response_add_header() function.
4713
 * This flag value can be used only with responses created without body (zero-size body).
4714
 * Responses with this flag enabled cannot be used in situations where reply body must be sent to the client.
4715
 * This flag is primarily intended to be used when automatic 'Content-Length' header is undesirable in response to HEAD requests.
4716
 * @param value the value of the parameter * @return structure with the requested setting
4717
 */
4718
struct MHD_ResponseOptionAndValue
4719
MHD_R_OPTION_HEAD_ONLY_RESPONSE (
4720
  enum MHD_Bool value
4721
  );
4722
4723
/**
4724
 * Force use of chunked encoding even if the response content size is known.
4725
 * Ignored when the reply cannot have body/content.
4726
 * @param value the value of the parameter * @return structure with the requested setting
4727
 */
4728
struct MHD_ResponseOptionAndValue
4729
MHD_R_OPTION_CHUNKED_ENC (
4730
  enum MHD_Bool value
4731
  );
4732
4733
/**
4734
 * Force close connection after sending the response, prevents keep-alive connections and adds 'Connection: close' header.
4735
 * @param value the value of the parameter * @return structure with the requested setting
4736
 */
4737
struct MHD_ResponseOptionAndValue
4738
MHD_R_OPTION_CONN_CLOSE (
4739
  enum MHD_Bool value
4740
  );
4741
4742
/**
4743
 * Only respond in conservative (dumb) HTTP/1.0-compatible mode.
4744
 * Response still use HTTP/1.1 version in header, but always close the connection after sending the response and do not use chunked encoding for the response.
4745
 * You can also set the #MHD_R_O_HTTP_1_0_SERVER flag to force HTTP/1.0 version in the response.
4746
 * Responses are still compatible with HTTP/1.1.
4747
 * Summary:
4748
 * + declared reply version: HTTP/1.1
4749
 * + keep-alive: no
4750
 * + chunked: no
4751
 *
4752
This option can be used to communicate with some broken client, which does not implement HTTP/1.1 features, but advertises HTTP/1.1 support.
4753
 * @param value the value of the parameter * @return structure with the requested setting
4754
 */
4755
struct MHD_ResponseOptionAndValue
4756
MHD_R_OPTION_HTTP_1_0_COMPATIBLE_STRICT (
4757
  enum MHD_Bool value
4758
  );
4759
4760
/**
4761
 * Only respond in HTTP/1.0-mode.
4762
 * Contrary to the #MHD_R_O_HTTP_1_0_COMPATIBLE_STRICT flag, the response's HTTP version will always be set to 1.0 and keep-alive connections will be used if explicitly requested by the client.
4763
 * The 'Connection:' header will be added for both 'close' and 'keep-alive' connections.
4764
 * Chunked encoding will not be used for the response.
4765
 * Due to backward compatibility, responses still can be used with HTTP/1.1 clients.
4766
 * This option can be used to emulate HTTP/1.0 server (for response part only as chunked encoding in requests (if any) is processed by MHD).
4767
 * Summary:
4768
 * + declared reply version: HTTP/1.0
4769
 * + keep-alive: possible
4770
 * + chunked: no
4771
 *
4772
With this option HTTP/1.0 server is emulated (with support for 'keep-alive' connections).
4773
 * @param value the value of the parameter * @return structure with the requested setting
4774
 */
4775
struct MHD_ResponseOptionAndValue
4776
MHD_R_OPTION_HTTP_1_0_SERVER (
4777
  enum MHD_Bool value
4778
  );
4779
4780
/**
4781
 * Disable sanity check preventing clients from manually setting the HTTP content length option.
4782
 * Allow to set several 'Content-Length' headers. These headers will be used even with replies without body.
4783
 * @param value the value of the parameter * @return structure with the requested setting
4784
 */
4785
struct MHD_ResponseOptionAndValue
4786
MHD_R_OPTION_INSANITY_HEADER_CONTENT_LENGTH (
4787
  enum MHD_Bool value
4788
  );
4789
4790
/**
4791
 * Set a function to be called once MHD is finished with the request.
4792
 * @param ended_cb the function to call,
4793
 *   NULL to not use the callback
4794
 * @param ended_cb_cls the closure for the callback
4795
 * @return structure with the requested setting
4796
 */
4797
struct MHD_ResponseOptionAndValue
4798
MHD_R_OPTION_TERMINATION_CALLBACK (
4799
  MHD_RequestEndedCallback ended_cb,
4800
  void *ended_cb_cls
4801
  );
4802
4803
/* End of generated code documenting how to use options */
4804
#endif
4805
4806
/**
4807
 * Create parameter for #MHD_daemon_set_options() for work mode with
4808
 * no internal threads.
4809
 * The application periodically calls #MHD_daemon_process_blocking(), where
4810
 * MHD internally checks all sockets automatically.
4811
 * This is the default mode.
4812
 * @return the object of struct MHD_DaemonOptionAndValue with requested values
4813
 */
4814
#define MHD_D_OPTION_WM_EXTERNAL_PERIODIC() \
4815
        MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_EXTERNAL_PERIODIC ())
4816
4817
/**
4818
* Create parameter for #MHD_daemon_set_options() for work mode with
4819
* an external event loop with level triggers.
4820
* Application uses #MHD_SocketRegistrationUpdateCallback, level triggered
4821
* sockets polling (like select() or poll()) and #MHD_daemon_event_update().
4822
* @param cb_val the callback for sockets registration
4823
* @param cb_cls_val the closure for the @a cv_val callback
4824
* @return the object of struct MHD_DaemonOptionAndValue with requested values
4825
*/
4826
#define MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL(cb_val,cb_cls_val) \
4827
        MHD_D_OPTION_WORK_MODE ( \
4828
          MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_LEVEL ((cb_val),(cb_cls_val)))
4829
4830
/**
4831
 * Create parameter for #MHD_daemon_set_options() for work mode with
4832
 * an external event loop with edge triggers.
4833
 * Application uses #MHD_SocketRegistrationUpdateCallback, edge triggered
4834
 * sockets polling (like epoll with EPOLLET) and #MHD_daemon_event_update().
4835
 * @param cb_val the callback for sockets registration
4836
 * @param cb_cls_val the closure for the @a cv_val callback
4837
 * @return the object of struct MHD_DaemonOptionAndValue with requested values
4838
 */
4839
#define MHD_D_OPTION_WM_EXTERNAL_EVENT_LOOP_CB_EDGE(cb_val,cb_cls_val) \
4840
        MHD_D_OPTION_WORK_MODE ( \
4841
          MHD_WM_OPTION_EXTERNAL_EVENT_LOOP_CB_EDGE ((cb_val),(cb_cls_val)))
4842
4843
/**
4844
 * Create parameter for #MHD_daemon_set_options() for work mode with
4845
 * no internal threads and aggregate watch FD.
4846
 * Application uses #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD to get single FD
4847
 * that gets triggered by any MHD event.
4848
 * This FD can be watched as an aggregate indicator for all MHD events.
4849
 * This mode is available only on selected platforms (currently
4850
 * GNU/Linux only), see #MHD_LIB_INFO_FIXED_HAS_AGGREGATE_FD.
4851
 * When the FD is triggered, #MHD_daemon_process_nonblocking() should
4852
 * be called.
4853
 * @return the object of struct MHD_DaemonOptionAndValue with requested values
4854
 */
4855
#define MHD_D_OPTION_WM_EXTERNAL_SINGLE_FD_WATCH() \
4856
        MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_EXTERNAL_SINGLE_FD_WATCH ())
4857
4858
/**
4859
 * Create parameter for #MHD_daemon_set_options() for work mode with
4860
 * one or more worker threads.
4861
 * If number of threads is one, then daemon starts with single worker thread
4862
 * that handles all connections.
4863
 * If number of threads is larger than one, then that number of worker threads,
4864
 * and handling of connection is distributed among the workers.
4865
 * @param num_workers the number of worker threads, zero is treated as one
4866
 * @return the object of struct MHD_DaemonOptionAndValue with requested values
4867
 */
4868
#define MHD_D_OPTION_WM_WORKER_THREADS(num_workers) \
4869
        MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_WORKER_THREADS (num_workers))
4870
4871
/**
4872
 * Create parameter for #MHD_daemon_set_options() for work mode with
4873
 * one internal thread for listening and additional threads per every
4874
 * connection.  Use this if handling requests is CPU-intensive or blocking,
4875
 * your application is thread-safe and you have plenty of memory (per
4876
 * connection).
4877
 * @return the object of struct MHD_DaemonOptionAndValue with requested values
4878
 */
4879
#define MHD_D_OPTION_WM_THREAD_PER_CONNECTION() \
4880
        MHD_D_OPTION_WORK_MODE (MHD_WM_OPTION_THREAD_PER_CONNECTION ())
4881
4882
/**
4883
 * Set the requested options for the daemon.
4884
 *
4885
 * If any option fail other options may be or may be not applied.
4886
 * @param daemon the daemon to set the options
4887
 * @param[in] options the pointer to the array with the options;
4888
 *                    the array processing stops at the first ::MHD_D_O_END
4889
 *                    option, but not later than after processing
4890
 *                    @a options_max_num entries
4891
 * @param options_max_num the maximum number of entries in the @a options,
4892
 *                        use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
4893
 *                        must stop only at zero-termination option
4894
 * @return ::MHD_SC_OK on success,
4895
 *         error code otherwise
4896
 */
4897
MHD_EXTERN_ enum MHD_StatusCode
4898
MHD_daemon_set_options (
4899
  struct MHD_Daemon *MHD_RESTRICT daemon,
4900
  const struct MHD_DaemonOptionAndValue *MHD_RESTRICT options,
4901
  size_t options_max_num)
4902
MHD_FN_PAR_NONNULL_ALL_;
4903
4904
4905
/**
4906
 * Set the requested single option for the daemon.
4907
 *
4908
 * @param daemon the daemon to set the option
4909
 * @param[in] option_ptr the pointer to the option
4910
 * @return ::MHD_SC_OK on success,
4911
 *         error code otherwise
4912
 */
4913
#define MHD_daemon_set_option(daemon, option_ptr) \
4914
        MHD_daemon_set_options (daemon, option_ptr, 1)
4915
4916
4917
/* *INDENT-OFF* */
4918
#ifdef MHD_USE_VARARG_MACROS
4919
MHD_NOWARN_VARIADIC_MACROS_
4920
#  if defined(MHD_USE_COMPOUND_LITERALS) && \
4921
  defined(MHD_USE_COMP_LIT_FUNC_PARAMS)
4922
/**
4923
 * Set the requested options for the daemon.
4924
 *
4925
 * If any option fail other options may be or may be not applied.
4926
 *
4927
 * It should be used with helpers that creates required options, for example:
4928
 *
4929
 * MHD_DAEMON_SET_OPTIONS(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
4930
 *                        MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
4931
 *
4932
 * @param daemon the daemon to set the options
4933
 * @param ... the list of the options, each option must be created
4934
 *            by helpers MHD_D_OPTION_NameOfOption(option_value)
4935
 * @return ::MHD_SC_OK on success,
4936
 *         error code otherwise
4937
 */
4938
#    define MHD_DAEMON_SET_OPTIONS(daemon,...)          \
4939
        MHD_NOWARN_COMPOUND_LITERALS_                   \
4940
        MHD_NOWARN_AGGR_DYN_INIT_                       \
4941
        MHD_daemon_set_options (                        \
4942
          daemon,                                       \
4943
          ((const struct MHD_DaemonOptionAndValue[])    \
4944
           {__VA_ARGS__, MHD_D_OPTION_TERMINATE ()}),   \
4945
          MHD_OPTIONS_ARRAY_MAX_SIZE)                   \
4946
        MHD_RESTORE_WARN_AGGR_DYN_INIT_                 \
4947
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
4948
#  elif defined(MHD_USE_CPP_INIT_LIST)
4949
MHD_C_DECLRATIONS_FINISH_HERE_
4950
#    include <vector>
4951
MHD_C_DECLRATIONS_START_HERE_
4952
/**
4953
 * Set the requested options for the daemon.
4954
 *
4955
 * If any option fail other options may be or may be not applied.
4956
 *
4957
 * It should be used with helpers that creates required options, for example:
4958
 *
4959
 * MHD_DAEMON_SET_OPTIONS(d, MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES),
4960
 *                        MHD_D_OPTION_SOCK_ADDR(sa_len, sa))
4961
 *
4962
 * @param daemon the daemon to set the options
4963
 * @param ... the list of the options, each option must be created
4964
 *            by helpers MHD_D_OPTION_NameOfOption(option_value)
4965
 * @return ::MHD_SC_OK on success,
4966
 *         error code otherwise
4967
 */
4968
#    define MHD_DAEMON_SET_OPTIONS(daemon,...)                  \
4969
        MHD_NOWARN_CPP_INIT_LIST_                               \
4970
        MHD_daemon_set_options (                                \
4971
          daemon,                                               \
4972
          (std::vector<struct MHD_DaemonOptionAndValue>         \
4973
           {__VA_ARGS__,MHD_D_OPTION_TERMINATE ()}).data (),    \
4974
          MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
4975
        MHD_RESTORE_WARN_CPP_INIT_LIST_
4976
#  endif
4977
MHD_RESTORE_WARN_VARIADIC_MACROS_
4978
#endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
4979
/* *INDENT-ON* */
4980
4981
4982
/* ******************* Event loop ************************ */
4983
4984
4985
/**
4986
 * Run websever operation with possible blocking.
4987
 *
4988
 * Supported only in #MHD_WM_EXTERNAL_PERIODIC and
4989
 * #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes.
4990
 *
4991
 * This function does the following: waits for any network event not more than
4992
 * specified number of microseconds, processes all incoming and outgoing data,
4993
 * processes new connections, processes any timed-out connection, and does
4994
 * other things required to run webserver.
4995
 * Once all connections are processed, function returns.
4996
 *
4997
 * This function is useful for quick and simple (lazy) webserver implementation
4998
 * if application needs to run a single thread only and does not have any other
4999
 * network activity.
5000
 *
5001
 * In #MHD_WM_EXTERNAL_PERIODIC mode if @a microsec parameter is not zero
5002
 * this function determines the internal daemon timeout and use returned value
5003
 * as maximum wait time if it less than value of @a microsec parameter.
5004
 *
5005
 * @param daemon the daemon to run
5006
 * @param microsec the maximum time in microseconds to wait for network and
5007
 *                 other events. Note: there is no guarantee that function
5008
 *                 blocks for the specified amount of time. The real processing
5009
 *                 time can be shorter (if some data or connection timeout
5010
 *                 comes earlier) or longer (if data processing requires more
5011
 *                 time, especially in user callbacks).
5012
 *                 If set to '0' then function does not block and processes
5013
 *                 only already available data (if any). Zero value is
5014
 *                 recommended when used in #MHD_WM_EXTERNAL_SINGLE_FD_WATCH
5015
 *                 and the watched FD has been triggered.
5016
 *                 If set to #MHD_WAIT_INDEFINITELY then function waits
5017
 *                 for events indefinitely (blocks until next network activity
5018
 *                 or connection timeout).
5019
 *                 Always used as zero value in
5020
 *                 #MHD_WM_EXTERNAL_SINGLE_FD_WATCH mode.
5021
 * @return #MHD_SC_OK on success, otherwise
5022
 *         an error code
5023
 * @ingroup event
5024
 */
5025
MHD_EXTERN_ enum MHD_StatusCode
5026
MHD_daemon_process_blocking (struct MHD_Daemon *daemon,
5027
                             uint_fast64_t microsec)
5028
MHD_FN_PAR_NONNULL_ (1);
5029
5030
/**
5031
 * Run webserver operations (without blocking unless in client
5032
 * callbacks).
5033
 *
5034
 * Supported only in #MHD_WM_EXTERNAL_SINGLE_FD_WATCH mode.
5035
 *
5036
 * This function does the following: processes all incoming and outgoing data,
5037
 * processes new connections, processes any timed-out connection, and does
5038
 * other things required to run webserver.
5039
 * Once all connections are processed, function returns.
5040
 *
5041
 * @param daemon the daemon to run
5042
 * @return #MHD_SC_OK on success, otherwise
5043
 *         an error code
5044
 * @ingroup event
5045
 */
5046
#define MHD_daemon_process_nonblocking(daemon) \
5047
        MHD_daemon_process_blocking (daemon, 0)
5048
5049
5050
/**
5051
 * Add another client connection to the set of connections managed by
5052
 * MHD.  This API is usually not needed (since MHD will accept inbound
5053
 * connections on the server socket).  Use this API in special cases,
5054
 * for example if your HTTP server is behind NAT and needs to connect
5055
 * out to the HTTP client, or if you are building a proxy.
5056
 *
5057
 * The given client socket will be managed (and closed!) by MHD after
5058
 * this call and must no longer be used directly by the application
5059
 * afterwards.
5060
 * The client socket will be closed by MHD even if error returned.
5061
 *
5062
 * @param daemon daemon that manages the connection
5063
 * @param client_socket socket to manage (MHD will expect
5064
 *        to receive an HTTP request from this socket next).
5065
 * @param[in] addr IP address of the client
5066
 * @param addrlen number of bytes in @a addr
5067
 * @param connection_cntx meta data the application wants to
5068
 *        associate with the new connection object
5069
 * @return #MHD_SC_OK on success,
5070
 *         error on failure (the @a client_socket is closed)
5071
 * @ingroup specialized
5072
 */
5073
MHD_EXTERN_ enum MHD_StatusCode
5074
MHD_daemon_add_connection (struct MHD_Daemon *MHD_RESTRICT daemon,
5075
                           MHD_Socket client_socket,
5076
                           size_t addrlen,
5077
                           const struct sockaddr *MHD_RESTRICT addr,
5078
                           void *connection_cntx)
5079
MHD_FN_PAR_NONNULL_ (1)
5080
MHD_FN_PAR_IN_ (4);
5081
5082
5083
/* ********************* connection options ************** */
5084
5085
enum MHD_FIXED_ENUM_APP_SET_ MHD_ConnectionOption
5086
{
5087
  /**
5088
   * Not a real option.
5089
   * Should not be used directly.
5090
   * This value indicates the end of the list of the options.
5091
   */
5092
  MHD_C_O_END = 0
5093
  ,
5094
  /**
5095
   * Set custom timeout for the given connection.
5096
   * Specified as the number of seconds.  Use zero for no timeout.
5097
   * Setting this option resets connection timeout timer.
5098
   */
5099
  MHD_C_O_TIMEOUT = 1
5100
  ,
5101
5102
5103
  /* * Sentinel * */
5104
  /**
5105
   * The sentinel value.
5106
   * This value enforces specific underlying integer type for the enum.
5107
   * Do not use.
5108
   */
5109
  MHD_C_O_SENTINEL = 65535
5110
};
5111
5112
5113
/**
5114
 * Dummy-struct for space allocation.
5115
 * Do not use in application logic.
5116
 */
5117
struct MHD_ReservedStruct
5118
{
5119
  uint_fast64_t reserved1;
5120
  void *reserved2;
5121
};
5122
5123
5124
/**
5125
 * Parameters for MHD connection options
5126
 */
5127
union MHD_ConnectionOptionValue
5128
{
5129
  /**
5130
   * Value for #MHD_C_O_TIMEOUT
5131
   */
5132
  unsigned int v_timeout;
5133
  /**
5134
   * Reserved member. Do not use.
5135
   */
5136
  struct MHD_ReservedStruct reserved;
5137
};
5138
5139
/**
5140
 * Combination of MHD connection option with parameters values
5141
 */
5142
struct MHD_ConnectionOptionAndValue
5143
{
5144
  /**
5145
   * The connection configuration option
5146
   */
5147
  enum MHD_ConnectionOption opt;
5148
  /**
5149
   * The value for the @a opt option
5150
   */
5151
  union MHD_ConnectionOptionValue val;
5152
};
5153
5154
#if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)
5155
/**
5156
 * Set custom timeout for the given connection.
5157
 * Specified as the number of seconds.  Use zero for no timeout.
5158
 * Setting this option resets connection timeout timer.
5159
 * @param timeout the in seconds, zero for no timeout
5160
 * @return the object of struct MHD_ConnectionOptionAndValue with the requested
5161
 *         values
5162
 */
5163
#  define MHD_C_OPTION_TIMEOUT(timeout)         \
5164
        MHD_NOWARN_COMPOUND_LITERALS_                 \
5165
          (const struct MHD_ConnectionOptionAndValue) \
5166
        {                                             \
5167
          .opt = (MHD_C_O_TIMEOUT),                   \
5168
          .val.v_timeout = (timeout)                  \
5169
        }                                             \
5170
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
5171
5172
/**
5173
 * Terminate the list of the options
5174
 * @return the terminating object of struct MHD_ConnectionOptionAndValue
5175
 */
5176
#  define MHD_C_OPTION_TERMINATE()              \
5177
        MHD_NOWARN_COMPOUND_LITERALS_                 \
5178
          (const struct MHD_ConnectionOptionAndValue) \
5179
        {                                             \
5180
          .opt = (MHD_C_O_END)                        \
5181
        }                                             \
5182
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
5183
5184
#else  /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
5185
MHD_NOWARN_UNUSED_FUNC_
5186
5187
/**
5188
 * Set custom timeout for the given connection.
5189
 * Specified as the number of seconds.  Use zero for no timeout.
5190
 * Setting this option resets connection timeout timer.
5191
 * @param timeout the in seconds, zero for no timeout
5192
 * @return the object of struct MHD_ConnectionOptionAndValue with the requested
5193
 *         values
5194
 */
5195
static MHD_INLINE struct MHD_ConnectionOptionAndValue
5196
MHD_C_OPTION_TIMEOUT (unsigned int timeout)
5197
0
{
5198
0
  struct MHD_ConnectionOptionAndValue opt_val;
5199
0
5200
0
  opt_val.opt = MHD_C_O_TIMEOUT;
5201
0
  opt_val.val.v_timeout = timeout;
5202
0
5203
0
  return opt_val;
5204
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_C_OPTION_TIMEOUT(unsigned int)
Unexecuted instantiation: connection_helper.cpp:MHD_C_OPTION_TIMEOUT(unsigned int)
5205
5206
5207
/**
5208
 * Terminate the list of the options
5209
 * @return the terminating object of struct MHD_ConnectionOptionAndValue
5210
 */
5211
static MHD_INLINE struct MHD_ConnectionOptionAndValue
5212
MHD_C_OPTION_TERMINATE (void)
5213
0
{
5214
0
  struct MHD_ConnectionOptionAndValue opt_val;
5215
0
5216
0
  opt_val.opt = MHD_C_O_END;
5217
0
5218
0
  return opt_val;
5219
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_C_OPTION_TERMINATE()
Unexecuted instantiation: connection_helper.cpp:MHD_C_OPTION_TERMINATE()
5220
5221
5222
MHD_RESTORE_WARN_UNUSED_FUNC_
5223
#endif /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */
5224
5225
/**
5226
 * Set the requested options for the connection.
5227
 *
5228
 * If any option fail other options may be or may be not applied.
5229
 * @param connection the connection to set the options
5230
 * @param[in] options the pointer to the array with the options;
5231
 *                    the array processing stops at the first ::MHD_D_O_END
5232
 *                    option, but not later than after processing
5233
 *                    @a options_max_num entries
5234
 * @param options_max_num the maximum number of entries in the @a options,
5235
 *                        use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
5236
 *                        must stop only at zero-termination option
5237
 * @return ::MHD_SC_OK on success,
5238
 *         error code otherwise
5239
 */
5240
MHD_EXTERN_ enum MHD_StatusCode
5241
MHD_connection_set_options (
5242
  struct MHD_Connection *MHD_RESTRICT connection,
5243
  const struct MHD_ConnectionOptionAndValue *MHD_RESTRICT options,
5244
  size_t options_max_num)
5245
MHD_FN_PAR_NONNULL_ALL_;
5246
5247
5248
/**
5249
 * Set the requested single option for the connection.
5250
 *
5251
 * @param connection the connection to set the options
5252
 * @param[in] option_ptr the pointer to the option
5253
 * @return ::MHD_SC_OK on success,
5254
 *         error code otherwise
5255
 */
5256
#define MHD_connection_set_option(connection, option_ptr) \
5257
        MHD_connection_set_options (connection, options_ptr, 1)
5258
5259
5260
/* *INDENT-OFF* */
5261
#ifdef MHD_USE_VARARG_MACROS
5262
MHD_NOWARN_VARIADIC_MACROS_
5263
#  if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_COMP_LIT_FUNC_PARAMS \
5264
                                                    )
5265
/**
5266
 * Set the requested options for the connection.
5267
 *
5268
 * If any option fail other options may be or may be not applied.
5269
 *
5270
 * It should be used with helpers that creates required options, for example:
5271
 *
5272
 * MHD_CONNECTION_SET_OPTIONS(d, MHD_C_OPTION_TIMEOUT(30))
5273
 *
5274
 * @param connection the connection to set the options
5275
 * @param ... the list of the options, each option must be created
5276
 *            by helpers MHD_C_OPTION_NameOfOption(option_value)
5277
 * @return ::MHD_SC_OK on success,
5278
 *         error code otherwise
5279
 */
5280
#    define MHD_CONNECTION_SET_OPTIONS(connection,...)          \
5281
        MHD_NOWARN_COMPOUND_LITERALS_                           \
5282
        MHD_connection_set_options (                            \
5283
          daemon,                                               \
5284
          ((const struct MHD_ConnectionOptionAndValue [])       \
5285
           {__VA_ARGS__, MHD_C_OPTION_TERMINATE ()}),           \
5286
          MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
5287
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
5288
#  elif defined(MHD_USE_CPP_INIT_LIST)
5289
MHD_C_DECLRATIONS_FINISH_HERE_
5290
#    include <vector>
5291
MHD_C_DECLRATIONS_START_HERE_
5292
/**
5293
 * Set the requested options for the connection.
5294
 *
5295
 * If any option fail other options may be or may be not applied.
5296
 *
5297
 * It should be used with helpers that creates required options, for example:
5298
 *
5299
 * MHD_CONNECTION_SET_OPTIONS(d, MHD_C_OPTION_TIMEOUT(30))
5300
 *
5301
 * @param connection the connection to set the options
5302
 * @param ... the list of the options, each option must be created
5303
 *            by helpers MHD_C_OPTION_NameOfOption(option_value)
5304
 * @return ::MHD_SC_OK on success,
5305
 *         error code otherwise
5306
 */
5307
#    define MHD_CONNECTION_SET_OPTIONS(daemon,...)              \
5308
        MHD_NOWARN_CPP_INIT_LIST_                               \
5309
        MHD_daemon_set_options (                                \
5310
          daemon,                                               \
5311
          (std::vector<struct MHD_ConnectionOptionAndValue>     \
5312
           {__VA_ARGS__,MHD_C_OPTION_TERMINATE ()}).data (),    \
5313
          MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
5314
        MHD_RESTORE_WARN_CPP_INIT_LIST_
5315
#  endif
5316
MHD_RESTORE_WARN_VARIADIC_MACROS_
5317
#endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
5318
/* *INDENT-ON* */
5319
5320
5321
/* **************** Request handling functions ***************** */
5322
5323
5324
/**
5325
 * The `enum MHD_ValueKind` specifies the source of
5326
 * the name-value pairs in the HTTP protocol.
5327
 */
5328
enum MHD_FLAGS_ENUM_ MHD_ValueKind
5329
{
5330
5331
  /**
5332
   * HTTP header.
5333
   */
5334
  MHD_VK_HEADER = (1u << 0)
5335
  ,
5336
  /**
5337
   * Cookies.  Note that the original HTTP header containing
5338
   * the cookie(s) will still be available and intact.
5339
   */
5340
  MHD_VK_COOKIE = (1u << 1)
5341
  ,
5342
  /**
5343
   * GET (URI) arguments.
5344
   */
5345
  MHD_VK_GET_ARGUMENT = (1u << 2)
5346
  ,
5347
  /**
5348
   * POST data.
5349
   * This is available only if #MHD_action_parse_post() action is used,
5350
   * a content encoding is supported by MHD, and only if the posted content
5351
   * fits within the specified memory buffers.
5352
   *
5353
   * @warning The encoding "multipart/form-data" has more fields than just
5354
   * "name" and "value". See #MHD_request_get_post_data_cb() and
5355
   * #MHD_request_get_post_data_list(). In particular it could be important
5356
   * to check used "Transfer-Encoding". While it is deprecated and not used
5357
   * by modern clients, formally it can be used.
5358
   */
5359
  MHD_VK_POSTDATA = (1u << 3)
5360
  ,
5361
  /**
5362
   * HTTP footer (only for HTTP 1.1 chunked encodings).
5363
   */
5364
  MHD_VK_FOOTER = (1u << 4)
5365
  ,
5366
  /**
5367
   * Header and footer values
5368
   */
5369
  MHD_VK_HEADER_FOOTER = MHD_VK_HEADER | MHD_VK_FOOTER
5370
  ,
5371
  /**
5372
   * Values from get arguments or post data
5373
   */
5374
  MHD_VK_GET_POST = MHD_VK_POSTDATA | MHD_VK_GET_ARGUMENT
5375
};
5376
5377
/**
5378
 * Name with value pair
5379
 */
5380
struct MHD_NameAndValue
5381
{
5382
  /**
5383
   * The name (key) of the field.
5384
   * The pointer to the C string must never be NULL.
5385
   * Some types (kinds) allow empty strings.
5386
   */
5387
  struct MHD_String name;
5388
  /**
5389
   * The value of the field.
5390
   * Some types (kinds) allow absence of the value. The absence is indicated
5391
   * by NULL pointer to the C string.
5392
   */
5393
  struct MHD_StringNullable value;
5394
};
5395
5396
/**
5397
 * Name, value and kind (type) of data
5398
 */
5399
struct MHD_NameValueKind
5400
{
5401
  /**
5402
   * The name and the value of the field
5403
   */
5404
  struct MHD_NameAndValue nv;
5405
  /**
5406
   * The kind (type) of the field
5407
   */
5408
  enum MHD_ValueKind kind;
5409
};
5410
5411
/**
5412
 * Iterator over name-value pairs.  This iterator can be used to
5413
 * iterate over all of the cookies, headers, footers or POST-data fields
5414
 * of a request.
5415
 *
5416
 * The @a nv pointer is valid only until return from this function.
5417
 *
5418
 * For @a kind other then #MHD_VK_POSTDATA the pointers to the strings in @a nv
5419
 * are valid until the response is queued.
5420
 * For the #MHD_VK_POSTDATA @a kind the pointers to the strings in @a nv
5421
 * are valid until any MHD_UploadAction is provided.
5422
 * If the data is needed beyond this point, it should be copied.
5423
 *
5424
 * @param cls closure
5425
 * @param nv the name and the value of the element, the pointer is valid only until
5426
 *           return from this function
5427
 * @param kind the type (kind) of the element
5428
 * @return #MHD_YES to continue iterating,
5429
 *         #MHD_NO to abort the iteration
5430
 * @ingroup request
5431
 */
5432
typedef enum MHD_Bool
5433
(MHD_FN_PAR_NONNULL_ (3)
5434
 *MHD_NameValueIterator)(void *cls,
5435
                         enum MHD_ValueKind kind,
5436
                         const struct MHD_NameAndValue *nv);
5437
5438
5439
/**
5440
 * Get all of the headers (or other kind of request data) via callback.
5441
 *
5442
 * @param[in,out] request request to get values from
5443
 * @param kind types of values to iterate over, can be a bitmask
5444
 * @param iterator callback to call on each header;
5445
 *        maybe NULL (then just count headers)
5446
 * @param iterator_cls extra argument to @a iterator
5447
 * @return number of entries iterated over
5448
 * @ingroup request
5449
 */
5450
MHD_EXTERN_ size_t
5451
MHD_request_get_values_cb (struct MHD_Request *request,
5452
                           enum MHD_ValueKind kind,
5453
                           MHD_NameValueIterator iterator,
5454
                           void *iterator_cls)
5455
MHD_FN_PAR_NONNULL_ (1);
5456
5457
5458
/**
5459
 * Get all of the headers (or other kind of request data) from the request.
5460
 *
5461
 * The pointers to the strings in @a elements are valid until any
5462
 * MHD_Action or MHD_UploadAction is provided. If the data is needed beyond
5463
 * this point, it should be copied.
5464
 *
5465
 * @param[in] request request to get values from
5466
 * @param kind the types of values to get, can be a bitmask
5467
 * @param num_elements the number of elements in @a elements array
5468
 * @param[out] elements the array of @a num_elements strings to be filled with
5469
 *                      the key-value pairs; if @a request has more elements
5470
 *                      than @a num_elements than any @a num_elements are
5471
 *                      stored
5472
 * @return the number of elements stored in @a elements, the
5473
 *         number cannot be larger then @a num_elements,
5474
 *         zero if there is no such values or any error occurs
5475
 */
5476
MHD_EXTERN_ size_t
5477
MHD_request_get_values_list (
5478
  struct MHD_Request *request,
5479
  enum MHD_ValueKind kind,
5480
  size_t num_elements,
5481
  struct MHD_NameValueKind elements[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)])
5482
MHD_FN_PAR_NONNULL_ (1)
5483
MHD_FN_PAR_NONNULL_ (4) MHD_FN_PAR_OUT_SIZE_ (4,3);
5484
5485
5486
/**
5487
 * Get a particular header (or other kind of request data) value.
5488
 * If multiple values match the kind, return any one of them.
5489
 *
5490
 * The returned pointer is valid until any MHD_Action or MHD_UploadAction is
5491
 * provided. If the data is needed beyond this point, it should be copied.
5492
 *
5493
 * @param request request to get values from
5494
 * @param kind what kind of value are we looking for
5495
 * @param key the name of the value looking for (used for case-insensetive
5496
              match), empty to lookup 'trailing' value without a key
5497
 * @return NULL if no such item was found,
5498
 *         non-NULL if item found (the inner pointer to string can be NULL
5499
 *         if item found, but has no value)
5500
 * @ingroup request
5501
 */
5502
MHD_EXTERN_ const struct MHD_StringNullable *
5503
MHD_request_get_value (struct MHD_Request *MHD_RESTRICT request,
5504
                       enum MHD_ValueKind kind,
5505
                       const char *MHD_RESTRICT key)
5506
MHD_FN_PAR_NONNULL_ (1)
5507
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3);
5508
5509
5510
/**
5511
 * @brief Status codes defined for HTTP responses.
5512
 *
5513
 * @defgroup httpcode HTTP response codes
5514
 * @{
5515
 */
5516
/* Registry export date: 2023-09-29 */
5517
/* See http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */
5518
enum MHD_FIXED_ENUM_APP_SET_ MHD_HTTP_StatusCode
5519
{
5520
  /* 100 "Continue".            RFC9110, Section 15.2.1. */
5521
  MHD_HTTP_STATUS_CONTINUE =                    100
5522
  ,
5523
  /* 101 "Switching Protocols". RFC9110, Section 15.2.2. */
5524
  MHD_HTTP_STATUS_SWITCHING_PROTOCOLS =         101
5525
  ,
5526
  /* 102 "Processing".          RFC2518. */
5527
  MHD_HTTP_STATUS_PROCESSING =                  102
5528
  ,
5529
  /* 103 "Early Hints".         RFC8297. */
5530
  MHD_HTTP_STATUS_EARLY_HINTS =                 103
5531
  ,
5532
5533
  /* 200 "OK".                  RFC9110, Section 15.3.1. */
5534
  MHD_HTTP_STATUS_OK =                          200
5535
  ,
5536
  /* 201 "Created".             RFC9110, Section 15.3.2. */
5537
  MHD_HTTP_STATUS_CREATED =                     201
5538
  ,
5539
  /* 202 "Accepted".            RFC9110, Section 15.3.3. */
5540
  MHD_HTTP_STATUS_ACCEPTED =                    202
5541
  ,
5542
  /* 203 "Non-Authoritative Information". RFC9110, Section 15.3.4. */
5543
  MHD_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203
5544
  ,
5545
  /* 204 "No Content".          RFC9110, Section 15.3.5. */
5546
  MHD_HTTP_STATUS_NO_CONTENT =                  204
5547
  ,
5548
  /* 205 "Reset Content".       RFC9110, Section 15.3.6. */
5549
  MHD_HTTP_STATUS_RESET_CONTENT =               205
5550
  ,
5551
  /* 206 "Partial Content".     RFC9110, Section 15.3.7. */
5552
  MHD_HTTP_STATUS_PARTIAL_CONTENT =             206
5553
  ,
5554
  /* 207 "Multi-Status".        RFC4918. */
5555
  MHD_HTTP_STATUS_MULTI_STATUS =                207
5556
  ,
5557
  /* 208 "Already Reported".    RFC5842. */
5558
  MHD_HTTP_STATUS_ALREADY_REPORTED =            208
5559
  ,
5560
5561
  /* 226 "IM Used".             RFC3229. */
5562
  MHD_HTTP_STATUS_IM_USED =                     226
5563
  ,
5564
5565
  /* 300 "Multiple Choices".    RFC9110, Section 15.4.1. */
5566
  MHD_HTTP_STATUS_MULTIPLE_CHOICES =            300
5567
  ,
5568
  /* 301 "Moved Permanently".   RFC9110, Section 15.4.2. */
5569
  MHD_HTTP_STATUS_MOVED_PERMANENTLY =           301
5570
  ,
5571
  /* 302 "Found".               RFC9110, Section 15.4.3. */
5572
  MHD_HTTP_STATUS_FOUND =                       302
5573
  ,
5574
  /* 303 "See Other".           RFC9110, Section 15.4.4. */
5575
  MHD_HTTP_STATUS_SEE_OTHER =                   303
5576
  ,
5577
  /* 304 "Not Modified".        RFC9110, Section 15.4.5. */
5578
  MHD_HTTP_STATUS_NOT_MODIFIED =                304
5579
  ,
5580
  /* 305 "Use Proxy".           RFC9110, Section 15.4.6. */
5581
  MHD_HTTP_STATUS_USE_PROXY =                   305
5582
  ,
5583
  /* 306 "Switch Proxy".        Not used! RFC9110, Section 15.4.7. */
5584
  MHD_HTTP_STATUS_SWITCH_PROXY =                306
5585
  ,
5586
  /* 307 "Temporary Redirect".  RFC9110, Section 15.4.8. */
5587
  MHD_HTTP_STATUS_TEMPORARY_REDIRECT =          307
5588
  ,
5589
  /* 308 "Permanent Redirect".  RFC9110, Section 15.4.9. */
5590
  MHD_HTTP_STATUS_PERMANENT_REDIRECT =          308
5591
  ,
5592
5593
  /* 400 "Bad Request".         RFC9110, Section 15.5.1. */
5594
  MHD_HTTP_STATUS_BAD_REQUEST =                 400
5595
  ,
5596
  /* 401 "Unauthorized".        RFC9110, Section 15.5.2. */
5597
  MHD_HTTP_STATUS_UNAUTHORIZED =                401
5598
  ,
5599
  /* 402 "Payment Required".    RFC9110, Section 15.5.3. */
5600
  MHD_HTTP_STATUS_PAYMENT_REQUIRED =            402
5601
  ,
5602
  /* 403 "Forbidden".           RFC9110, Section 15.5.4. */
5603
  MHD_HTTP_STATUS_FORBIDDEN =                   403
5604
  ,
5605
  /* 404 "Not Found".           RFC9110, Section 15.5.5. */
5606
  MHD_HTTP_STATUS_NOT_FOUND =                   404
5607
  ,
5608
  /* 405 "Method Not Allowed".  RFC9110, Section 15.5.6. */
5609
  MHD_HTTP_STATUS_METHOD_NOT_ALLOWED =          405
5610
  ,
5611
  /* 406 "Not Acceptable".      RFC9110, Section 15.5.7. */
5612
  MHD_HTTP_STATUS_NOT_ACCEPTABLE =              406
5613
  ,
5614
  /* 407 "Proxy Authentication Required". RFC9110, Section 15.5.8. */
5615
  MHD_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407
5616
  ,
5617
  /* 408 "Request Timeout".     RFC9110, Section 15.5.9. */
5618
  MHD_HTTP_STATUS_REQUEST_TIMEOUT =             408
5619
  ,
5620
  /* 409 "Conflict".            RFC9110, Section 15.5.10. */
5621
  MHD_HTTP_STATUS_CONFLICT =                    409
5622
  ,
5623
  /* 410 "Gone".                RFC9110, Section 15.5.11. */
5624
  MHD_HTTP_STATUS_GONE =                        410
5625
  ,
5626
  /* 411 "Length Required".     RFC9110, Section 15.5.12. */
5627
  MHD_HTTP_STATUS_LENGTH_REQUIRED =             411
5628
  ,
5629
  /* 412 "Precondition Failed". RFC9110, Section 15.5.13. */
5630
  MHD_HTTP_STATUS_PRECONDITION_FAILED =         412
5631
  ,
5632
  /* 413 "Content Too Large".   RFC9110, Section 15.5.14. */
5633
  MHD_HTTP_STATUS_CONTENT_TOO_LARGE =           413
5634
  ,
5635
  /* 414 "URI Too Long".        RFC9110, Section 15.5.15. */
5636
  MHD_HTTP_STATUS_URI_TOO_LONG =                414
5637
  ,
5638
  /* 415 "Unsupported Media Type". RFC9110, Section 15.5.16. */
5639
  MHD_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE =      415
5640
  ,
5641
  /* 416 "Range Not Satisfiable". RFC9110, Section 15.5.17. */
5642
  MHD_HTTP_STATUS_RANGE_NOT_SATISFIABLE =       416
5643
  ,
5644
  /* 417 "Expectation Failed".  RFC9110, Section 15.5.18. */
5645
  MHD_HTTP_STATUS_EXPECTATION_FAILED =          417
5646
  ,
5647
5648
5649
  /* 421 "Misdirected Request". RFC9110, Section 15.5.20. */
5650
  MHD_HTTP_STATUS_MISDIRECTED_REQUEST =         421
5651
  ,
5652
  /* 422 "Unprocessable Content". RFC9110, Section 15.5.21. */
5653
  MHD_HTTP_STATUS_UNPROCESSABLE_CONTENT =       422
5654
  ,
5655
  /* 423 "Locked".              RFC4918. */
5656
  MHD_HTTP_STATUS_LOCKED =                      423
5657
  ,
5658
  /* 424 "Failed Dependency".   RFC4918. */
5659
  MHD_HTTP_STATUS_FAILED_DEPENDENCY =           424
5660
  ,
5661
  /* 425 "Too Early".           RFC8470. */
5662
  MHD_HTTP_STATUS_TOO_EARLY =                   425
5663
  ,
5664
  /* 426 "Upgrade Required".    RFC9110, Section 15.5.22. */
5665
  MHD_HTTP_STATUS_UPGRADE_REQUIRED =            426
5666
  ,
5667
5668
  /* 428 "Precondition Required". RFC6585. */
5669
  MHD_HTTP_STATUS_PRECONDITION_REQUIRED =       428
5670
  ,
5671
  /* 429 "Too Many Requests".   RFC6585. */
5672
  MHD_HTTP_STATUS_TOO_MANY_REQUESTS =           429
5673
  ,
5674
5675
  /* 431 "Request Header Fields Too Large". RFC6585. */
5676
  MHD_HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
5677
  ,
5678
5679
  /* 451 "Unavailable For Legal Reasons". RFC7725. */
5680
  MHD_HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451
5681
  ,
5682
5683
  /* 500 "Internal Server Error". RFC9110, Section 15.6.1. */
5684
  MHD_HTTP_STATUS_INTERNAL_SERVER_ERROR =       500
5685
  ,
5686
  /* 501 "Not Implemented".     RFC9110, Section 15.6.2. */
5687
  MHD_HTTP_STATUS_NOT_IMPLEMENTED =             501
5688
  ,
5689
  /* 502 "Bad Gateway".         RFC9110, Section 15.6.3. */
5690
  MHD_HTTP_STATUS_BAD_GATEWAY =                 502
5691
  ,
5692
  /* 503 "Service Unavailable". RFC9110, Section 15.6.4. */
5693
  MHD_HTTP_STATUS_SERVICE_UNAVAILABLE =         503
5694
  ,
5695
  /* 504 "Gateway Timeout".     RFC9110, Section 15.6.5. */
5696
  MHD_HTTP_STATUS_GATEWAY_TIMEOUT =             504
5697
  ,
5698
  /* 505 "HTTP Version Not Supported". RFC9110, Section 15.6.6. */
5699
  MHD_HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED =  505
5700
  ,
5701
  /* 506 "Variant Also Negotiates". RFC2295. */
5702
  MHD_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES =     506
5703
  ,
5704
  /* 507 "Insufficient Storage". RFC4918. */
5705
  MHD_HTTP_STATUS_INSUFFICIENT_STORAGE =        507
5706
  ,
5707
  /* 508 "Loop Detected".       RFC5842. */
5708
  MHD_HTTP_STATUS_LOOP_DETECTED =               508
5709
  ,
5710
5711
  /* 510 "Not Extended".        (OBSOLETED) RFC2774; status-change-http-experiments-to-historic. */
5712
  MHD_HTTP_STATUS_NOT_EXTENDED =                510
5713
  ,
5714
  /* 511 "Network Authentication Required". RFC6585. */
5715
  MHD_HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511
5716
  ,
5717
5718
5719
  /* Not registered non-standard codes */
5720
  /* 449 "Reply With".          MS IIS extension. */
5721
  MHD_HTTP_STATUS_RETRY_WITH =                  449
5722
  ,
5723
5724
  /* 450 "Blocked by Windows Parental Controls". MS extension. */
5725
  MHD_HTTP_STATUS_BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450
5726
  ,
5727
5728
  /* 509 "Bandwidth Limit Exceeded". Apache extension. */
5729
  MHD_HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED =    509
5730
};
5731
5732
5733
/**
5734
 * Returns the string status for a response code.
5735
 *
5736
 * This function works for @b HTTP status code, not for @b MHD error codes/
5737
 * @param code the HTTP code to get text representation for
5738
 * @return the pointer to the text representation,
5739
 *         NULL if HTTP status code in not known.
5740
 */
5741
MHD_EXTERN_ const struct MHD_String *
5742
MHD_HTTP_status_code_to_string (enum MHD_HTTP_StatusCode code)
5743
MHD_FN_CONST_;
5744
5745
/**
5746
 * Get the pointer to the C string for the HTTP response code, never NULL.
5747
 */
5748
#define MHD_HTTP_status_code_to_string_lazy(code) \
5749
        (MHD_HTTP_status_code_to_string ((code)) ? \
5750
         ((MHD_HTTP_status_code_to_string (code))->cstr) : ("[No status]") )
5751
5752
5753
/** @} */ /* end of group httpcode */
5754
5755
#ifndef MHD_HTTP_PROTOCOL_VER_DEFINED
5756
5757
/**
5758
 * @brief HTTP protocol versions
5759
 * @defgroup versions HTTP versions
5760
 * @{
5761
 */
5762
enum MHD_FIXED_ENUM_MHD_SET_ MHD_HTTP_ProtocolVersion
5763
{
5764
  MHD_HTTP_VERSION_INVALID = 0
5765
  ,
5766
  MHD_HTTP_VERSION_1_0 = 1
5767
  ,
5768
  MHD_HTTP_VERSION_1_1 = 2
5769
  ,
5770
  MHD_HTTP_VERSION_2 = 3
5771
  ,
5772
  MHD_HTTP_VERSION_3 = 4
5773
  ,
5774
  MHD_HTTP_VERSION_FUTURE = 255
5775
};
5776
5777
#define MHD_HTTP_PROTOCOL_VER_DEFINED 1
5778
#endif /* ! MHD_HTTP_PROTOCOL_VER_DEFINED */
5779
5780
/**
5781
 * Return the string representation of the requested HTTP version.
5782
 * Note: this is suitable mainly for logging and similar proposes as
5783
 * HTTP/2 (and later) is not used inside the HTTP protocol.
5784
 * @param pv the protocol version
5785
 * @return the string representation of the protocol version,
5786
 *         NULL for invalid values
5787
 */
5788
MHD_EXTERN_ const struct MHD_String *
5789
MHD_protocol_version_to_string (enum MHD_HTTP_ProtocolVersion pv)
5790
MHD_FN_CONST_;
5791
5792
/**
5793
 * HTTP/1.0 identification string
5794
 */
5795
#define MHD_HTTP_VERSION_1_0_STR "HTTP/1.0"
5796
/**
5797
 * HTTP/1.1 identification string
5798
 */
5799
#define MHD_HTTP_VERSION_1_1_STR "HTTP/1.1"
5800
/**
5801
 * HTTP/2 identification string.
5802
 * Not used by the HTTP protocol (except non-TLS handshake), useful for logs and
5803
 * similar proposes.
5804
 */
5805
#define MHD_HTTP_VERSION_2_STR "HTTP/2"
5806
/**
5807
 * HTTP/3 identification string.
5808
 * Not used by the HTTP protocol, useful for logs and similar proposes.
5809
 */
5810
#define MHD_HTTP_VERSION_3_STR "HTTP/3"
5811
5812
/** @} */ /* end of group versions */
5813
5814
5815
/**
5816
 * Resume handling of network data for suspended request.
5817
 * It is safe to resume a suspended request at any time.
5818
 * Calling this function on a request that was not previously suspended will
5819
 * result in undefined behaviour.
5820
 *
5821
 * @param[in,out] request the request to resume
5822
 */
5823
MHD_EXTERN_ void
5824
MHD_request_resume (struct MHD_Request *request)
5825
MHD_FN_PAR_NONNULL_ALL_;
5826
5827
5828
/* ************** Action and Response manipulation functions **************** */
5829
5830
/**
5831
 * @defgroup response Response objects control
5832
 */
5833
5834
5835
/**
5836
 * Name with value pair as C strings
5837
 */
5838
struct MHD_NameValueCStr
5839
{
5840
  /**
5841
   * The name (key) of the field.
5842
   * Must never be NULL.
5843
   * Some types (kinds) allow empty strings.
5844
   */
5845
  const char *name;
5846
  /**
5847
   * The value of the field.
5848
   * Some types (kinds) allow absence of the value. The absence is indicated
5849
   * by NULL pointer.
5850
   */
5851
  const char *value;
5852
};
5853
5854
/**
5855
 * Data transmitted in response to an HTTP request.
5856
 * Usually the final action taken in response to
5857
 * receiving a request.
5858
 */
5859
struct MHD_Response;
5860
5861
5862
/**
5863
 * Suspend handling of network data for a given request.  This can
5864
 * be used to dequeue a request from MHD's event loop for a while.
5865
 *
5866
 * Suspended requests continue to count against the total number of
5867
 * requests allowed (per daemon, as well as per IP, if such limits
5868
 * are set).  Suspended requests will NOT time out; timeouts will
5869
 * restart when the request handling is resumed.  While a
5870
 * request is suspended, MHD may not detect disconnects by the
5871
 * client.
5872
 *
5873
 * At most one action can be created for any request.
5874
 *
5875
 * @param[in,out] request the request for which the action is generated
5876
 * @return action to cause a request to be suspended,
5877
 *         NULL if any action has been already created for the @a request
5878
 * @ingroup action
5879
 */
5880
MHD_EXTERN_ const struct MHD_Action *
5881
MHD_action_suspend (struct MHD_Request *request)
5882
MHD_FN_PAR_NONNULL_ALL_;
5883
5884
5885
/**
5886
 * Converts a @a response to an action.  If #MHD_R_O_REUSABLE
5887
 * is not set, the reference to the @a response is consumed
5888
 * by the conversion. If #MHD_R_O_REUSABLE is #MHD_YES,
5889
 * then the @a response can be used again to create actions in
5890
 * the future.
5891
 * However, the @a response is frozen by this step and
5892
 * must no longer be modified (i.e. by setting headers).
5893
 *
5894
 * At most one action can be created for any request.
5895
 *
5896
 * @param request the request to create the action for
5897
 * @param[in] response the response to convert,
5898
 *                     if NULL then this function is equivalent to
5899
 *                     #MHD_action_abort_connection() call
5900
 * @return pointer to the action, the action must be consumed
5901
 *         otherwise response object may leak;
5902
 *         NULL if failed (no memory) or if any action has been already
5903
 *         created for the @a request;
5904
 *         when failed the response object is consumed and need not
5905
 *         to be "destroyed"
5906
 * @ingroup action
5907
 */
5908
MHD_EXTERN_ const struct MHD_Action *
5909
MHD_action_from_response (struct MHD_Request *MHD_RESTRICT request,
5910
                          struct MHD_Response *MHD_RESTRICT response)
5911
MHD_FN_PAR_NONNULL_ (1);
5912
5913
5914
/**
5915
 * Action telling MHD to close the connection hard
5916
 * (kind-of breaking HTTP specification).
5917
 *
5918
 * @param req the request to make an action
5919
 * @return action operation, always NULL
5920
 * @ingroup action
5921
 */
5922
#define MHD_action_abort_request(req) \
5923
        MHD_STATIC_CAST_ (const struct MHD_Action *, NULL)
5924
5925
5926
/**
5927
 * Set the requested options for the response.
5928
 *
5929
 * If any option fail other options may be or may be not applied.
5930
 * @param response the response to set the options
5931
 * @param[in] options the pointer to the array with the options;
5932
 *                    the array processing stops at the first ::MHD_D_O_END
5933
 *                    option, but not later than after processing
5934
 *                    @a options_max_num entries
5935
 * @param options_max_num the maximum number of entries in the @a options,
5936
 *                        use #MHD_OPTIONS_ARRAY_MAX_SIZE if options processing
5937
 *                        must stop only at zero-termination option
5938
 * @return ::MHD_SC_OK on success,
5939
 *         error code otherwise
5940
 */
5941
MHD_EXTERN_ enum MHD_StatusCode
5942
MHD_response_set_options (
5943
  struct MHD_Response *MHD_RESTRICT response,
5944
  const struct MHD_ResponseOptionAndValue *MHD_RESTRICT options,
5945
  size_t options_max_num)
5946
MHD_FN_PAR_NONNULL_ALL_;
5947
5948
5949
/**
5950
 * Set the requested single option for the response.
5951
 *
5952
 * @param response the response to set the option
5953
 * @param[in] option_ptr the pointer to the option
5954
 * @return ::MHD_SC_OK on success,
5955
 *         error code otherwise
5956
 * @ingroup response
5957
 */
5958
#define MHD_response_set_option(response,option_ptr) \
5959
        MHD_response_set_options (response,option_ptr,1)
5960
5961
5962
/* *INDENT-OFF* */
5963
#ifdef MHD_USE_VARARG_MACROS
5964
MHD_NOWARN_VARIADIC_MACROS_
5965
#  if defined(MHD_USE_COMPOUND_LITERALS) && \
5966
  defined(MHD_USE_COMP_LIT_FUNC_PARAMS)
5967
/**
5968
 * Set the requested options for the response.
5969
 *
5970
 * If any option fail other options may be or may be not applied.
5971
 *
5972
 * It should be used with helpers that creates required options, for example:
5973
 *
5974
 * MHD_RESPONE_SET_OPTIONS(d, MHD_R_OPTION_REUSABLE(MHD_YES),
5975
 *                         MHD_R_OPTION_TERMINATION_CALLBACK(func, cls))
5976
 *
5977
 * @param response the response to set the option
5978
 * @param ... the list of the options, each option must be created
5979
 *            by helpers MHD_RESPONSE_OPTION_NameOfOption(option_value)
5980
 * @return ::MHD_SC_OK on success,
5981
 *         error code otherwise
5982
 */
5983
#    define MHD_RESPONSE_SET_OPTIONS(response,...)              \
5984
        MHD_NOWARN_COMPOUND_LITERALS_                           \
5985
        MHD_response_set_options (                              \
5986
          response,                                             \
5987
          ((const struct MHD_ResponseOptionAndValue[])          \
5988
           {__VA_ARGS__, MHD_R_OPTION_TERMINATE ()}),           \
5989
          MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
5990
        MHD_RESTORE_WARN_COMPOUND_LITERALS_
5991
#  elif defined(MHD_USE_CPP_INIT_LIST)
5992
MHD_C_DECLRATIONS_FINISH_HERE_
5993
#    include <vector>
5994
MHD_C_DECLRATIONS_START_HERE_
5995
/**
5996
 * Set the requested options for the response.
5997
 *
5998
 * If any option fail other options may be or may be not applied.
5999
 *
6000
 * It should be used with helpers that creates required options, for example:
6001
 *
6002
 * MHD_RESPONE_SET_OPTIONS(d, MHD_R_OPTION_REUSABLE(MHD_YES),
6003
 *                         MHD_R_OPTION_TERMINATION_CALLBACK(func, cls))
6004
 *
6005
 * @param response the response to set the option
6006
 * @param ... the list of the options, each option must be created
6007
 *            by helpers MHD_RESPONSE_OPTION_NameOfOption(option_value)
6008
 * @return ::MHD_SC_OK on success,
6009
 *         error code otherwise
6010
 */
6011
#    define MHD_RESPONSE_SET_OPTIONS(response,...)              \
6012
        MHD_NOWARN_CPP_INIT_LIST_                               \
6013
        MHD_response_set_options (                              \
6014
          response,                                             \
6015
          (std::vector<struct MHD_ResponseOptionAndValue>       \
6016
           {__VA_ARGS__,MHD_R_OPTION_TERMINATE ()}).data (),    \
6017
          MHD_OPTIONS_ARRAY_MAX_SIZE)                           \
6018
        MHD_RESTORE_WARN_CPP_INIT_LIST_
6019
#  endif
6020
MHD_RESTORE_WARN_VARIADIC_MACROS_
6021
#endif /* MHD_USE_VARARG_MACROS && MHD_USE_COMP_LIT_FUNC_PARAMS */
6022
/* *INDENT-ON* */
6023
6024
#ifndef MHD_FREECALLBACK_DEFINED
6025
6026
/**
6027
 * This method is called by libmicrohttpd when response with dynamic content
6028
 * is being destroyed.  It should be used to free resources associated
6029
 * with the dynamic content.
6030
 *
6031
 * @param[in] free_cls closure
6032
 * @ingroup response
6033
 */
6034
typedef void
6035
(*MHD_FreeCallback) (void *free_cls);
6036
6037
#define MHD_FREECALLBACK_DEFINED 1
6038
#endif /* ! MHD_FREECALLBACK_DEFINED */
6039
#ifndef MHD_DYNCONTENTZCIOVEC_DEFINED
6040
6041
6042
/**
6043
 * Structure for iov type of the response.
6044
 * Used for zero-copy response content data.
6045
 */
6046
struct MHD_DynContentZCIoVec
6047
{
6048
  /**
6049
   * The number of elements in @a iov
6050
   */
6051
  unsigned int iov_count;
6052
  /**
6053
   * The pointer to the array with @a iov_count elements.
6054
   */
6055
  const struct MHD_IoVec *iov;
6056
  /**
6057
   * The callback to free resources.
6058
   * It is called once the full array of iov elements is sent.
6059
   * No callback is called if NULL.
6060
   */
6061
  MHD_FreeCallback iov_fcb;
6062
  /**
6063
   * The parameter for @a iov_fcb
6064
   */
6065
  void *iov_fcb_cls;
6066
};
6067
6068
#define MHD_DYNCONTENTZCIOVEC_DEFINED 1
6069
#endif /* ! MHD_DYNCONTENTZCIOVEC_DEFINED */
6070
6071
/**
6072
 * The action type returned by Dynamic Content Creator callback
6073
 */
6074
struct MHD_DynamicContentCreatorAction;
6075
6076
/**
6077
 * The context used for Dynamic Content Creator callback
6078
 */
6079
struct MHD_DynamicContentCreatorContext;
6080
6081
6082
/**
6083
 * Create "continue processing" action with optional chunk-extension.
6084
 * The data is provided in the buffer and/or in the zero-copy @a iov_data.
6085
 *
6086
 * If data is provided both in the buffer and @a ivo_data then
6087
 * data in the buffer sent first, following the iov data.
6088
 * The total size of the data in the buffer and in @a iov_data must
6089
 * be non-zero.
6090
 * If response content size is known and total size of content provided earlier
6091
 * for this request combined with the size provided by this action is larger
6092
 * then known response content size, then NULL is returned.
6093
 *
6094
 * At most one DCC action can be created for one content callback.
6095
 *
6096
 * @param[in,out] ctx the pointer the context as provided to the callback
6097
 * @param data_size the amount of the data placed to the provided buffer,
6098
 *                  cannot be larger than provided buffer size,
6099
 *                  must be non-zero if @a iov_data is NULL or has no data,
6100
 * @param iov_data the optional pointer to the iov data,
6101
 *                 must not be NULL and have non-zero size data if @a data_size
6102
 *                 is zero,
6103
 * @param chunk_ext the optional pointer to chunk extension string,
6104
 *                  can be NULL to not use chunk extension,
6105
 *                  ignored if chunked encoding is not used
6106
 * @return the pointer to the action if succeed,
6107
 *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
6108
 */
6109
MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction *
6110
MHD_DCC_action_continue_zc (
6111
  struct MHD_DynamicContentCreatorContext *ctx,
6112
  size_t data_size,
6113
  const struct MHD_DynContentZCIoVec *iov_data,
6114
  const char *MHD_RESTRICT chunk_ext)
6115
MHD_FN_PAR_NONNULL_ (1)
6116
MHD_FN_PAR_CSTR_ (4);
6117
6118
6119
/**
6120
 * Create "continue processing" action with optional chunk-extension.
6121
 * The data is provided in the buffer.
6122
 *
6123
 * At most one DCC action can be created for one content callback.
6124
 *
6125
 * @param[in,out] ctx the pointer the context as provided to the callback
6126
 * @param data_size the amount of the data placed to the provided buffer (not @a iov_data),
6127
 *                  cannot be larger than provided buffer size,
6128
 *                  must be non-zero.
6129
 * @param chunk_ext the optional pointer to chunk extension string,
6130
 *                  can be NULL to not use chunk extension,
6131
 *                  ignored if chunked encoding is not used
6132
 * @return the pointer to the action if succeed,
6133
 *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
6134
 */
6135
#define MHD_DCC_action_continue_ce(ctx,data_size,chunk_ext) \
6136
        MHD_DCC_action_continue_zc ((ctx), (data_size), NULL, (chunk_ext))
6137
6138
6139
/**
6140
 * Create "continue processing" action, the data is provided in the buffer.
6141
 *
6142
 * At most one DCC action can be created for one content callback.
6143
 *
6144
 * @param[in,out] ctx the pointer the context as provided to the callback
6145
 * @param data_size the amount of the data placed to the provided buffer;
6146
 *                  cannot be larger than provided buffer size,
6147
 *                  must be non-zero.
6148
 *
6149
 * @return the pointer to the action if succeed,
6150
 *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
6151
 */
6152
#define MHD_DCC_action_continue(ctx,data_size) \
6153
        MHD_DCC_action_continue_ce ((ctx), (data_size), NULL)
6154
6155
6156
/**
6157
 * Create "finished" action with optional footers.
6158
 * If function failed for any reason, the action is automatically
6159
 * set to "stop with error".
6160
 *
6161
 * At most one DCC action can be created for one content callback.
6162
 *
6163
 * @param[in,out] ctx the pointer the context as provided to the callback
6164
 * @param num_footers number of elements in the @a footers array,
6165
 *                    must be zero if @a footers is NULL
6166
 * @param footers the optional pointer to the array of the footers (the strings
6167
 *                are copied and does not need to be valid after return from
6168
 *                this function),
6169
 *                can be NULL if @a num_footers is zero
6170
 * @return the pointer to the action if succeed,
6171
 *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
6172
 */
6173
MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction *
6174
MHD_DCC_action_finish_with_footer (
6175
  struct MHD_DynamicContentCreatorContext *ctx,
6176
  size_t num_footers,
6177
  const struct MHD_NameValueCStr *MHD_RESTRICT footers)
6178
MHD_FN_PAR_NONNULL_ (1);
6179
6180
6181
/**
6182
 * Create "finished" action.
6183
 * If function failed for any reason, the action is automatically
6184
 * set to "stop with error".
6185
 *
6186
 * At most one DCC action can be created for one content callback.
6187
 *
6188
 * @param[in,out] ctx the pointer the context as provided to the callback
6189
 * @return the pointer to the action if succeed,
6190
 *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
6191
 */
6192
#define MHD_DCC_action_finish(ctx) \
6193
        MHD_DCC_action_finish_with_footer ((ctx), 0, NULL)
6194
6195
6196
/**
6197
 * Create "suspend" action.
6198
 * If function failed for any reason, the action is automatically
6199
 * set to "stop with error".
6200
 *
6201
 * At most one DCC action can be created for one content callback.
6202
 *
6203
 * @param[in,out] ctx the pointer the context as provided to the callback
6204
 * @return the pointer to the action if succeed,
6205
 *         NULL (equivalent of MHD_DCC_action_abort())in case of any error
6206
 */
6207
MHD_EXTERN_ const struct MHD_DynamicContentCreatorAction *
6208
MHD_DCC_action_suspend (struct MHD_DynamicContentCreatorContext *ctx)
6209
MHD_FN_PAR_NONNULL_ (1);
6210
6211
/**
6212
 * Create "stop with error" action.
6213
 * @param[in,out] ctx the pointer the context as provided to the callback
6214
 * @return always NULL (the action "stop with error")
6215
 */
6216
#define MHD_DCC_action_abort(ctx) \
6217
        MHD_STATIC_CAST_ (const struct MHD_DynamicContentCreatorAction *, NULL)
6218
6219
/**
6220
 * Callback used by libmicrohttpd in order to obtain content.  The
6221
 * callback is to copy at most @a max bytes of content into @a buf or
6222
 * provide zero-copy data for #MHD_DCC_action_continue_zc().
6223
 *
6224
 * @param dyn_cont_cls closure argument to the callback
6225
 * @param ctx the context to produce the action to return,
6226
 *            the pointer is only valid until the callback returns
6227
 * @param pos position in the datastream to access;
6228
 *        note that if a `struct MHD_Response` object is re-used,
6229
 *        it is possible for the same content reader to
6230
 *        be queried multiple times for the same data;
6231
 *        however, if a `struct MHD_Response` is not re-used,
6232
 *        libmicrohttpd guarantees that "pos" will be
6233
 *        the sum of all data sizes provided by this callback
6234
 * @param[out] buf where to copy the data
6235
 * @param max maximum number of bytes to copy to @a buf (size of @a buf),
6236
              if the size of the content of the response is known then size
6237
              of the buffer is never larger than amount of the content left
6238
 * @return action to use,
6239
 *         NULL in case of any error (the response will be aborted)
6240
 */
6241
typedef const struct MHD_DynamicContentCreatorAction *
6242
(MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (4)
6243
 *MHD_DynamicContentCreator)(void *dyn_cont_cls,
6244
                             struct MHD_DynamicContentCreatorContext *ctx,
6245
                             uint_fast64_t pos,
6246
                             void *buf,
6247
                             size_t max);
6248
6249
6250
/**
6251
 * Create a response.  The response object can be extended with
6252
 * header information.
6253
 *
6254
 * @param sc status code to return
6255
 * @param size size of the data portion of the response, #MHD_SIZE_UNKNOWN for unknown
6256
 * @param dyn_cont callback to use to obtain response data
6257
 * @param dyn_cont_cls extra argument to @a crc
6258
 * @param dyn_cont_fc callback to call to free @a dyn_cont_cls resources
6259
 * @return NULL on error (i.e. invalid arguments, out of memory)
6260
 * FIXME: Call free callback on error?
6261
 * @ingroup response
6262
 */
6263
MHD_EXTERN_ struct MHD_Response *
6264
MHD_response_from_callback (enum MHD_HTTP_StatusCode sc,
6265
                            uint_fast64_t size,
6266
                            MHD_DynamicContentCreator dyn_cont,
6267
                            void *dyn_cont_cls,
6268
                            MHD_FreeCallback dyn_cont_fc);
6269
6270
6271
/**
6272
 * Create a response object.  The response object can be extended with
6273
 * header information.
6274
 *
6275
 * @param sc status code to use for the response;
6276
 *           #MHD_HTTP_STATUS_NO_CONTENT is only valid if @a size is 0;
6277
 * @param buffer_size the size of the data portion of the response
6278
 * @param buffer the @a size bytes containing the response's data portion,
6279
 *               needs to be valid while the response is used
6280
 * @param free_cb the callback to free any allocated data, called
6281
 *                when response is being destroyed, can be NULL
6282
 *                to skip the free/cleanup callback;
6283
 * @param free_cb_cls the parameter for @a free_cb
6284
 * @return NULL on error (i.e. invalid arguments, out of memory)
6285
 *   on error, @a free_cb is NOT called
6286
 * @ingroup response
6287
 */
6288
MHD_EXTERN_ struct MHD_Response *
6289
MHD_response_from_buffer (
6290
  enum MHD_HTTP_StatusCode sc,
6291
  size_t buffer_size,
6292
  const char *buffer,
6293
  MHD_FreeCallback free_cb,
6294
  void *free_cb_cls)
6295
MHD_FN_PAR_IN_SIZE_ (3,2);
6296
6297
6298
/**
6299
 * Create a response object with body that is a
6300
 * statically allocated buffer that never needs to
6301
 * be freed as its lifetime exceeds that of the
6302
 * daemon.
6303
 *
6304
 * The response object can be extended with header information and then be used
6305
 * any number of times.
6306
 * @param sc status code to use for the response
6307
 * @param len number of bytes in @a buf
6308
 * @param buf buffer with response payload
6309
 */
6310
#define MHD_response_from_buffer_static(sc, len, buf)       \
6311
        MHD_response_from_buffer (sc, len, buf, NULL, NULL)
6312
6313
6314
/**
6315
 * Create a response object with empty (zero size) body.
6316
 *
6317
 * The response object can be extended with header information and then be used
6318
 * any number of times.
6319
 * @param sc status code to use for the response
6320
 */
6321
#define MHD_response_from_empty(sc) \
6322
        MHD_response_from_buffer_static (sc, 0, "")
6323
6324
6325
/**
6326
 * Create a response object.  The response object can be extended with
6327
 * header information.
6328
 *
6329
 * @param sc status code to use for the response
6330
 * @param buffer_size the size of the data portion of the response
6331
 * @param buffer the @a size bytes containing the response's data portion,
6332
 *               an internal copy will be made, there is no need to
6333
 *               keep this data after return from this function
6334
 * @return NULL on error (i.e. invalid arguments, out of memory)
6335
 * FIXME: Call free callback on error?
6336
 * @ingroup response
6337
 */
6338
MHD_EXTERN_ struct MHD_Response *
6339
MHD_response_from_buffer_copy (
6340
  enum MHD_HTTP_StatusCode sc,
6341
  size_t buffer_size,
6342
  const char buffer[MHD_FN_PAR_DYN_ARR_SIZE_ (buffer_size)])
6343
MHD_FN_PAR_IN_SIZE_ (3,2);
6344
6345
6346
/**
6347
 * I/O vector type. Provided for use with #MHD_response_from_iovec().
6348
 * @ingroup response
6349
 */
6350
struct MHD_IoVec
6351
{
6352
  /**
6353
   * The pointer to the memory region for I/O.
6354
   */
6355
  const void *iov_base;
6356
6357
  /**
6358
   * The size in bytes of the memory region for I/O.
6359
   */
6360
  size_t iov_len;
6361
};
6362
6363
6364
/**
6365
 * Create a response object with an array of memory buffers
6366
 * used as the response body.
6367
 *
6368
 * The response object can be extended with header information.
6369
 *
6370
 * If response object is used to answer HEAD request then the body
6371
 * of the response is not used, while all headers (including automatic
6372
 * headers) are used.
6373
 *
6374
 * @param sc status code to use for the response
6375
 * @param iov_count the number of elements in @a iov
6376
 * @param iov the array for response data buffers, an internal copy of this
6377
 *        will be made
6378
 * @param free_cb the callback to clean up any data associated with @a iov when
6379
 *        the response is destroyed.
6380
 * @param free_cb_cls the argument passed to @a free_cb
6381
 * @return NULL on error (i.e. invalid arguments, out of memory)
6382
 * FIXME: Call free callback on error?
6383
 * @ingroup response
6384
 */
6385
MHD_EXTERN_ struct MHD_Response *
6386
MHD_response_from_iovec (
6387
  enum MHD_HTTP_StatusCode sc,
6388
  unsigned int iov_count,
6389
  const struct MHD_IoVec iov[MHD_FN_PAR_DYN_ARR_SIZE_ (iov_count)],
6390
  MHD_FreeCallback free_cb,
6391
  void *free_cb_cls);
6392
6393
6394
/**
6395
 * Create a response object based on an @a fd from which
6396
 * data is read.  The response object can be extended with
6397
 * header information.
6398
 *
6399
 * @param sc status code to return
6400
 * @param fd file descriptor referring to a file on disk with the
6401
 *        data; will be closed when response is destroyed;
6402
 *        fd should be in 'blocking' mode
6403
 * @param offset offset to start reading from in the file;
6404
 *        reading file beyond 2 GiB may be not supported by OS or
6405
 *        MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
6406
 * @param size size of the data portion of the response;
6407
 *        sizes larger than 2 GiB may be not supported by OS or
6408
 *        MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
6409
 * @return NULL on error (i.e. invalid arguments, out of memory)
6410
 * FIXME: Close FD on error?
6411
 * @ingroup response
6412
 */
6413
MHD_EXTERN_ struct MHD_Response *
6414
MHD_response_from_fd (enum MHD_HTTP_StatusCode sc,
6415
                      int fd,
6416
                      uint_fast64_t offset,
6417
                      uint_fast64_t size)
6418
MHD_FN_PAR_FD_READ_ (2);
6419
6420
/**
6421
 * Create a response object with the response body created by reading
6422
 * the provided pipe.
6423
 *
6424
 * The response object can be extended with header information and
6425
 * then be used ONLY ONCE.
6426
 *
6427
 * If response object is used to answer HEAD request then the body
6428
 * of the response is not used, while all headers (including automatic
6429
 * headers) are used.
6430
 *
6431
 * @param sc status code to use for the response
6432
 * @param fd file descriptor referring to a read-end of a pipe with the
6433
 *        data; will be closed when response is destroyed;
6434
 *        fd should be in 'blocking' mode
6435
 * @return NULL on error (i.e. invalid arguments, out of memory)
6436
 * FIXME: Close pipe FD on error?
6437
 * @ingroup response
6438
 */
6439
MHD_EXTERN_ struct MHD_Response *
6440
MHD_response_from_pipe (enum MHD_HTTP_StatusCode sc,
6441
                        int fd)
6442
MHD_FN_PAR_FD_READ_ (2);
6443
6444
6445
/**
6446
 * Destroy response.
6447
 * Should be called if response was created but not consumed.
6448
 * Also must be called if response has #MHD_R_O_REUSABLE set.
6449
 * The actual destroy can be happen later, if the response
6450
 * is still being used in any request.
6451
 * The function does not block.
6452
 *
6453
 * @param[in] response the response to destroy
6454
 * @ingroup response
6455
 */
6456
MHD_EXTERN_ void
6457
MHD_response_destroy (struct MHD_Response *response)
6458
MHD_FN_PAR_NONNULL_ (1);
6459
6460
6461
/**
6462
 * Add a header line to the response.
6463
 *
6464
 * @param response response to add a header to, NULL is tolerated
6465
 * @param name the name of the header to add,
6466
 *             an internal copy of the string will be made
6467
 * @param value the value of the header to add,
6468
 *              an internal copy of the string will be made
6469
 * @return #MHD_SC_OK on success,
6470
 *         error code otherwise
6471
 * @ingroup response
6472
 */
6473
MHD_EXTERN_ enum MHD_StatusCode
6474
MHD_response_add_header (struct MHD_Response *MHD_RESTRICT response,
6475
                         const char *MHD_RESTRICT name,
6476
                         const char *MHD_RESTRICT value)
6477
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
6478
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3);
6479
6480
6481
/**
6482
 * Add a header with predefined (standard) name to the response.
6483
 *
6484
 * @param response response to add a header to
6485
 * @param stk the code of the predefined header
6486
 * @param content the value of the header to add,
6487
 *              an internal copy of the string will be made
6488
 * @return #MHD_SC_OK on success,
6489
 *         error code otherwise
6490
 * @ingroup response
6491
 */
6492
MHD_EXTERN_ enum MHD_StatusCode
6493
MHD_response_add_predef_header (struct MHD_Response *MHD_RESTRICT response,
6494
                                enum MHD_PredefinedHeader stk,
6495
                                const char *MHD_RESTRICT content)
6496
MHD_FN_PAR_NONNULL_ (1)
6497
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_CSTR_ (3);
6498
6499
6500
/* ************ (b) Upload and PostProcessor functions ********************** */
6501
6502
6503
/**
6504
 * Suspend handling of network data for a given request.  This can
6505
 * be used to dequeue a request from MHD's event loop for a while.
6506
 *
6507
 * Suspended requests continue to count against the total number of
6508
 * requests allowed (per daemon, as well as per IP, if such limits
6509
 * are set).  Suspended requests will NOT time out; timeouts will
6510
 * restart when the request handling is resumed.  While a
6511
 * request is suspended, MHD may not detect disconnects by the
6512
 * client.
6513
 *
6514
 * At most one upload action can be created for one upload callback.
6515
 *
6516
 * @param[in,out] request the request for which the action is generated
6517
 * @return action to cause a request to be suspended,
6518
 *         NULL if any action has been already created for the @a request
6519
 * @ingroup action
6520
 */
6521
MHD_EXTERN_ const struct MHD_UploadAction *
6522
MHD_upload_action_suspend (struct MHD_Request *request)
6523
MHD_FN_PAR_NONNULL_ALL_;
6524
6525
/**
6526
 * Converts a @a response to an action.  If #MHD_R_O_REUSABLE
6527
 * is not set, the reference to the @a response is consumed
6528
 * by the conversion. If #MHD_R_O_REUSABLE is #MHD_YES,
6529
 * then the @a response can be used again to create actions in
6530
 * the future.
6531
 * However, the @a response is frozen by this step and
6532
 * must no longer be modified (i.e. by setting headers).
6533
 *
6534
 * At most one upload action can be created for one upload callback.
6535
 *
6536
 * @param request the request to create the action for
6537
 * @param[in] response the response to convert,
6538
 *                     if NULL then this function is equivalent to
6539
 *                     #MHD_upload_action_abort_request() call
6540
 * @return pointer to the action, the action must be consumed
6541
 *         otherwise response object may leak;
6542
 *         NULL if failed (no memory) or if any action has been already
6543
 *         created for the @a request;
6544
 *         when failed the response object is consumed and need not
6545
 *         to be "destroyed"
6546
 * @ingroup action
6547
 */
6548
MHD_EXTERN_ const struct MHD_UploadAction *
6549
MHD_upload_action_from_response (struct MHD_Request *MHD_RESTRICT request,
6550
                                 struct MHD_Response *MHD_RESTRICT response)
6551
MHD_FN_PAR_NONNULL_ (1);
6552
6553
/**
6554
 * Action telling MHD to continue processing the upload.
6555
 * Valid only for incremental upload processing.
6556
 * Works as #MHD_upload_action_abort_request() if used for full upload callback
6557
 * or for the final (with zero data) incremental callback.
6558
 *
6559
 * At most one upload action can be created for one upload callback.
6560
 *
6561
 * @param request the request to make an action
6562
 * @return action operation,
6563
 *         NULL if any action has been already created for the @a request
6564
 * @ingroup action
6565
 */
6566
MHD_EXTERN_ const struct MHD_UploadAction *
6567
MHD_upload_action_continue (struct MHD_Request *request)
6568
MHD_FN_PAR_NONNULL_ (1);
6569
6570
6571
/**
6572
 * Action telling MHD to close the connection hard
6573
 * (kind-of breaking HTTP specification).
6574
 *
6575
 * @param req the request to make an action
6576
 * @return action operation, always NULL
6577
 * @ingroup action
6578
 */
6579
#define MHD_upload_action_abort_request(req) \
6580
        MHD_STATIC_CAST_ (const struct MHD_UploadAction *, NULL)
6581
6582
#ifndef MHD_UPLOADCALLBACK_DEFINED
6583
6584
/**
6585
 * Function to process data uploaded by a client.
6586
 *
6587
 * @param upload_cls the argument given together with the function
6588
 *                   pointer when the handler was registered with MHD
6589
 * @param request the request is being processed
6590
 * @param content_data_size the size of the @a content_data,
6591
 *                          zero when all data have been processed
6592
 * @param[in] content_data the uploaded content data,
6593
 *                         may be modified in the callback,
6594
 *                         valid only until return from the callback,
6595
 *                         NULL when all data have been processed
6596
 * @return action specifying how to proceed:
6597
 *         #MHD_upload_action_continue() to continue upload (for incremental
6598
 *         upload processing only),
6599
 *         #MHD_upload_action_suspend() to stop reading the upload until
6600
 *         the request is resumed,
6601
 *         #MHD_upload_action_abort_request() to close the socket,
6602
 *         or a response to discard the rest of the upload and transmit
6603
 *         the response
6604
 * @ingroup action
6605
 */
6606
typedef const struct MHD_UploadAction *
6607
(MHD_FN_PAR_NONNULL_ (2)  MHD_FN_PAR_INOUT_SIZE_ (4,3)
6608
 *MHD_UploadCallback)(void *upload_cls,
6609
                      struct MHD_Request *request,
6610
                      size_t content_data_size,
6611
                      void *content_data);
6612
6613
#define MHD_UPLOADCALLBACK_DEFINED 1
6614
#endif /* ! MHD_UPLOADCALLBACK_DEFINED */
6615
6616
/**
6617
 * Create an action that handles an upload.
6618
 *
6619
 * If @a uc_inc is NULL and upload cannot fit the allocated buffer
6620
 * then request is aborted without response.
6621
 *
6622
 * At most one action can be created for any request.
6623
 *
6624
 * @param request the request to create action for
6625
 * @param large_buffer_size how large should the upload buffer be.
6626
 *                          May allocate memory from the shared "large"
6627
 *                          memory pool if necessary and non-zero is given.
6628
 *                          Must be zero if @a uc_full is NULL.
6629
 * @param uc_full the function to call when complete upload
6630
 *                is received (only if fit @a upload_buffer_size),
6631
 *                can be NULL if uc_inc is not NULL,
6632
 *                must be NULL is @a upload_buffer_size is zero.
6633
 * @param uc_full_cls closure for @a uc_full
6634
 * @param uc_inc the function to incrementally process the upload data
6635
 *               if the upload if larger than @a upload_buffer_size or
6636
 *               @a upload_buffer_size cannot be allocated or
6637
 *               @a uc_full is NULL,
6638
 *               can be NULL if uc_full is not NULL
6639
 * @param uc_inc_cls closure for @a uc_inc
6640
 * @return NULL on error (out of memory, invalid parameters)
6641
 * @return pointer to the action,
6642
 *         NULL if failed (no memory) or if any action has been already
6643
 *         created for the @a request.
6644
 * @sa #MHD_D_OPTION_LARGE_POOL_SIZE()
6645
 * @ingroup action
6646
 */
6647
MHD_EXTERN_ const struct MHD_Action *
6648
MHD_action_process_upload (
6649
  struct MHD_Request *request,
6650
  size_t large_buffer_size,
6651
  MHD_UploadCallback uc_full,
6652
  void *uc_full_cls,
6653
  MHD_UploadCallback uc_inc,
6654
  void *uc_inc_cls)
6655
MHD_FN_PAR_NONNULL_ (1);
6656
6657
/**
6658
 * Create an action that handles an upload as full upload data.
6659
 *
6660
 * @param request the request to create action for
6661
 * @param buff_size how large should the upload buffer be. May allocate memory
6662
 *                  from the large memory pool if necessary. Must not be zero.
6663
 * @param uc the function to call when complete upload
6664
 *           is received (only if fit @a upload_buffer_size)
6665
 * @param uc_cls closure for @a uc
6666
 * @return NULL on error (out of memory. both @a uc is NULL)
6667
 * @ingroup action
6668
 */
6669
#define MHD_action_process_upload_full(request,buff_size,uc,uc_cls) \
6670
        MHD_action_process_upload (request, buff_size, uc, uc_cls, NULL, NULL)
6671
6672
/**
6673
 * Create an action that handles an upload incrementally.
6674
 *
6675
 * @param request the request to create action for
6676
 * @param uc the function to incrementally process the upload data
6677
 * @param uc_cls closure for @a uc
6678
 * @return NULL on error (out of memory. both @a uc is NULL)
6679
 * @ingroup action
6680
 */
6681
#define MHD_action_process_upload_inc(request,uc,uc_cls) \
6682
        MHD_action_process_upload (request, 0, NULL, NULL, uc, uc_cls)
6683
6684
#ifndef MHD_POST_PARSE_RESULT_DEFINED
6685
6686
/**
6687
 * The result of POST data parsing
6688
 */
6689
enum MHD_FIXED_ENUM_MHD_SET_ MHD_PostParseResult
6690
{
6691
  /**
6692
   * The POST data parsed successfully and completely.
6693
   */
6694
  MHD_POST_PARSE_RES_OK = 0
6695
  ,
6696
  /**
6697
   * The POST request has no content or zero-length content.
6698
   */
6699
  MHD_POST_PARSE_RES_REQUEST_EMPTY = 1
6700
  ,
6701
  /**
6702
   * The POST data parsed successfully, but has missing or incorrect
6703
   * termination.
6704
   * The last parsed field may have incorrect data.
6705
   */
6706
  MHD_POST_PARSE_RES_OK_BAD_TERMINATION = 2
6707
  ,
6708
  /**
6709
   * Parsing of the POST data is incomplete because client used incorrect
6710
   * format of POST encoding.
6711
   * The last parsed field may have incorrect data.
6712
   * Some POST data is available or has been provided via callback.
6713
   */
6714
  MHD_POST_PARSE_RES_PARTIAL_INVALID_POST_FORMAT = 3
6715
  ,
6716
  /**
6717
   * The POST data cannot be parsed completely because the stream has
6718
   * no free pool memory.
6719
   * Some POST data may be parsed.
6720
   */
6721
  MHD_POST_PARSE_RES_FAILED_NO_POOL_MEM = 60
6722
  ,
6723
  /**
6724
   * The POST data cannot be parsed completely because no "large shared buffer"
6725
   * space is available.
6726
   * Some POST data may be parsed.
6727
   */
6728
  MHD_POST_PARSE_RES_FAILED_NO_LARGE_BUF_MEM = 61
6729
  ,
6730
  /**
6731
   * The POST data cannot be parsed because 'Content-Type:' is unknown.
6732
   */
6733
  MHD_POST_PARSE_RES_FAILED_UNKNOWN_CNTN_TYPE = 80
6734
  ,
6735
  /**
6736
   * The POST data cannot be parsed because 'Content-Type:' header is not set.
6737
   */
6738
  MHD_POST_PARSE_RES_FAILED_NO_CNTN_TYPE = 81
6739
  ,
6740
  /**
6741
   * The POST data cannot be parsed because "Content-Type:" request header has
6742
   * no "boundary" parameter for "multipart/form-data"
6743
   */
6744
  MHD_POST_PARSE_RES_FAILED_HEADER_NO_BOUNDARY = 82
6745
  ,
6746
  /**
6747
   * The POST data cannot be parsed because "Content-Type: multipart/form-data"
6748
   * request header is misformed
6749
   */
6750
  MHD_POST_PARSE_RES_FAILED_HEADER_MISFORMED = 83
6751
  ,
6752
  /**
6753
   * The application set POST encoding to "multipart/form-data", but the request
6754
   * has no "Content-Type: multipart/form-data" header which is required
6755
   * to find "boundary" used in this encoding
6756
   */
6757
  MHD_POST_PARSE_RES_FAILED_HEADER_NOT_MPART = 84
6758
  ,
6759
  /**
6760
   * The POST data cannot be parsed because client used incorrect format
6761
   * of POST encoding.
6762
   */
6763
  MHD_POST_PARSE_RES_FAILED_INVALID_POST_FORMAT = 90
6764
6765
};
6766
6767
#define MHD_POST_PARSE_RESULT_DEFINED 1
6768
#endif /* ! MHD_POST_PARSE_RESULT_DEFINED */
6769
6770
#ifndef MHD_POST_DATA_READER_DEFINED
6771
6772
/**
6773
 * "Stream" reader for POST data.
6774
 * This callback is called to incrementally process parsed POST data sent by
6775
 * the client.
6776
 * The pointers to the MHD_String and MHD_StringNullable are valid only until
6777
 * return from this callback.
6778
 * The pointers to the strings and the @a data are valid only until return from
6779
 * this callback.
6780
 *
6781
 * @param req the request
6782
 * @param cls user-specified closure
6783
 * @param name the name of the POST field
6784
 * @param filename the name of the uploaded file, @a cstr member is NULL if not
6785
 *                 known / not provided
6786
 * @param content_type the mime-type of the data, cstr member is NULL if not
6787
 *                     known / not provided
6788
 * @param encoding the encoding of the data, cstr member is NULL if not known /
6789
 *                 not provided
6790
 * @param size the number of bytes in @a data available, may be zero if
6791
 *             the @a final_data is #MHD_YES
6792
 * @param data the pointer to @a size bytes of data at the specified
6793
 *             @a off offset, NOT zero-terminated
6794
 * @param off the offset of @a data in the overall value, always equal to
6795
 *            the sum of sizes of previous calls for the same field / file;
6796
 *            client may provide more than one field with the same name and
6797
 *            the same filename, the new filed (or file) is indicated by zero
6798
 *            value of @a off (and the end is indicated by @a final_data)
6799
 * @param final_data if set to #MHD_YES then full field data is provided,
6800
 *                   if set to #MHD_NO then more field data may be provided
6801
 * @return action specifying how to proceed:
6802
 *         #MHD_upload_action_continue() if all is well,
6803
 *         #MHD_upload_action_suspend() to stop reading the upload until
6804
 *         the request is resumed,
6805
 *         #MHD_upload_action_abort_request() to close the socket,
6806
 *         or a response to discard the rest of the upload and transmit
6807
 *         the response
6808
 * @ingroup action
6809
 */
6810
typedef const struct MHD_UploadAction *
6811
(MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_NONNULL_ (4)
6812
 MHD_FN_PAR_NONNULL_ (5) MHD_FN_PAR_NONNULL_ (6)
6813
 *MHD_PostDataReader) (struct MHD_Request *req,
6814
                       void *cls,
6815
                       const struct MHD_String *name,
6816
                       const struct MHD_StringNullable *filename,
6817
                       const struct MHD_StringNullable *content_type,
6818
                       const struct MHD_StringNullable *encoding,
6819
                       size_t size,
6820
                       const void *data,
6821
                       uint_fast64_t off,
6822
                       enum MHD_Bool final_data);
6823
6824
6825
/**
6826
 * The callback to be called when finished with processing
6827
 * of the postprocessor upload data.
6828
 * @param req the request
6829
 * @param cls the closure
6830
 * @param parsing_result the result of POST data parsing
6831
 * @return the action to proceed
6832
 */
6833
typedef const struct MHD_UploadAction *
6834
(MHD_FN_PAR_NONNULL_ (1)
6835
 *MHD_PostDataFinished) (struct MHD_Request *req,
6836
                         void *cls,
6837
                         enum MHD_PostParseResult parsing_result);
6838
6839
#define MHD_POST_DATA_READER_DEFINED 1
6840
#endif /* ! MHD_POST_DATA_READER_DEFINED */
6841
6842
/**
6843
 * Create an action to parse the POSTed content from the client.
6844
 *
6845
 * The action starts parsing of the POST data. Any value that does not fit
6846
 * @a buffer_size or larger that @a auto_stream_size is given to
6847
 * @a stream_reader (if it is not NULL).
6848
 *
6849
 * If @a buffer_size is zero, then buffers will be limited to the connection's
6850
 * memory pool. To force all POST data process via @a stream_reader
6851
 * set @a auto_stream_size to zero.
6852
 *
6853
 * At most one action can be created for any request.
6854
 *
6855
 * @param request the request to create action for
6856
 * @param buffer_size the maximum size allowed for the buffers to parse this
6857
 *                    request POST data. Within the set limit the buffer is
6858
 *                    allocated automatically from the "large" shared memory
6859
 *                    pool if necessary.
6860
 * @param max_nonstream_size the size of the field (in encoded form) above which
6861
 *                           values are not buffered and provided for
6862
 *                           the @a steam_reader automatically;
6863
 *                           useful to have large data (like file uploads)
6864
 *                           processed incrementally, while keeping buffer space
6865
 *                           for small fields only;
6866
 *                           ignored if @a stream_reader is NULL
6867
 * @param enc the data encoding to use,
6868
 *            use #MHD_HTTP_POST_ENCODING_OTHER to detect automatically
6869
 * @param stream_reader the function to call for "oversize" values in
6870
 *                      the stream; can be NULL if @a auto_stream_size is
6871
 *                      not zero
6872
 * @param reader_cls the closure for the @a stream_reader
6873
 * @param done_cb called once all data has been processed for
6874
 *   the final action; values smaller than @a auto_stream_size that
6875
 *   fit into @a buffer_size will be available via
6876
 *   #MHD_request_get_values_cb(), #MHD_request_get_values_list() and
6877
 *   #MHD_request_get_post_data_cb(), #MHD_request_get_post_data_list()
6878
 * @param done_cb_cls the closure for the @a done_cb
6879
 * @return pointer to the action,
6880
 *         NULL if failed (no memory) or if any action has been already
6881
 *         created for the @a request.
6882
 * @sa #MHD_D_OPTION_LARGE_POOL_SIZE()
6883
 * @ingroup action
6884
 */
6885
MHD_EXTERN_ const struct MHD_Action *
6886
MHD_action_parse_post (struct MHD_Request *request,
6887
                       size_t buffer_size,
6888
                       size_t max_nonstream_size,
6889
                       enum MHD_HTTP_PostEncoding enc,
6890
                       MHD_PostDataReader stream_reader,
6891
                       void *reader_cls,
6892
                       MHD_PostDataFinished done_cb,
6893
                       void *done_cb_cls)
6894
MHD_FN_PAR_NONNULL_ (1);
6895
6896
6897
#ifndef MHD_POSTFILED_DEFINED
6898
6899
/**
6900
 * Post data element.
6901
 * If any member is not provided/set then pointer to C string is NULL.
6902
 * If any member is set to empty string then pointer to C string not NULL,
6903
 * but the length is zero.
6904
 */
6905
struct MHD_PostField
6906
{
6907
  /**
6908
   * The name of the field
6909
   */
6910
  struct MHD_String name;
6911
  /**
6912
   * The field data
6913
   * If not set or defined then to C string is NULL.
6914
   * If set to empty string then pointer to C string not NULL,
6915
   * but the length is zero.
6916
   */
6917
  struct MHD_StringNullable value;
6918
  /**
6919
   * The filename if provided (only for "multipart/form-data")
6920
   * If not set or defined then to C string is NULL.
6921
   * If set to empty string then pointer to C string not NULL,
6922
   * but the length is zero.
6923
   */
6924
  struct MHD_StringNullable filename;
6925
  /**
6926
   * The Content-Type if provided (only for "multipart/form-data")
6927
   * If not set or defined then to C string is NULL.
6928
   * If set to empty string then pointer to C string not NULL,
6929
   * but the length is zero.
6930
   */
6931
  struct MHD_StringNullable content_type;
6932
  /**
6933
   * The Transfer-Encoding if provided (only for "multipart/form-data")
6934
   * If not set or defined then to C string is NULL.
6935
   * If set to empty string then pointer to C string not NULL,
6936
   * but the length is zero.
6937
   */
6938
  struct MHD_StringNullable transfer_encoding;
6939
};
6940
6941
#define MHD_POSTFILED_DEFINED 1
6942
#endif /* ! MHD_POSTFILED_DEFINED */
6943
6944
6945
/**
6946
 * Iterator over POST data.
6947
 *
6948
 * The @a data pointer is valid only until return from this function.
6949
 *
6950
 * The pointers to the strings in @a data are valid until any MHD_UploadAction
6951
 * is provided. If the data is needed beyond this point, it should be copied.
6952
 *
6953
 * @param cls closure
6954
 * @param data the element of the post data, the pointer is valid only until
6955
 *             return from this function
6956
 * @return #MHD_YES to continue iterating,
6957
 *         #MHD_NO to abort the iteration
6958
 * @ingroup request
6959
 */
6960
typedef enum MHD_Bool
6961
(MHD_FN_PAR_NONNULL_ (2)
6962
 *MHD_PostDataIterator)(void *cls,
6963
                        const struct MHD_PostField *data);
6964
6965
/**
6966
 * Get all of the post data from the request via request.
6967
 *
6968
 * @param request the request to get data for
6969
 * @param iterator callback to call on each header;
6970
 *        maybe NULL (then just count headers)
6971
 * @param iterator_cls extra argument to @a iterator
6972
 * @return number of entries iterated over
6973
 * @ingroup request
6974
 */
6975
MHD_EXTERN_ size_t
6976
MHD_request_get_post_data_cb (struct MHD_Request *request,
6977
                              MHD_PostDataIterator iterator,
6978
                              void *iterator_cls)
6979
MHD_FN_PAR_NONNULL_ (1);
6980
6981
/**
6982
 * Get all of the post data from the request.
6983
 *
6984
 * The pointers to the strings in @a elements are valid until any
6985
 * MHD_UploadAction is provided. If the data is needed beyond this point,
6986
 * it should be copied.
6987
 * @param request the request to get data for
6988
 * @param num_elements the number of elements in @a elements array
6989
 * @param[out] elements the array of @a num_elements to get the data
6990
 * @return the number of elements stored in @a elements,
6991
 *         zero if no data or postprocessor was not used.
6992
 * @ingroup request
6993
 */
6994
MHD_EXTERN_ size_t
6995
MHD_request_get_post_data_list (
6996
  struct MHD_Request *request,
6997
  size_t num_elements,
6998
  struct MHD_PostField elements[MHD_FN_PAR_DYN_ARR_SIZE_ (num_elements)])
6999
MHD_FN_PAR_NONNULL_ (1)
7000
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_SIZE_ (3,2);
7001
7002
/* ***************** (c) WebSocket support ********** */
7003
7004
/**
7005
 * Handle given to the application to manage special
7006
 * actions relating to MHD responses that "upgrade"
7007
 * the HTTP protocol (i.e. to WebSockets).
7008
 */
7009
struct MHD_UpgradedHandle;
7010
7011
7012
#ifndef MHD_UPGRADEHANDLER_DEFINED
7013
7014
/**
7015
 * Function called after a protocol "upgrade" response was sent successfully
7016
 * and the connection is being switched to other protocol.
7017
 *
7018
 * The newly provided handle @a urh can be used to send and receive the data
7019
 * by #MHD_upgraded_send() and #MHD_upgraded_recv(). The handle must be closed
7020
 * by #MHD_upgraded_close() before destroying the daemon.
7021
 *
7022
 * "Upgraded" connection will not time out, but still counted for daemon
7023
 * global connections limit and for per-IP limit (if set).
7024
 *
7025
 * Except when in 'thread-per-connection' mode, implementations
7026
 * of this function should never block (as it will still be called
7027
 * from within the main event loop).
7028
 *
7029
 * @param cls closure, whatever was given to #MHD_action_upgrade().
7030
 * @param request original HTTP request handle,
7031
 *                giving the function a last chance
7032
 *                to inspect the original HTTP request
7033
 * @param urh argument for #MHD_upgrade_operation() on this @a response.
7034
 *        Applications must eventually use this callback to (indirectly)
7035
 *        perform the close() action on the @a sock.
7036
 */
7037
typedef void
7038
(MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3)
7039
 *MHD_UpgradeHandler)(void *cls,
7040
                      struct MHD_Request *MHD_RESTRICT request,
7041
                      struct MHD_UpgradedHandle *MHD_RESTRICT urh);
7042
7043
#define MHD_UPGRADEHANDLER_DEFINED 1
7044
#endif /* ! MHD_UPGRADEHANDLER_DEFINED */
7045
7046
7047
/**
7048
 * Create a action object that can be used for 101 Upgrade
7049
 * responses, for example to implement WebSockets.  After sending the
7050
 * response, control over the data stream is given to the callback (which
7051
 * can then, for example, start some bi-directional communication).
7052
 * The callback will ONLY be called after the response header was successfully
7053
 * passed to the OS; if there are communication errors before, the usual MHD
7054
 * connection error handling code will be performed.
7055
 *
7056
 * At most one action can be created for any request.
7057
 *
7058
 * @param request the request to create action for
7059
 * @param upgrade_hdr_value the value of the "Upgrade:" header, mandatory
7060
                            string
7061
 * @param upgrade_handler function to call with the "upgraded" socket
7062
 * @param upgrade_handler_cls closure for @a upgrade_handler
7063
 * @param num_headers number of elements in the @a headers array,
7064
 *                    must be zero if @a headers is NULL
7065
 * @param headers the optional pointer to the array of the headers (the strings
7066
 *                are copied and does not need to be valid after return from
7067
 *                this function),
7068
 *                can be NULL if @a num_headers is zero
7069
 * @return NULL on error (i.e. invalid arguments, out of memory)
7070
 * @ingroup action
7071
 */
7072
MHD_EXTERN_ const struct MHD_Action *
7073
MHD_action_upgrade (struct MHD_Request *MHD_RESTRICT request,
7074
                    const char *MHD_RESTRICT upgrade_hdr_value,
7075
                    MHD_UpgradeHandler upgrade_handler,
7076
                    void *upgrade_handler_cls,
7077
                    size_t num_headers,
7078
                    const struct MHD_NameValueCStr *MHD_RESTRICT headers)
7079
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
7080
MHD_FN_PAR_IN_SIZE_ (6,5);
7081
7082
7083
/**
7084
 * Create a action object that can be used for 101 Upgrade
7085
 * responses, for example to implement WebSockets.  After sending the
7086
 * response, control over the data stream is given to the callback (which
7087
 * can then, for example, start some bi-directional communication).
7088
 * The callback will ONLY be called after the response header was successfully
7089
 * passed to the OS; if there are communication errors before, the usual MHD
7090
 * connection error handling code will be performed.
7091
 *
7092
 * At most one action can be created for any request.
7093
 *
7094
 * @param request the request to create action for
7095
 * @param upgrade_hdr_value the value of the "Upgrade:" header, mandatory
7096
                            string
7097
 * @param upgrade_handler function to call with the "upgraded" socket
7098
 * @param upgrade_handler_cls closure for @a upgrade_handler
7099
 * @param num_headers number of elements in the @a headers array,
7100
 *                    must be zero if @a headers is NULL
7101
 * @param headers the optional pointer to the array of the headers (the strings
7102
 *                are copied and does not need to be valid after return from
7103
 *                this function),
7104
 *                can be NULL if @a num_headers is zero
7105
 * @return NULL on error (i.e. invalid arguments, out of memory)
7106
 * @ingroup action
7107
 */
7108
MHD_EXTERN_ const struct MHD_UploadAction *
7109
MHD_upload_action_upgrade (
7110
  struct MHD_Request *MHD_RESTRICT request,
7111
  const char *MHD_RESTRICT upgrade_hdr_value,
7112
  MHD_UpgradeHandler upgrade_handler,
7113
  void *upgrade_handler_cls,
7114
  size_t num_headers,
7115
  const struct MHD_NameValueCStr *MHD_RESTRICT headers)
7116
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
7117
MHD_FN_PAR_IN_SIZE_ (6,5);
7118
7119
7120
/**
7121
 * Receive data on the HTTP-Upgraded connection.
7122
 *
7123
 * The function finished if one of the following happens:
7124
 * + ANY amount of data has been received,
7125
 * + timeout reached,
7126
 * + network error occurs
7127
 *
7128
 * @param urh the HTTP-Upgraded handle
7129
 * @param recv_buf_size the size of the @a recv_buf
7130
 * @param recv_buf the buffer to receive the data
7131
 * @param received_size the pointer to variable to get amount of received data
7132
 * @param max_wait_millisec the maximum wait time for the data,
7133
 *                          non-blocking operation if set to zero,
7134
 *                          wait indefinitely if larger or equal to
7135
 *                          #MHD_WAIT_INDEFINITELY,
7136
 *                          the function may return earlier if waiting is
7137
 *                          interrupted or by other reasons
7138
 * @return #MHD_SC_OK if ANY data received (check the @a received_size) or
7139
 *                    remote shut down send side (indicated by @a received_size
7140
 *                    set to zero),
7141
 *         #MHD_SC_UPGRADED_NET_TIMEOUT if NO data received but timeout expired,
7142
 *         #MHD_SC_UPGRADED_NET_CONN_CLOSED if network connection has been
7143
 *                                          closed,
7144
 *         #MHD_SC_UPGRADED_NET_CONN_BROKEN if broken network connection has
7145
 *                                          been detected,
7146
 *         #MHD_SC_UPGRADED_TLS_ERROR if TLS error occurs (only for TLS),
7147
 *         #MHD_SC_UPGRADED_NET_HARD_ERROR if any other network or sockets
7148
 *                                         unrecoverable error occurs,
7149
 *         #MHD_SC_UPGRADED_HANDLE_INVALID if @a urh is invalid,
7150
 *         #MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED if timed wait is not supported
7151
 *                                                by this MHD build or platform
7152
 */
7153
MHD_EXTERN_ enum MHD_StatusCode
7154
MHD_upgraded_recv (struct MHD_UpgradedHandle *MHD_RESTRICT urh,
7155
                   size_t recv_buf_size,
7156
                   void *MHD_RESTRICT recv_buf,
7157
                   size_t *MHD_RESTRICT received_size,
7158
                   uint_fast64_t max_wait_millisec)
7159
MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (3,2)
7160
MHD_FN_PAR_OUT_ (4);
7161
7162
7163
/**
7164
 * Send data on the HTTP-Upgraded connection.
7165
 *
7166
 * The function finished if one of the following happens:
7167
 * + ALL provided data has been sent,
7168
 * + timeout reached,
7169
 * + network error occurs
7170
 *
7171
 * Parameter @a more_data_to_come controls network buffering. When set to
7172
 * #MHD_YES, the OS waits shortly for additional data and tries to use
7173
 * the network more effeciently delaying the last network packet, if it is
7174
 * incomplete, to combine it with the next data provided.
7175
 *
7176
 * @param urh the HTTP-Upgraded handle
7177
 * @param send_buf_size the amount of data in the @a send_buf
7178
 * @param send_buf the buffer with the data to send
7179
 * @param sent_size the pointer to get the amout of sent data
7180
 * @param max_wait_millisec the maximum wait time for the data,
7181
 *                          non-blocking operation if set to zero,
7182
 *                          wait indefinitely if larger or equal to
7183
 *                          #MHD_WAIT_INDEFINITELY
7184
 * @param more_data_to_come set to #MHD_YES if the provided data in
7185
 *                          the @a send_buf is part of a larger data package,
7186
 *                          like an incomplete message or streamed
7187
 *                          (not the final) part of some file, and more data
7188
 *                          expected to be sent soon over the same connection,
7189
 *                          set to #MHD_NO the data in the @a send_buf is
7190
 *                          the complete message or the final part of
7191
 *                          the message (or file) and it should be pushed
7192
 *                          to the network (and to the client) as soon
7193
 *                          as possible
7194
 * @return #MHD_SC_OK if ANY data sent (check the @a sent_size),
7195
 *         #MHD_SC_UPGRADED_NET_TIMEOUT if NO data sent but timeout expired,
7196
 *         #MHD_SC_UPGRADED_NET_CONN_CLOSED if network connection has been
7197
 *                                          closed,
7198
 *         #MHD_SC_UPGRADED_NET_CONN_BROKEN if broken network connection has
7199
 *                                          been detected,
7200
 *         #MHD_SC_UPGRADED_TLS_ERROR if TLS error occurs (only for TLS),
7201
 *         #MHD_SC_UPGRADED_NET_HARD_ERROR if any other network or sockets
7202
 *                                         unrecoverable error occurs,
7203
 *         #MHD_SC_UPGRADED_HANDLE_INVALID if @a urh is invalid,
7204
 *         #MHD_SC_UPGRADED_WAITING_NOT_SUPPORTED if timed wait is not supported
7205
 *                                                by this MHD build or platform
7206
 */
7207
MHD_EXTERN_ enum MHD_StatusCode
7208
MHD_upgraded_send (struct MHD_UpgradedHandle *MHD_RESTRICT urh,
7209
                   size_t send_buf_size,
7210
                   const void *MHD_RESTRICT send_buf,
7211
                   size_t *MHD_RESTRICT sent_size,
7212
                   uint_fast64_t max_wait_millisec,
7213
                   enum MHD_Bool more_data_to_come)
7214
MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (3,2)
7215
MHD_FN_PAR_OUT_ (4);
7216
7217
7218
/**
7219
 * Close HTTP-Upgraded connection handle.
7220
 *
7221
 * The handle cannot be used after successful return from this function.
7222
 *
7223
 * The function cannot fail if called correctly (the daemon is not destroyed
7224
 * and the upgraded connection has not been closed yet).
7225
 *
7226
 * @param urh the handle to close
7227
 * @return #MHD_SC_OK on success,
7228
 *         error code otherwise
7229
 */
7230
MHD_EXTERN_ enum MHD_StatusCode
7231
MHD_upgraded_close (struct MHD_UpgradedHandle *urh)
7232
MHD_FN_PAR_NONNULL_ (1);
7233
7234
7235
/* ********************** (e) Client auth ********************** */
7236
7237
7238
/**
7239
 * Length of the binary output of the MD5 hash function.
7240
 * @sa #MHD_digest_get_hash_size()
7241
 * @ingroup authentication
7242
 */
7243
0
#define MHD_MD5_DIGEST_SIZE 16
7244
7245
/**
7246
 * Length of the binary output of the SHA-256 hash function.
7247
 * @sa #MHD_digest_get_hash_size()
7248
 * @ingroup authentication
7249
 */
7250
0
#define MHD_SHA256_DIGEST_SIZE 32
7251
7252
/**
7253
 * Length of the binary output of the SHA-512/256 hash function.
7254
 * @warning While this value is the same as the #MHD_SHA256_DIGEST_SIZE,
7255
 *          the calculated digests for SHA-256 and SHA-512/256 are different.
7256
 * @sa #MHD_digest_get_hash_size()
7257
 * @ingroup authentication
7258
 */
7259
#define MHD_SHA512_256_DIGEST_SIZE 32
7260
7261
/**
7262
 * Base type of hash calculation.
7263
 * Used as part of #MHD_DigestAuthAlgo values.
7264
 *
7265
 * @warning Not used directly by MHD API.
7266
 */
7267
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestBaseAlgo
7268
{
7269
  /**
7270
   * Invalid hash algorithm value
7271
   */
7272
  MHD_DIGEST_BASE_ALGO_INVALID = 0
7273
  ,
7274
  /**
7275
   * MD5 hash algorithm.
7276
   * As specified by RFC1321
7277
   */
7278
  MHD_DIGEST_BASE_ALGO_MD5 = (1u << 0)
7279
  ,
7280
  /**
7281
   * SHA-256 hash algorithm.
7282
   * As specified by FIPS PUB 180-4
7283
   */
7284
  MHD_DIGEST_BASE_ALGO_SHA256 = (1u << 1)
7285
  ,
7286
  /**
7287
   * SHA-512/256 hash algorithm.
7288
   * As specified by FIPS PUB 180-4
7289
   */
7290
  MHD_DIGEST_BASE_ALGO_SHA512_256 = (1u << 2)
7291
};
7292
7293
/**
7294
 * The flag indicating non-session algorithm types,
7295
 * like 'MD5', 'SHA-256' or 'SHA-512-256'.
7296
 */
7297
0
#define MHD_DIGEST_AUTH_ALGO_NON_SESSION    (1u << 6)
7298
7299
/**
7300
 * The flag indicating session algorithm types,
7301
 * like 'MD5-sess', 'SHA-256-sess' or 'SHA-512-256-sess'.
7302
 */
7303
0
#define MHD_DIGEST_AUTH_ALGO_SESSION        (1u << 7)
7304
7305
/**
7306
 * Digest algorithm identification
7307
 */
7308
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthAlgo
7309
{
7310
  /**
7311
   * Unknown or wrong algorithm type.
7312
   * Used in struct MHD_AuthDigestInfo to indicate client value that
7313
   * cannot by identified.
7314
   */
7315
  MHD_DIGEST_AUTH_ALGO_INVALID = 0
7316
  ,
7317
  /**
7318
   * The 'MD5' algorithm, non-session version.
7319
   */
7320
  MHD_DIGEST_AUTH_ALGO_MD5 =
7321
    MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO_NON_SESSION
7322
  ,
7323
  /**
7324
   * The 'MD5-sess' algorithm.
7325
   * Not supported by MHD for authentication.
7326
   */
7327
  MHD_DIGEST_AUTH_ALGO_MD5_SESSION =
7328
    MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_AUTH_ALGO_SESSION
7329
  ,
7330
  /**
7331
   * The 'SHA-256' algorithm, non-session version.
7332
   */
7333
  MHD_DIGEST_AUTH_ALGO_SHA256 =
7334
    MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_NON_SESSION
7335
  ,
7336
  /**
7337
   * The 'SHA-256-sess' algorithm.
7338
   * Not supported by MHD for authentication.
7339
   */
7340
  MHD_DIGEST_AUTH_ALGO_SHA256_SESSION =
7341
    MHD_DIGEST_BASE_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_SESSION
7342
  ,
7343
  /**
7344
   * The 'SHA-512-256' (SHA-512/256) algorithm.
7345
   */
7346
  MHD_DIGEST_AUTH_ALGO_SHA512_256 =
7347
    MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO_NON_SESSION
7348
  ,
7349
  /**
7350
   * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm.
7351
   * Not supported by MHD for authentication.
7352
   */
7353
  MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION =
7354
    MHD_DIGEST_BASE_ALGO_SHA512_256 | MHD_DIGEST_AUTH_ALGO_SESSION
7355
};
7356
7357
7358
/**
7359
 * Get digest size in bytes for specified algorithm.
7360
 *
7361
 * The size of the digest specifies the size of the userhash, userdigest
7362
 * and other parameters which size depends on used hash algorithm.
7363
 * @param algo the algorithm to check
7364
 * @return the size (in bytes) of the digest (either #MHD_MD5_DIGEST_SIZE or
7365
 *         #MHD_SHA256_DIGEST_SIZE/MHD_SHA512_256_DIGEST_SIZE)
7366
 *         or zero if the input value is not supported or not valid
7367
 * @sa #MHD_digest_auth_calc_userdigest()
7368
 * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex()
7369
 * @ingroup authentication
7370
 */
7371
MHD_EXTERN_ size_t
7372
MHD_digest_get_hash_size (enum MHD_DigestAuthAlgo algo)
7373
MHD_FN_CONST_;
7374
7375
/**
7376
 * Digest algorithm identification, allow multiple selection.
7377
 *
7378
 * #MHD_DigestAuthAlgo always can be casted to #MHD_DigestAuthMultiAlgo, but
7379
 * not vice versa.
7380
 */
7381
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiAlgo
7382
{
7383
  /**
7384
   * Unknown or wrong algorithm type.
7385
   */
7386
  MHD_DIGEST_AUTH_MULT_ALGO_INVALID = MHD_DIGEST_AUTH_ALGO_INVALID
7387
  ,
7388
  /**
7389
   * The 'MD5' algorithm, non-session version.
7390
   */
7391
  MHD_DIGEST_AUTH_MULT_ALGO_MD5 = MHD_DIGEST_AUTH_ALGO_MD5
7392
  ,
7393
  /**
7394
   * The 'MD5-sess' algorithm.
7395
   * Not supported by MHD for authentication.
7396
   * Reserved value.
7397
   */
7398
  MHD_DIGEST_AUTH_MULT_ALGO_MD5_SESSION = MHD_DIGEST_AUTH_ALGO_MD5_SESSION
7399
  ,
7400
  /**
7401
   * The 'SHA-256' algorithm, non-session version.
7402
   */
7403
  MHD_DIGEST_AUTH_MULT_ALGO_SHA256 = MHD_DIGEST_AUTH_ALGO_SHA256
7404
  ,
7405
  /**
7406
   * The 'SHA-256-sess' algorithm.
7407
   * Not supported by MHD for authentication.
7408
   * Reserved value.
7409
   */
7410
  MHD_DIGEST_AUTH_MULT_ALGO_SHA256_SESSION =
7411
    MHD_DIGEST_AUTH_ALGO_SHA256_SESSION
7412
  ,
7413
  /**
7414
   * The 'SHA-512-256' (SHA-512/256) algorithm, non-session version.
7415
   */
7416
  MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256 = MHD_DIGEST_AUTH_ALGO_SHA512_256
7417
  ,
7418
  /**
7419
   * The 'SHA-512-256-sess' (SHA-512/256 session) algorithm.
7420
   * Not supported by MHD for authentication.
7421
   * Reserved value.
7422
   */
7423
  MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_SESSION =
7424
    MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION
7425
  ,
7426
  /**
7427
   * SHA-256 or SHA-512/256 non-session algorithm, MHD will choose
7428
   * the preferred or the matching one.
7429
   */
7430
  MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_NON_SESSION =
7431
    MHD_DIGEST_AUTH_ALGO_SHA256 | MHD_DIGEST_AUTH_ALGO_SHA512_256
7432
  ,
7433
  /**
7434
   * Any non-session algorithm, MHD will choose the preferred or
7435
   * the matching one.
7436
   */
7437
  MHD_DIGEST_AUTH_MULT_ALGO_ANY_NON_SESSION =
7438
    (0x3F) | MHD_DIGEST_AUTH_ALGO_NON_SESSION
7439
  ,
7440
  /**
7441
   * The SHA-256 or SHA-512/256 session algorithm.
7442
   * Not supported by MHD.
7443
   * Reserved value.
7444
   */
7445
  MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_SESSION =
7446
    MHD_DIGEST_AUTH_ALGO_SHA256_SESSION
7447
    | MHD_DIGEST_AUTH_ALGO_SHA512_256_SESSION
7448
  ,
7449
  /**
7450
   * Any session algorithm.
7451
   * Not supported by MHD.
7452
   * Reserved value.
7453
   */
7454
  MHD_DIGEST_AUTH_MULT_ALGO_ANY_SESSION =
7455
    (0x3F) | MHD_DIGEST_AUTH_ALGO_SESSION
7456
  ,
7457
  /**
7458
   * The MD5 algorithm, session or non-session.
7459
   * Currently supported as non-session only.
7460
   */
7461
  MHD_DIGEST_AUTH_MULT_ALGO_MD5_ANY =
7462
    MHD_DIGEST_AUTH_MULT_ALGO_MD5 | MHD_DIGEST_AUTH_MULT_ALGO_MD5_SESSION
7463
  ,
7464
  /**
7465
   * The SHA-256 algorithm, session or non-session.
7466
   * Currently supported as non-session only.
7467
   */
7468
  MHD_DIGEST_AUTH_MULT_ALGO_SHA256_ANY =
7469
    MHD_DIGEST_AUTH_MULT_ALGO_SHA256
7470
    | MHD_DIGEST_AUTH_MULT_ALGO_SHA256_SESSION
7471
  ,
7472
  /**
7473
   * The SHA-512/256 algorithm, session or non-session.
7474
   * Currently supported as non-session only.
7475
   */
7476
  MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_ANY =
7477
    MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256
7478
    | MHD_DIGEST_AUTH_MULT_ALGO_SHA512_256_SESSION
7479
  ,
7480
  /**
7481
   * The SHA-256 or SHA-512/256 algorithm, session or non-session.
7482
   * Currently supported as non-session only.
7483
   */
7484
  MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_ANY =
7485
    MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_NON_SESSION
7486
    | MHD_DIGEST_AUTH_MULT_ALGO_SHA_ANY_SESSION
7487
  ,
7488
  /**
7489
   * Any algorithm, MHD will choose the preferred or the matching one.
7490
   */
7491
  MHD_DIGEST_AUTH_MULT_ALGO_ANY =
7492
    (0x3F) | MHD_DIGEST_AUTH_ALGO_NON_SESSION | MHD_DIGEST_AUTH_ALGO_SESSION
7493
};
7494
7495
7496
/**
7497
 * Calculate "userhash", return it as binary data.
7498
 *
7499
 * The "userhash" is the hash of the string "username:realm".
7500
 *
7501
 * The "userhash" could be used to avoid sending username in cleartext in Digest
7502
 * Authorization client's header.
7503
 *
7504
 * Userhash is not designed to hide the username in local database or files,
7505
 * as username in cleartext is required for #MHD_digest_auth_check() function
7506
 * to check the response, but it can be used to hide username in HTTP headers.
7507
 *
7508
 * This function could be used when the new username is added to the username
7509
 * database to save the "userhash" alongside with the username (preferably) or
7510
 * when loading list of the usernames to generate the userhash for every loaded
7511
 * username (this will cause delays at the start with the long lists).
7512
 *
7513
 * Once "userhash" is generated it could be used to identify users by clients
7514
 * with "userhash" support.
7515
 * Avoid repetitive usage of this function for the same username/realm
7516
 * combination as it will cause excessive CPU load; save and reuse the result
7517
 * instead.
7518
 *
7519
 * @param algo the algorithm for userhash calculations
7520
 * @param username the username
7521
 * @param realm the realm
7522
 * @param[out] userhash_bin the output buffer for userhash as binary data;
7523
 *                          if this function succeeds, then this buffer has
7524
 *                          #MHD_digest_get_hash_size() bytes of userhash
7525
 *                          upon return
7526
 * @param bin_buf_size the size of the @a userhash_bin buffer, must be
7527
 *                     at least #MHD_digest_get_hash_size() bytes long
7528
 * @return #MHD_SC_OK on success,
7529
 *         #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small,
7530
 *         #MHD_SC_HASH_FAILED if hashing failed,
7531
 *         #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is
7532
 *                                                unknown or unsupported.
7533
 * @sa #MHD_digest_auth_calc_userhash_hex()
7534
 * @ingroup authentication
7535
 */
7536
MHD_EXTERN_ enum MHD_StatusCode
7537
MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo algo,
7538
                               const char *MHD_RESTRICT username,
7539
                               const char *MHD_RESTRICT realm,
7540
                               size_t bin_buf_size,
7541
                               void *MHD_RESTRICT userhash_bin)
7542
MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (2)
7543
MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_OUT_SIZE_ (5,4);
7544
7545
7546
/**
7547
 * Calculate "userhash", return it as hexadecimal string.
7548
 *
7549
 * The "userhash" is the hash of the string "username:realm".
7550
 *
7551
 * The "userhash" could be used to avoid sending username in cleartext in Digest
7552
 * Authorization client's header.
7553
 *
7554
 * Userhash is not designed to hide the username in local database or files,
7555
 * as username in cleartext is required for #MHD_digest_auth_check() function
7556
 * to check the response, but it can be used to hide username in HTTP headers.
7557
 *
7558
 * This function could be used when the new username is added to the username
7559
 * database to save the "userhash" alongside with the username (preferably) or
7560
 * when loading list of the usernames to generate the userhash for every loaded
7561
 * username (this will cause delays at the start with the long lists).
7562
 *
7563
 * Once "userhash" is generated it could be used to identify users by clients
7564
 * with "userhash" support.
7565
 * Avoid repetitive usage of this function for the same username/realm
7566
 * combination as it will cause excessive CPU load; save and reuse the result
7567
 * instead.
7568
 *
7569
 * @param algo the algorithm for userhash calculations
7570
 * @param username the username
7571
 * @param realm the realm
7572
 * @param hex_buf_size the size of the @a userhash_hex buffer, must be
7573
 *                     at least #MHD_digest_get_hash_size()*2+1 chars long
7574
 * @param[out] userhash_hex the output buffer for userhash as hex string;
7575
 *                          if this function succeeds, then this buffer has
7576
 *                          #MHD_digest_get_hash_size()*2 chars long
7577
 *                          userhash string plus one zero-termination char
7578
 * @return #MHD_SC_OK on success,
7579
 *         #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small,
7580
 *         #MHD_SC_HASH_FAILED if hashing failed,
7581
 *         #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is
7582
 *                                                unknown or unsupported.
7583
 * @sa #MHD_digest_auth_calc_userhash()
7584
 * @ingroup authentication
7585
 */
7586
MHD_EXTERN_ enum MHD_StatusCode
7587
MHD_digest_auth_calc_userhash_hex (
7588
  enum MHD_DigestAuthAlgo algo,
7589
  const char *MHD_RESTRICT username,
7590
  const char *MHD_RESTRICT realm,
7591
  size_t hex_buf_size,
7592
  char userhash_hex[MHD_FN_PAR_DYN_ARR_SIZE_ (hex_buf_size)])
7593
MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (2)
7594
MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_OUT_SIZE_ (5,4);
7595
7596
7597
/**
7598
 * The type of username used by client in Digest Authorization header
7599
 *
7600
 * Values are sorted so simplified checks could be used.
7601
 * For example:
7602
 * * (value <= MHD_DIGEST_AUTH_UNAME_TYPE_INVALID) is true if no valid username
7603
 *   is provided by the client (not used currently)
7604
 * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH) is true if username is
7605
 *   provided in any form
7606
 * * (value >= MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD) is true if username is
7607
 *   provided in clear text (no userhash matching is needed)
7608
 */
7609
enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthUsernameType
7610
{
7611
  /**
7612
   * No username parameter is in Digest Authorization header.
7613
   * Not used currently. Value #MHD_SC_REQ_AUTH_DATA_BROKEN is returned
7614
   * by #MHD_request_get_info_dynamic_sz() if the request has no username.
7615
   */
7616
  MHD_DIGEST_AUTH_UNAME_TYPE_MISSING = 0
7617
  ,
7618
  /**
7619
   * The 'username' parameter is used to specify the username.
7620
   */
7621
  MHD_DIGEST_AUTH_UNAME_TYPE_STANDARD = (1u << 2)
7622
  ,
7623
  /**
7624
   * The username is specified by 'username*' parameter with
7625
   * the extended notation (see RFC 5987, section-3.2.1).
7626
   * The only difference between standard and extended types is
7627
   * the way how username value is encoded in the header.
7628
   */
7629
  MHD_DIGEST_AUTH_UNAME_TYPE_EXTENDED = (1u << 3)
7630
  ,
7631
  /**
7632
   * The username provided in form of 'userhash' as
7633
   * specified by RFC 7616, section-3.4.4.
7634
   * @sa #MHD_digest_auth_calc_userhash_hex(), #MHD_digest_auth_calc_userhash()
7635
   */
7636
  MHD_DIGEST_AUTH_UNAME_TYPE_USERHASH = (1u << 1)
7637
  ,
7638
  /**
7639
   * The invalid combination of username parameters are used by client.
7640
   * Either:
7641
   * + both 'username' and 'username*' are used
7642
   * + 'username*' is used with 'userhash=true'
7643
   * + 'username*' used with invalid extended notation
7644
   * + 'username' is not hexadecimal string, while 'userhash' set to 'true'
7645
   * Not used currently. Value #MHD_SC_REQ_AUTH_DATA_BROKEN is returned
7646
   * by #MHD_request_get_info_dynamic_sz() if the request has broken username.
7647
   */
7648
  MHD_DIGEST_AUTH_UNAME_TYPE_INVALID = (1u << 0)
7649
};
7650
7651
/**
7652
 * The QOP ('quality of protection') types.
7653
 */
7654
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthQOP
7655
{
7656
  /**
7657
   * Invalid/unknown QOP.
7658
   * Used in struct MHD_AuthDigestInfo to indicate client value that
7659
   * cannot by identified.
7660
   */
7661
  MHD_DIGEST_AUTH_QOP_INVALID = 0
7662
  ,
7663
  /**
7664
   * No QOP parameter.
7665
   * As described in old RFC 2069 original specification.
7666
   * This mode is not allowed by latest RFCs and should be used only to
7667
   * communicate with clients that do not support more modern modes (with QOP
7668
   * parameter).
7669
   * This mode is less secure than other modes and inefficient.
7670
   */
7671
  MHD_DIGEST_AUTH_QOP_NONE = (1u << 0)
7672
  ,
7673
  /**
7674
   * The 'auth' QOP type.
7675
   */
7676
  MHD_DIGEST_AUTH_QOP_AUTH = (1u << 1)
7677
  ,
7678
  /**
7679
   * The 'auth-int' QOP type.
7680
   * Not supported by MHD for authentication.
7681
   */
7682
  MHD_DIGEST_AUTH_QOP_AUTH_INT = (1u << 2)
7683
};
7684
7685
/**
7686
 * The QOP ('quality of protection') types, multiple selection.
7687
 *
7688
 * #MHD_DigestAuthQOP always can be casted to #MHD_DigestAuthMultiQOP, but
7689
 * not vice versa.
7690
 */
7691
enum MHD_FIXED_ENUM_MHD_APP_SET_ MHD_DigestAuthMultiQOP
7692
{
7693
  /**
7694
   * Invalid/unknown QOP.
7695
   */
7696
  MHD_DIGEST_AUTH_MULT_QOP_INVALID = MHD_DIGEST_AUTH_QOP_INVALID
7697
  ,
7698
  /**
7699
   * No QOP parameter.
7700
   * As described in old RFC 2069 original specification.
7701
   * This mode is not allowed by latest RFCs and should be used only to
7702
   * communicate with clients that do not support more modern modes (with QOP
7703
   * parameter).
7704
   * This mode is less secure than other modes and inefficient.
7705
   */
7706
  MHD_DIGEST_AUTH_MULT_QOP_NONE = MHD_DIGEST_AUTH_QOP_NONE
7707
  ,
7708
  /**
7709
   * The 'auth' QOP type.
7710
   */
7711
  MHD_DIGEST_AUTH_MULT_QOP_AUTH = MHD_DIGEST_AUTH_QOP_AUTH
7712
  ,
7713
  /**
7714
   * The 'auth-int' QOP type.
7715
   * Not supported by MHD.
7716
   * Reserved value.
7717
   */
7718
  MHD_DIGEST_AUTH_MULT_QOP_AUTH_INT = MHD_DIGEST_AUTH_QOP_AUTH_INT
7719
  ,
7720
  /**
7721
   * The 'auth' QOP type OR the old RFC2069 (no QOP) type.
7722
   * In other words: any types except 'auth-int'.
7723
   * RFC2069-compatible mode is allowed, thus this value should be used only
7724
   * when it is really necessary.
7725
   */
7726
  MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT =
7727
    MHD_DIGEST_AUTH_QOP_NONE | MHD_DIGEST_AUTH_QOP_AUTH
7728
  ,
7729
  /**
7730
   * Any 'auth' QOP type ('auth' or 'auth-int').
7731
   * Currently supported as 'auth' QOP type only.
7732
   */
7733
  MHD_DIGEST_AUTH_MULT_QOP_AUTH_ANY =
7734
    MHD_DIGEST_AUTH_QOP_AUTH | MHD_DIGEST_AUTH_QOP_AUTH_INT
7735
};
7736
7737
/**
7738
 * The type of 'nc' (nonce count) value provided in the request
7739
 */
7740
enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthNC
7741
{
7742
  /**
7743
   * Readable hexdecimal non-zero number.
7744
   * The decoded value is placed in @a nc member of struct MHD_AuthDigestInfo
7745
   */
7746
  MHD_DIGEST_AUTH_NC_NUMBER = 1
7747
  ,
7748
  /**
7749
   * Readable zero number.
7750
   * Compliant clients should not use such values.
7751
   * Can be treated as invalid request.
7752
   */
7753
  MHD_DIGEST_AUTH_NC_ZERO = 2
7754
  ,
7755
  /**
7756
   * 'nc' value is not provided by the client.
7757
   * Unless old RFC 2069 mode is allowed, this should be treated as invalid
7758
   * request.
7759
   */
7760
  MHD_DIGEST_AUTH_NC_NONE = 3
7761
  ,
7762
  /**
7763
   * 'nc' value is too long to be decoded.
7764
   * Compliant clients should not use such values.
7765
   * Can be treated as invalid request.
7766
   */
7767
  MHD_DIGEST_AUTH_NC_TOO_LONG = 4
7768
  ,
7769
  /**
7770
   * 'nc' value is too large for uint32_t.
7771
   * Compliant clients should not use such values.
7772
   * Can be treated as request with a stale nonce or as invalid request.
7773
   */
7774
  MHD_DIGEST_AUTH_NC_TOO_LARGE = 5
7775
};
7776
7777
7778
/**
7779
 * Information from Digest Authorization client's header.
7780
 *
7781
 * @see #MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO
7782
 */
7783
struct MHD_AuthDigestInfo
7784
{
7785
  /**
7786
   * The algorithm as defined by client.
7787
   * Set automatically to MD5 if not specified by client.
7788
   */
7789
  enum MHD_DigestAuthAlgo algo;
7790
7791
  /**
7792
   * The type of username used by client.
7793
   */
7794
  enum MHD_DigestAuthUsernameType uname_type;
7795
7796
  /**
7797
   * The username string.
7798
   * Used only if username type is standard or extended, always NULL otherwise.
7799
   * If extended notation is used, this string is pct-decoded string
7800
   * with charset and language tag removed (i.e. it is original username
7801
   * extracted from the extended notation).
7802
   * When userhash is used by the client, the string pointer is NULL and
7803
   * @a userhash_hex and @a userhash_bin are set.
7804
   */
7805
  struct MHD_StringNullable username;
7806
7807
  /**
7808
   * The userhash string.
7809
   * Valid only if username type is userhash.
7810
   * This is unqoted string without decoding of the hexadecimal
7811
   * digits (as provided by the client).
7812
   * @sa #MHD_digest_auth_calc_userhash_hex()
7813
   */
7814
  struct MHD_StringNullable userhash_hex;
7815
7816
  /**
7817
   * The userhash decoded to binary form.
7818
   * Used only if username type is userhash, always NULL otherwise.
7819
   * When not NULL, this points to binary sequence @a userhash_bin_size bytes
7820
   * long.
7821
   * The valid size should be #MHD_digest_get_hash_size() bytes.
7822
   * @warning This is a binary data, no zero termination.
7823
   * @warning To avoid buffer overruns, always check the size of the data before
7824
   *          use, because @a userhash_bin can point even to zero-sized
7825
   *          data.
7826
   * @sa #MHD_digest_auth_calc_userhash()
7827
   */
7828
  const uint8_t *userhash_bin;
7829
7830
  /**
7831
   * The size of the data pointed by @a userhash_bin.
7832
   * Always zero when @a userhash_bin is NULL.
7833
   */
7834
  size_t userhash_bin_size;
7835
7836
  /**
7837
   * The 'opaque' parameter value, as specified by client.
7838
   * If not specified by client then string pointer is NULL.
7839
   */
7840
  struct MHD_StringNullable opaque;
7841
7842
  /**
7843
   * The 'realm' parameter value, as specified by client.
7844
   * If not specified by client then string pointer is NULL.
7845
   */
7846
  struct MHD_StringNullable realm;
7847
7848
  /**
7849
   * The 'qop' parameter value.
7850
   */
7851
  enum MHD_DigestAuthQOP qop;
7852
7853
  /**
7854
   * The length of the 'cnonce' parameter value, including possible
7855
   * backslash-escape characters.
7856
   * 'cnonce' is used in hash calculation, which is CPU-intensive procedure.
7857
   * An application may want to reject too large cnonces to limit the CPU load.
7858
   * A few kilobytes is a reasonable limit, typically cnonce is just 32-160
7859
   * characters long.
7860
   */
7861
  size_t cnonce_len;
7862
7863
  /**
7864
   * The type of 'nc' (nonce count) value provided in the request.
7865
   */
7866
  enum MHD_DigestAuthNC nc_type;
7867
7868
  /**
7869
   * The nc (nonce count) parameter value.
7870
   * Can be used by application to limit the number of nonce re-uses. If @a nc
7871
   * is higher than application wants to allow, then "auth required" response
7872
   * with 'stale=true' could be used to force client to retry with the fresh
7873
   * 'nonce'.
7874
   * Set to zero when @a nc_type is not set to #MHD_DIGEST_AUTH_NC_NUMBER.
7875
   */
7876
  uint_fast32_t nc;
7877
};
7878
7879
/**
7880
 * The result of digest authentication of the client.
7881
 *
7882
 * All error values are zero or negative.
7883
 */
7884
enum MHD_FIXED_ENUM_MHD_SET_ MHD_DigestAuthResult
7885
{
7886
  /**
7887
   * Authentication OK.
7888
   */
7889
  MHD_DAUTH_OK = 1
7890
  ,
7891
  /**
7892
   * General error, like "out of memory".
7893
   * Authentication may be valid, but cannot be checked.
7894
   */
7895
  MHD_DAUTH_ERROR = 0
7896
  ,
7897
  /**
7898
   * No "Authorization" header for Digest Authentication.
7899
   */
7900
  MHD_DAUTH_HEADER_MISSING = -1
7901
  ,
7902
  /**
7903
   * Wrong format of the header.
7904
   * Also returned if required parameters in Authorization header are missing
7905
   * or broken (in invalid format).
7906
   */
7907
  MHD_DAUTH_HEADER_BROKEN = -9
7908
  ,
7909
  /**
7910
   * Unsupported algorithm.
7911
   */
7912
  MHD_DAUTH_UNSUPPORTED_ALGO = -10
7913
  ,
7914
  /**
7915
   * Unsupported 'qop'.
7916
   */
7917
  MHD_DAUTH_UNSUPPORTED_QOP = -11
7918
  ,
7919
  /**
7920
   * Incorrect userdigest size.
7921
   */
7922
  MHD_DAUTH_INVALID_USERDIGEST_SIZE = -15
7923
  ,
7924
  /**
7925
   * Wrong 'username'.
7926
   */
7927
  MHD_DAUTH_WRONG_USERNAME = -17
7928
  ,
7929
  /**
7930
   * Wrong 'realm'.
7931
   */
7932
  MHD_DAUTH_WRONG_REALM = -18
7933
  ,
7934
  /**
7935
   * Wrong 'URI' (or URI parameters).
7936
   */
7937
  MHD_DAUTH_WRONG_URI = -19
7938
  ,
7939
  /**
7940
   * Wrong 'qop'.
7941
   */
7942
  MHD_DAUTH_WRONG_QOP = -20
7943
  ,
7944
  /**
7945
   * Wrong 'algorithm'.
7946
   */
7947
  MHD_DAUTH_WRONG_ALGO = -21
7948
  ,
7949
  /**
7950
   * Too large (>64 KiB) Authorization parameter value.
7951
   */
7952
  MHD_DAUTH_TOO_LARGE = -22
7953
  ,
7954
  /* The different form of naming is intentionally used for the results below,
7955
   * as they are more important */
7956
7957
  /**
7958
   * The 'nonce' is too old. Suggest the client to retry with the same
7959
   * username and password to get the fresh 'nonce'.
7960
   * The validity of the 'nonce' may be not checked.
7961
   */
7962
  MHD_DAUTH_NONCE_STALE = -25
7963
  ,
7964
  /**
7965
   * The 'nonce' is wrong. May indicate an attack attempt.
7966
   */
7967
  MHD_DAUTH_NONCE_WRONG = -33
7968
  ,
7969
  /**
7970
   * The 'response' is wrong. May indicate a wrong password used or
7971
   * an attack attempt.
7972
   */
7973
  MHD_DAUTH_RESPONSE_WRONG = -34
7974
};
7975
7976
7977
/**
7978
 * Authenticates the authorization header sent by the client.
7979
 *
7980
 * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in
7981
 * @a mqop and the client uses this mode, then server generated nonces are
7982
 * used as one-time nonces because nonce-count is not supported in this old RFC.
7983
 * Communication in this mode is very inefficient, especially if the client
7984
 * requests several resources one-by-one as for every request a new nonce must
7985
 * be generated and client repeats all requests twice (first time to get a new
7986
 * nonce and second time to perform an authorised request).
7987
 *
7988
 * @param request the request
7989
 * @param realm the realm for authorization of the client
7990
 * @param username the username to be authenticated, must be in clear text
7991
 *                 even if userhash is used by the client
7992
 * @param password the password matching the @a username (and the @a realm)
7993
 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc
7994
 *               exceeds the specified value then MHD_DAUTH_NONCE_STALE is
7995
 *               returned;
7996
 *               if zero is specified then daemon default value is used.
7997
 * @param mqop the QOP to use
7998
 * @param malgo digest algorithms allowed to use, fail if algorithm used
7999
 *               by the client is not allowed by this parameter
8000
 * @return #MHD_DAUTH_OK if authenticated,
8001
 *         the error code otherwise
8002
 * @ingroup authentication
8003
 */
8004
MHD_EXTERN_ enum MHD_DigestAuthResult
8005
MHD_digest_auth_check (struct MHD_Request *MHD_RESTRICT request,
8006
                       const char *MHD_RESTRICT realm,
8007
                       const char *MHD_RESTRICT username,
8008
                       const char *MHD_RESTRICT password,
8009
                       uint_fast32_t max_nc,
8010
                       enum MHD_DigestAuthMultiQOP mqop,
8011
                       enum MHD_DigestAuthMultiAlgo malgo)
8012
MHD_FN_PAR_NONNULL_ALL_
8013
MHD_FN_PAR_CSTR_ (2) MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_CSTR_ (4);
8014
8015
8016
/**
8017
 * Calculate userdigest, return it as a binary data.
8018
 *
8019
 * The "userdigest" is the hash of the "username:realm:password" string.
8020
 *
8021
 * The "userdigest" can be used to avoid storing the password in clear text
8022
 * in database/files
8023
 *
8024
 * This function is designed to improve security of stored credentials,
8025
 * the "userdigest" does not improve security of the authentication process.
8026
 *
8027
 * The results can be used to store username & userdigest pairs instead of
8028
 * username & password pairs. To further improve security, application may
8029
 * store username & userhash & userdigest triplets.
8030
 *
8031
 * @param algo the digest algorithm
8032
 * @param username the username
8033
 * @param realm the realm
8034
 * @param password the password
8035
 * @param bin_buf_size the size of the @a userdigest_bin buffer, must be
8036
 *                     at least #MHD_digest_get_hash_size() bytes long
8037
 * @param[out] userdigest_bin the output buffer for userdigest;
8038
 *                            if this function succeeds, then this buffer has
8039
 *                            #MHD_digest_get_hash_size() bytes of
8040
 *                            userdigest upon return
8041
 * @return #MHD_SC_OK on success,
8042
 *         #MHD_SC_OUT_BUFF_TOO_SMALL if @a bin_buf_size is too small,
8043
 *         #MHD_SC_HASH_FAILED if hashing failed,
8044
 *         #MHD_SC_AUTH_DIGEST_ALGO_NOT_SUPPORTED if requested @a algo is
8045
 *                                                unknown or unsupported.
8046
 * @sa #MHD_digest_auth_check_digest()
8047
 * @ingroup authentication
8048
 */
8049
MHD_EXTERN_ enum MHD_StatusCode
8050
MHD_digest_auth_calc_userdigest (enum MHD_DigestAuthAlgo algo,
8051
                                 const char *MHD_RESTRICT username,
8052
                                 const char *MHD_RESTRICT realm,
8053
                                 const char *MHD_RESTRICT password,
8054
                                 size_t bin_buf_size,
8055
                                 void *MHD_RESTRICT userdigest_bin)
8056
MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
8057
MHD_FN_PAR_CSTR_ (2)
8058
MHD_FN_PAR_CSTR_ (3)
8059
MHD_FN_PAR_CSTR_ (4)
8060
MHD_FN_PAR_OUT_SIZE_ (6,5);
8061
8062
8063
/**
8064
 * Authenticates the authorization header sent by the client by using
8065
 * hash of "username:realm:password".
8066
 *
8067
 * If RFC2069 mode is allowed by setting bit #MHD_DIGEST_AUTH_QOP_NONE in
8068
 * @a mqop and the client uses this mode, then server generated nonces are
8069
 * used as one-time nonces because nonce-count is not supported in this old RFC.
8070
 * Communication in this mode is very inefficient, especially if the client
8071
 * requests several resources one-by-one as for every request a new nonce must
8072
 * be generated and client repeats all requests twice (first time to get a new
8073
 * nonce and second time to perform an authorised request).
8074
 *
8075
 * @param request the request
8076
 * @param realm the realm for authorization of the client
8077
 * @param username the username to be authenticated, must be in clear text
8078
 *                 even if userhash is used by the client
8079
 * @param userdigest_size the size of the @a userdigest in bytes, must match the
8080
 *                        hashing algorithm (see #MHD_MD5_DIGEST_SIZE,
8081
 *                        #MHD_SHA256_DIGEST_SIZE, #MHD_SHA512_256_DIGEST_SIZE,
8082
 *                        #MHD_digest_get_hash_size())
8083
 * @param userdigest the precalculated binary hash of the string
8084
 *                   "username:realm:password",
8085
 *                   see #MHD_digest_auth_calc_userdigest()
8086
 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc
8087
 *               exceeds the specified value then MHD_DAUTH_NONCE_STALE is
8088
 *               returned;
8089
 *               if zero is specified then daemon default value is used.
8090
 * @param mqop the QOP to use
8091
 * @param malgo digest algorithms allowed to use, fail if algorithm used
8092
 *              by the client is not allowed by this parameter;
8093
 *              more than one base algorithms (MD5, SHA-256, SHA-512/256)
8094
 *              cannot be used at the same time for this function
8095
 *              as @a userdigest must match specified algorithm
8096
 * @return #MHD_DAUTH_OK if authenticated,
8097
 *         the error code otherwise
8098
 * @sa #MHD_digest_auth_calc_userdigest()
8099
 * @ingroup authentication
8100
 */
8101
MHD_EXTERN_ enum MHD_DigestAuthResult
8102
MHD_digest_auth_check_digest (struct MHD_Request *MHD_RESTRICT request,
8103
                              const char *MHD_RESTRICT realm,
8104
                              const char *MHD_RESTRICT username,
8105
                              size_t userdigest_size,
8106
                              const void *MHD_RESTRICT userdigest,
8107
                              uint_fast32_t max_nc,
8108
                              enum MHD_DigestAuthMultiQOP mqop,
8109
                              enum MHD_DigestAuthMultiAlgo malgo)
8110
MHD_FN_PAR_NONNULL_ALL_
8111
MHD_FN_PAR_CSTR_ (2)
8112
MHD_FN_PAR_CSTR_ (3)
8113
MHD_FN_PAR_IN_SIZE_ (5, 4);
8114
8115
8116
/**
8117
 * Add Digest Authentication "challenge" to the response.
8118
 *
8119
 * The response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8120
 *
8121
 * If @a mqop allows both RFC 2069 (#MHD_DIGEST_AUTH_QOP_NONE) and other QOP
8122
 * values, then the "challenge" is formed like if MHD_DIGEST_AUTH_QOP_NONE bit
8123
 * was not set, because such "challenge" should be backward-compatible with
8124
 * RFC 2069.
8125
 *
8126
 * If @a mqop allows only MHD_DIGEST_AUTH_MULT_QOP_NONE, then the response is
8127
 * formed in strict accordance with RFC 2069 (no 'qop', no 'userhash', no
8128
 * 'charset'). For better compatibility with clients, it is recommended (but
8129
 * not required) to set @a domain to NULL in this mode.
8130
 *
8131
 * New nonces are generated each time when the resulting response is used.
8132
 *
8133
 * See RFC 7616, section 3.3 for details.
8134
 *
8135
 * @param response the response to update; should contain the "access denied"
8136
 *                 body;
8137
 *                 note: this function sets the "WWW Authenticate" header and
8138
 *                 the caller should not set this header;
8139
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8140
 *                 code;
8141
 *                 the NULL is tolerated (the result is
8142
 *                 #MHD_SC_RESP_POINTER_NULL)
8143
 * @param realm the realm presented to the client
8144
 * @param opaque the string for opaque value, can be NULL, but NULL is
8145
 *               not recommended for better compatibility with clients;
8146
 *               the recommended format is hex or Base64 encoded string
8147
 * @param domain the optional space-separated list of URIs for which the
8148
 *               same authorisation could be used, URIs can be in form
8149
 *               "path-absolute" (the path for the same host with initial slash)
8150
 *               or in form "absolute-URI" (the full path with protocol), in
8151
 *               any case client may assume that URI is in the same "protection
8152
 *               space" if it starts with any of values specified here;
8153
 *               could be NULL (clients typically assume that the same
8154
 *               credentials could be used for any URI on the same host);
8155
 *               this list provides information for the client only and does
8156
 *               not actually restrict anything on the server side
8157
 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used
8158
 *                       in the client's request is indicated by adding
8159
 *                       'stale=true' to the authentication header, this
8160
 *                       instructs the client to retry immediately with the new
8161
 *                       nonce and the same credentials, without asking user
8162
 *                       for the new password
8163
 * @param mqop the QOP to use
8164
 * @param malgo digest algorithm to use; if several algorithms are allowed
8165
 *              then one challenge for each allowed algorithm is added
8166
 * @param userhash_support if set to #MHD_YES then support of userhash is
8167
 *                         indicated, allowing client to provide
8168
 *                         hash("username:realm") instead of the username in
8169
 *                         clear text;
8170
 *                         note that clients are allowed to provide the username
8171
 *                         in cleartext even if this parameter set to non-zero;
8172
 *                         when userhash is used, application must be ready to
8173
 *                         identify users by provided userhash value instead of
8174
 *                         username; see #MHD_digest_auth_calc_userhash() and
8175
 *                         #MHD_digest_auth_calc_userhash_hex()
8176
 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
8177
 *                    added, indicating for the client that UTF-8 encoding for
8178
 *                    the username is preferred
8179
 * @return #MHD_SC_OK if succeed,
8180
 *         #MHD_SC_TOO_LATE if the response has been already "frozen" (used to
8181
 *         create an action),
8182
 *         #MHD_SC_RESP_HEADERS_CONFLICT if Digest Authentication "challenge"
8183
 *         has been added already,
8184
 *         #MHD_SC_RESP_POINTER_NULL if @a response is NULL,
8185
 *         #MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE is response status code is wrong,
8186
 *         #MHD_SC_RESP_HEADER_VALUE_INVALID if @a realm, @a opaque or @a domain
8187
 *         have wrong characters or zero length (for @a realm),
8188
 *         #MHD_SC_RESPONSE_HEADER_MEM_ALLOC_FAILED if memory allocation failed,
8189
 *         or other error code if failed
8190
 * @ingroup authentication
8191
 */
8192
MHD_EXTERN_ enum MHD_StatusCode
8193
MHD_response_add_auth_digest_challenge (
8194
  struct MHD_Response *MHD_RESTRICT response,
8195
  const char *MHD_RESTRICT realm,
8196
  const char *MHD_RESTRICT opaque,
8197
  const char *MHD_RESTRICT domain,
8198
  enum MHD_Bool indicate_stale,
8199
  enum MHD_DigestAuthMultiQOP mqop,
8200
  enum MHD_DigestAuthMultiAlgo malgo,
8201
  enum MHD_Bool userhash_support,
8202
  enum MHD_Bool prefer_utf8)
8203
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
8204
MHD_FN_PAR_CSTR_ (3) MHD_FN_PAR_CSTR_ (4);
8205
8206
8207
/* Application may define MHD_NO_STATIC_INLINE macro before including
8208
   libmicrohttpd headers to disable static inline functions in the headers. */
8209
#ifndef MHD_NO_STATIC_INLINE
8210
8211
/**
8212
 * Create action to reply with Digest Authentication "challenge".
8213
 *
8214
 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8215
 *
8216
 * See RFC 7616, section 3.3 for details.
8217
 *
8218
 * @param request the request to create the action for
8219
 * @param realm the realm presented to the client
8220
 * @param opaque the string for opaque value, can be NULL, but NULL is
8221
 *               not recommended for better compatibility with clients;
8222
 *               the recommended format is hex or Base64 encoded string
8223
 * @param domain the optional space-separated list of URIs for which the
8224
 *               same authorisation could be used, URIs can be in form
8225
 *               "path-absolute" (the path for the same host with initial slash)
8226
 *               or in form "absolute-URI" (the full path with protocol), in
8227
 *               any case client may assume that URI is in the same "protection
8228
 *               space" if it starts with any of values specified here;
8229
 *               could be NULL (clients typically assume that the same
8230
 *               credentials could be used for any URI on the same host);
8231
 *               this list provides information for the client only and does
8232
 *               not actually restrict anything on the server side
8233
 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used
8234
 *                       in the client's request is indicated by adding
8235
 *                       'stale=true' to the authentication header, this
8236
 *                       instructs the client to retry immediately with the new
8237
 *                       nonce and the same credentials, without asking user
8238
 *                       for the new password
8239
 * @param mqop the QOP to use
8240
 * @param malgo digest algorithm to use; if several algorithms are allowed
8241
 *              then one challenge for each allowed algorithm is added
8242
 * @param userhash_support if set to #MHD_YES then support of userhash is
8243
 *                         indicated, allowing client to provide
8244
 *                         hash("username:realm") instead of the username in
8245
 *                         clear text;
8246
 *                         note that clients are allowed to provide the username
8247
 *                         in cleartext even if this parameter set to non-zero;
8248
 *                         when userhash is used, application must be ready to
8249
 *                         identify users by provided userhash value instead of
8250
 *                         username; see #MHD_digest_auth_calc_userhash() and
8251
 *                         #MHD_digest_auth_calc_userhash_hex()
8252
 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
8253
 *                    added, indicating for the client that UTF-8 encoding for
8254
 *                    the username is preferred
8255
 * @param response the response to update; should contain the "access denied"
8256
 *                 body;
8257
 *                 note: this function sets the "WWW Authenticate" header and
8258
 *                 the caller should not set this header;
8259
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8260
 *                 code;
8261
 *                 the NULL is tolerated (the result is
8262
 *                 #MHD_SC_RESP_POINTER_NULL)
8263
 * @param abort_if_failed if set to #MHD_NO the response will be used even if
8264
 *                        failed to add Basic Authentication "challenge",
8265
 *                        if not set to #MHD_NO the request will be aborted
8266
 *                        if the "challenge" could not be added.
8267
 * @return pointer to the action, the action must be consumed
8268
 *         otherwise response object may leak;
8269
 *         NULL if failed or if any action has been already created for
8270
 *         the @a request;
8271
 *         when failed the response object is consumed and need not
8272
 *         to be "destroyed"
8273
 * @ingroup authentication
8274
 */
8275
MHD_STATIC_INLINE_
8276
MHD_FN_PAR_NONNULL_ (1)
8277
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
8278
const struct MHD_Action *
8279
MHD_action_digest_auth_challenge (struct MHD_Request *MHD_RESTRICT request,
8280
                                  const char *MHD_RESTRICT realm,
8281
                                  const char *MHD_RESTRICT opaque,
8282
                                  const char *MHD_RESTRICT domain,
8283
                                  enum MHD_Bool indicate_stale,
8284
                                  enum MHD_DigestAuthMultiQOP mqop,
8285
                                  enum MHD_DigestAuthMultiAlgo malgo,
8286
                                  enum MHD_Bool userhash_support,
8287
                                  enum MHD_Bool prefer_utf8,
8288
                                  struct MHD_Response *MHD_RESTRICT response,
8289
                                  enum MHD_Bool abort_if_failed)
8290
0
{
8291
0
  if ((MHD_SC_OK !=
8292
0
       MHD_response_add_auth_digest_challenge (response, realm, opaque, domain,
8293
0
                                               indicate_stale, mqop, malgo,
8294
0
                                               userhash_support, prefer_utf8))
8295
0
      && (MHD_NO != abort_if_failed))
8296
0
  {
8297
0
    MHD_response_destroy (response);
8298
0
    return MHD_action_abort_request (request);
8299
0
  }
8300
0
  return MHD_action_from_response (request, response);
8301
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_action_digest_auth_challenge(MHD_Request*, char const*, char const*, char const*, MHD_Bool, MHD_DigestAuthMultiQOP, MHD_DigestAuthMultiAlgo, MHD_Bool, MHD_Bool, MHD_Response*, MHD_Bool)
Unexecuted instantiation: connection_helper.cpp:MHD_action_digest_auth_challenge(MHD_Request*, char const*, char const*, char const*, MHD_Bool, MHD_DigestAuthMultiQOP, MHD_DigestAuthMultiAlgo, MHD_Bool, MHD_Bool, MHD_Response*, MHD_Bool)
Unexecuted instantiation: daemon_funcs.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: request_funcs.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: response_destroy.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: response_funcs.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: stream_funcs.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: stream_process_request.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: stream_process_reply.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: post_parser_funcs.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: response_auth_digest.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: auth_digest.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: tls_gnu_funcs.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: mhd_panic.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: http_status_str.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: daemon_logger.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: extr_events_funcs.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: request_get_value.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: respond_with_error.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: response_from.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: response_add_header.c:MHD_action_digest_auth_challenge
Unexecuted instantiation: request_auth_get.c:MHD_action_digest_auth_challenge
8302
8303
8304
MHD_STATIC_INLINE_END_
8305
8306
/**
8307
 * Create action to reply with Digest Authentication "challenge".
8308
 *
8309
 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8310
 *
8311
 * If the @a response object cannot be extended with the "challenge",
8312
 * the @a response is used to reply without the "challenge".
8313
 *
8314
 * @param request the request to create the action for
8315
 * @param realm the realm presented to the client
8316
 * @param opaque the string for opaque value, can be NULL, but NULL is
8317
 *               not recommended for better compatibility with clients;
8318
 *               the recommended format is hex or Base64 encoded string
8319
 * @param domain the optional space-separated list of URIs for which the
8320
 *               same authorisation could be used, URIs can be in form
8321
 *               "path-absolute" (the path for the same host with initial slash)
8322
 *               or in form "absolute-URI" (the full path with protocol), in
8323
 *               any case client may assume that URI is in the same "protection
8324
 *               space" if it starts with any of values specified here;
8325
 *               could be NULL (clients typically assume that the same
8326
 *               credentials could be used for any URI on the same host);
8327
 *               this list provides information for the client only and does
8328
 *               not actually restrict anything on the server side
8329
 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used
8330
 *                       in the client's request is indicated by adding
8331
 *                       'stale=true' to the authentication header, this
8332
 *                       instructs the client to retry immediately with the new
8333
 *                       nonce and the same credentials, without asking user
8334
 *                       for the new password
8335
 * @param mqop the QOP to use
8336
 * @param algo digest algorithm to use; if several algorithms are allowed
8337
 *             then one challenge for each allowed algorithm is added
8338
 * @param userhash_support if set to #MHD_YES then support of userhash is
8339
 *                         indicated, allowing client to provide
8340
 *                         hash("username:realm") instead of the username in
8341
 *                         clear text;
8342
 *                         note that clients are allowed to provide the username
8343
 *                         in cleartext even if this parameter set to non-zero;
8344
 *                         when userhash is used, application must be ready to
8345
 *                         identify users by provided userhash value instead of
8346
 *                         username; see #MHD_digest_auth_calc_userhash() and
8347
 *                         #MHD_digest_auth_calc_userhash_hex()
8348
 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
8349
 *                    added, indicating for the client that UTF-8 encoding for
8350
 *                    the username is preferred
8351
 * @param response the response to update; should contain the "access denied"
8352
 *                 body;
8353
 *                 note: this function sets the "WWW Authenticate" header and
8354
 *                 the caller should not set this header;
8355
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8356
 *                 code;
8357
 *                 the NULL is tolerated (the result is
8358
 *                 #MHD_SC_RESP_POINTER_NULL)
8359
 * @return pointer to the action, the action must be consumed
8360
 *         otherwise response object may leak;
8361
 *         NULL if failed or if any action has been already created for
8362
 *         the @a request;
8363
 *         when failed the response object is consumed and need not
8364
 *         to be "destroyed"
8365
 * @ingroup authentication
8366
 */
8367
#define MHD_action_digest_auth_challenge_p(rq,rlm,opq,dmn,stl,mqop,malgo, \
8368
                                           uh,utf,resp) \
8369
        MHD_action_digest_auth_challenge ((rq),(rlm),(opq),(dmn),(stl),(mqop), \
8370
                                          (malgo),(uh),(utf),(resp),MHD_NO)
8371
8372
8373
/**
8374
 * Create action to reply with Digest Authentication "challenge".
8375
 *
8376
 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8377
 *
8378
 * If the @a response object cannot be extended with the "challenge",
8379
 * the @a response is aborted.
8380
 *
8381
 * @param request the request to create the action for
8382
 * @param realm the realm presented to the client
8383
 * @param opaque the string for opaque value, can be NULL, but NULL is
8384
 *               not recommended for better compatibility with clients;
8385
 *               the recommended format is hex or Base64 encoded string
8386
 * @param domain the optional space-separated list of URIs for which the
8387
 *               same authorisation could be used, URIs can be in form
8388
 *               "path-absolute" (the path for the same host with initial slash)
8389
 *               or in form "absolute-URI" (the full path with protocol), in
8390
 *               any case client may assume that URI is in the same "protection
8391
 *               space" if it starts with any of values specified here;
8392
 *               could be NULL (clients typically assume that the same
8393
 *               credentials could be used for any URI on the same host);
8394
 *               this list provides information for the client only and does
8395
 *               not actually restrict anything on the server side
8396
 * @param indicate_stale if set to #MHD_YES then indication of stale nonce used
8397
 *                       in the client's request is indicated by adding
8398
 *                       'stale=true' to the authentication header, this
8399
 *                       instructs the client to retry immediately with the new
8400
 *                       nonce and the same credentials, without asking user
8401
 *                       for the new password
8402
 * @param mqop the QOP to use
8403
 * @param algo digest algorithm to use; if several algorithms are allowed
8404
 *             then one challenge for each allowed algorithm is added
8405
 * @param userhash_support if set to #MHD_YES then support of userhash is
8406
 *                         indicated, allowing client to provide
8407
 *                         hash("username:realm") instead of the username in
8408
 *                         clear text;
8409
 *                         note that clients are allowed to provide the username
8410
 *                         in cleartext even if this parameter set to non-zero;
8411
 *                         when userhash is used, application must be ready to
8412
 *                         identify users by provided userhash value instead of
8413
 *                         username; see #MHD_digest_auth_calc_userhash() and
8414
 *                         #MHD_digest_auth_calc_userhash_hex()
8415
 * @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
8416
 *                    added, indicating for the client that UTF-8 encoding for
8417
 *                    the username is preferred
8418
 * @param response the response to update; should contain the "access denied"
8419
 *                 body;
8420
 *                 note: this function sets the "WWW Authenticate" header and
8421
 *                 the caller should not set this header;
8422
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8423
 *                 code;
8424
 *                 the NULL is tolerated (the result is
8425
 *                 #MHD_SC_RESP_POINTER_NULL)
8426
 * @return pointer to the action, the action must be consumed
8427
 *         otherwise response object may leak;
8428
 *         NULL if failed or if any action has been already created for
8429
 *         the @a request;
8430
 *         when failed the response object is consumed and need not
8431
 *         to be "destroyed"
8432
 * @ingroup authentication
8433
 */
8434
#define MHD_action_digest_auth_challenge_a(rq,rlm,opq,dmn,stl,mqop,malgo, \
8435
                                           uh,utf,resp) \
8436
        MHD_action_digest_auth_challenge ((rq),(rlm),(opq),(dmn),(stl),(mqop), \
8437
                                          (malgo),(uh),(utf),(resp),MHD_YES)
8438
8439
#endif /* ! MHD_NO_STATIC_INLINE */
8440
8441
8442
/**
8443
 * Add Basic Authentication "challenge" to the response.
8444
 *
8445
 * The response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8446
 *
8447
 * If access to any resource should be limited to specific users, authenticated
8448
 * by Basic Authentication mechanism, and the request for this resource does not
8449
 * have Basic Authentication information (see #MHD_AuthBasicCreds), then response
8450
 * with Basic Authentication "challenge" should be sent. This works as
8451
 * an indication that Basic Authentication should be used for the access.
8452
 *
8453
 * See RFC 7617, section-2 for details.
8454
 *
8455
 * @param response the reply to send; should contain the "access denied"
8456
 *                 body;
8457
 *                 note: this function sets the "WWW Authenticate" header and
8458
 *                 the caller should not set this header;
8459
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8460
 *                 code;
8461
 *                 the NULL is tolerated (the result is
8462
 *                 #MHD_SC_RESP_POINTER_NULL)
8463
 * @param realm the realm presented to the client
8464
 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will
8465
 *                    be added, indicating for client that UTF-8 encoding
8466
 *                    is preferred
8467
 * @return #MHD_SC_OK if succeed,
8468
 *         #MHD_SC_TOO_LATE if the response has been already "frozen" (used to
8469
 *         create an action),
8470
 *         #MHD_SC_RESP_HEADERS_CONFLICT if Basic Authentication "challenge"
8471
 *         has been added already,
8472
 *         #MHD_SC_RESP_POINTER_NULL if @a response is NULL,
8473
 *         #MHD_SC_RESP_HTTP_CODE_NOT_SUITABLE is response status code is wrong,
8474
 *         #MHD_SC_RESP_HEADER_VALUE_INVALID if realm is zero-length or has CR
8475
 *         or LF characters,
8476
 *         #MHD_SC_RESPONSE_HEADER_MEM_ALLOC_FAILED if memory allocation failed,
8477
 *         or other error code if failed
8478
 * @ingroup authentication
8479
 */
8480
MHD_EXTERN_ enum MHD_StatusCode
8481
MHD_response_add_auth_basic_challenge (
8482
  struct MHD_Response *MHD_RESTRICT response,
8483
  const char *MHD_RESTRICT realm,
8484
  enum MHD_Bool prefer_utf8)
8485
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2);
8486
8487
/* Application may define MHD_NO_STATIC_INLINE macro before including
8488
   libmicrohttpd headers to disable static inline functions in the headers. */
8489
#ifndef MHD_NO_STATIC_INLINE
8490
8491
/**
8492
 * Create action to reply with Basic Authentication "challenge".
8493
 *
8494
 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8495
 *
8496
 * If access to any resource should be limited to specific users, authenticated
8497
 * by Basic Authentication mechanism, and the request for this resource does not
8498
 * have Basic Authentication information (see #MHD_AuthBasicCreds), then response
8499
 * with Basic Authentication "challenge" should be sent. This works as
8500
 * an indication that Basic Authentication should be used for the access.
8501
 *
8502
 * See RFC 7617, section-2 for details.
8503
 *
8504
 * @param request the request to create the action for
8505
 * @param realm the realm presented to the client
8506
 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will
8507
 *                    be added, indicating for client that UTF-8 encoding
8508
 *                    is preferred
8509
 * @param response the reply to send; should contain the "access denied"
8510
 *                 body;
8511
 *                 note: this function adds the "WWW Authenticate" header in
8512
 *                 the response and the caller should not set this header;
8513
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8514
 *                 code;
8515
 *                 the NULL is tolerated (the result is
8516
 *                 #MHD_action_abort_request())
8517
 * @param abort_if_failed if set to #MHD_NO the response will be used even if
8518
 *                        failed to add Basic Authentication "challenge",
8519
 *                        if not set to #MHD_NO the request will be aborted
8520
 *                        if the "challenge" could not be added.
8521
 * @return pointer to the action, the action must be consumed
8522
 *         otherwise response object may leak;
8523
 *         NULL if failed or if any action has been already created for
8524
 *         the @a request;
8525
 *         when failed the response object is consumed and need not
8526
 *         to be "destroyed"
8527
 * @ingroup authentication
8528
 */
8529
MHD_STATIC_INLINE_
8530
MHD_FN_PAR_NONNULL_ (1)
8531
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_CSTR_ (2)
8532
const struct MHD_Action *
8533
MHD_action_basic_auth_challenge (struct MHD_Request *MHD_RESTRICT request,
8534
                                 const char *MHD_RESTRICT realm,
8535
                                 enum MHD_Bool prefer_utf8,
8536
                                 struct MHD_Response *MHD_RESTRICT response,
8537
                                 enum MHD_Bool abort_if_failed)
8538
0
{
8539
0
  if ((MHD_SC_OK !=
8540
0
       MHD_response_add_auth_basic_challenge (response, realm, prefer_utf8))
8541
0
      && (MHD_NO != abort_if_failed))
8542
0
  {
8543
0
    MHD_response_destroy (response);
8544
0
    return MHD_action_abort_request (request);
8545
0
  }
8546
0
  return MHD_action_from_response (request, response);
8547
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_action_basic_auth_challenge(MHD_Request*, char const*, MHD_Bool, MHD_Response*, MHD_Bool)
Unexecuted instantiation: connection_helper.cpp:MHD_action_basic_auth_challenge(MHD_Request*, char const*, MHD_Bool, MHD_Response*, MHD_Bool)
Unexecuted instantiation: daemon_funcs.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: request_funcs.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: response_destroy.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: response_funcs.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: stream_funcs.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: stream_process_request.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: stream_process_reply.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: post_parser_funcs.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: response_auth_digest.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: auth_digest.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: tls_gnu_funcs.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: mhd_panic.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: http_status_str.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: daemon_logger.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: extr_events_funcs.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: request_get_value.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: respond_with_error.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: response_from.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: response_add_header.c:MHD_action_basic_auth_challenge
Unexecuted instantiation: request_auth_get.c:MHD_action_basic_auth_challenge
8548
8549
8550
MHD_STATIC_INLINE_END_
8551
8552
8553
/**
8554
 * Create action to reply with Basic Authentication "challenge".
8555
 *
8556
 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8557
 *
8558
 * If the @a response object cannot be extended with the "challenge",
8559
 * the @a response will be used to reply without the "challenge".
8560
 *
8561
 * @param request the request to create the action for
8562
 * @param realm the realm presented to the client
8563
 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will
8564
 *                    be added, indicating for client that UTF-8 encoding
8565
 *                    is preferred
8566
 * @param response the reply to send; should contain the "access denied"
8567
 *                 body;
8568
 *                 note: this function adds the "WWW Authenticate" header in
8569
 *                 the response and the caller should not set this header;
8570
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8571
 *                 code;
8572
 *                 the NULL is tolerated (the result is
8573
 *                 #MHD_action_abort_request())
8574
 * @return pointer to the action, the action must be consumed
8575
 *         otherwise response object may leak;
8576
 *         NULL if failed or if any action has been already created for
8577
 *         the @a request;
8578
 *         when failed the response object is consumed and need not
8579
 *         to be "destroyed"
8580
 * @ingroup authentication
8581
 */
8582
#define MHD_action_basic_auth_challenge_p(request,realm,prefer_utf8,response) \
8583
        MHD_action_basic_auth_challenge ((request), (realm), (prefer_utf8), \
8584
                                         (response), MHD_NO)
8585
8586
/**
8587
 * Create action to reply with Basic Authentication "challenge".
8588
 *
8589
 * The @a response must have #MHD_HTTP_STATUS_UNAUTHORIZED status code.
8590
 *
8591
 * If the @a response object cannot be extended with the "challenge",
8592
 * the request will be aborted.
8593
 *
8594
 * @param request the request to create the action for
8595
 * @param realm the realm presented to the client
8596
 * @param prefer_utf8 if not set to #MHD_NO, parameter'charset="UTF-8"' will
8597
 *                    be added, indicating for client that UTF-8 encoding
8598
 *                    is preferred
8599
 * @param response the reply to send; should contain the "access denied"
8600
 *                 body;
8601
 *                 note: this function adds the "WWW Authenticate" header in
8602
 *                 the response and the caller should not set this header;
8603
 *                 the response must have #MHD_HTTP_STATUS_UNAUTHORIZED status
8604
 *                 code;
8605
 *                 the NULL is tolerated (the result is
8606
 *                 #MHD_action_abort_request())
8607
 * @return pointer to the action, the action must be consumed
8608
 *         otherwise response object may leak;
8609
 *         NULL if failed or if any action has been already created for
8610
 *         the @a request;
8611
 *         when failed the response object is consumed and need not
8612
 *         to be "destroyed"
8613
 * @ingroup authentication
8614
 */
8615
#define MHD_action_basic_auth_challenge_a(request,realm,prefer_utf8,response) \
8616
        MHD_action_basic_auth_challenge ((request), (realm), (prefer_utf8), \
8617
                                         (response), MHD_YES)
8618
8619
#endif /* ! MHD_NO_STATIC_INLINE */
8620
8621
8622
/**
8623
 * Information decoded from Basic Authentication client's header.
8624
 *
8625
 * @see #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS
8626
 */
8627
struct MHD_AuthBasicCreds
8628
{
8629
  /**
8630
   * The username
8631
   */
8632
  struct MHD_String username;
8633
8634
  /**
8635
   * The password, string pointer may be NULL if password is not encoded
8636
   * by the client.
8637
   */
8638
  struct MHD_StringNullable password;
8639
};
8640
8641
/* ********************** (f) Introspection ********************** */
8642
8643
8644
/**
8645
 * Types of information about MHD, used by #MHD_lib_get_info_fixed_sz().
8646
 * This information is not changed at run-time.
8647
 */
8648
enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoFixed
8649
{
8650
  /* * Basic MHD information * */
8651
8652
  /**
8653
   * Get the MHD version as a number.
8654
   * The result is placed in @a v_version_num_uint32 member.
8655
   */
8656
  MHD_LIB_INFO_FIXED_VERSION_NUM = 0
8657
  ,
8658
  /**
8659
   * Get the MHD version as a string.
8660
   * The result is placed in @a v_version_string member.
8661
   */
8662
  MHD_LIB_INFO_FIXED_VERSION_STRING = 1
8663
  ,
8664
8665
  /* * Basic MHD features, buid-time configurable * */
8666
  /* These features should be always available unless the library was
8667
   * not compiled specifically for some embedded project.
8668
   * Exceptions are marked explicitly in the description. */
8669
8670
  /**
8671
   * Get whether messages are supported. If supported then messages can be
8672
   * printed to stderr or to an external logger.
8673
   * The result is placed in @a v_support_log_messages_bool member.
8674
   */
8675
  MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES = 11
8676
  ,
8677
  /**
8678
   * Get whether detailed automatic HTTP reply messages are supported.
8679
   * If supported then automatic responses have bodies with text explaining
8680
   * the error details.
8681
   * Automatic responses are sent by MHD automatically when client is violating
8682
   * HTTP specification, for example, the request header has whitespace in
8683
   * header name or request's "Content-Length" header has non-number value.
8684
   * The result is placed in @a v_support_auto_replies_bodies_bool member.
8685
   */
8686
  MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES = 12
8687
  ,
8688
  /**
8689
   * Get whether MHD was built with debug asserts disabled.
8690
   * These asserts enabled only on special debug builds.
8691
   * For debug builds the error log is always enabled.
8692
   * The result is placed in @a v_is_non_debug_bool member.
8693
   */
8694
  MHD_LIB_INFO_FIXED_IS_NON_DEBUG = 13
8695
  ,
8696
  /**
8697
   * Get whether MHD supports threads.
8698
   * The result is placed in @a v_support_threads_bool member.
8699
   */
8700
  MHD_LIB_INFO_FIXED_SUPPORT_THREADS = 14
8701
  ,
8702
  /**
8703
   * Get whether automatic parsing of HTTP Cookie header is supported.
8704
   * If disabled, no #MHD_VK_COOKIE will be generated by MHD.
8705
   * The result is placed in @a v_support_cookie_parser_bool member.
8706
   */
8707
  MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER = 15
8708
  ,
8709
  /**
8710
   * Get whether postprocessor is supported. If supported then
8711
   * #MHD_action_post_processor() can be used.
8712
   * The result is placed in @a v_support_post_parser_bool member.
8713
   */
8714
  MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER = 16
8715
  ,
8716
  /**
8717
   * Get whether HTTP "Upgrade" is supported.
8718
   * If supported then #MHD_action_upgrade() can be used.
8719
   * The result is placed in @a v_support_upgrade_bool member.
8720
   */
8721
  MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE = 17
8722
  ,
8723
  /**
8724
   * Get whether HTTP Basic authorization is supported. If supported
8725
   * then functions #MHD_action_basic_auth_required_response ()
8726
   * and #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS can be used.
8727
   * The result is placed in @a v_support_auth_basic_bool member.
8728
   */
8729
  MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC = 20
8730
  ,
8731
  /**
8732
   * Get whether HTTP Digest authorization is supported. If
8733
   * supported then options #MHD_D_O_RANDOM_ENTROPY,
8734
   * #MHD_D_O_DAUTH_MAP_SIZE and functions
8735
   * #MHD_action_digest_auth_required_response () and
8736
   * #MHD_digest_auth_check() can be used.
8737
   * The result is placed in @a v_support_auth_digest_bool member.
8738
   */
8739
  MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST = 21
8740
  ,
8741
  /**
8742
   * Get whether the early version the Digest Authorization (RFC 2069) is
8743
   * supported (digest authorisation without QOP parameter).
8744
   * Currently it is always supported if Digest Auth module is built.
8745
   * The result is placed in @a v_support_digest_auth_rfc2069_bool member.
8746
   */
8747
  MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069 = 22
8748
  ,
8749
  /**
8750
   * Get whether the MD5-based hashing algorithms are supported for Digest
8751
   * Authorization and the type of the implementation if supported.
8752
   * Currently it is always supported if Digest Auth module is built
8753
   * unless manually disabled in a custom build.
8754
   * The result is placed in @a v_type_digest_auth_md5_algo_type member.
8755
   */
8756
  MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 = 23
8757
  ,
8758
  /**
8759
   * Get whether the SHA-256-based hashing algorithms are supported for Digest
8760
   * Authorization and the type of the implementation if supported.
8761
   * Currently it is always supported if Digest Auth module is built
8762
   * unless manually disabled in a custom build.
8763
   * The result is placed in @a v_type_digest_auth_sha256_algo_type member.
8764
   */
8765
  MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 = 24
8766
  ,
8767
  /**
8768
   * Get whether the SHA-512/256-based hashing algorithms are supported
8769
   * Authorization and the type of the implementation if supported.
8770
   * Currently it is always supported if Digest Auth module is built
8771
   * unless manually disabled in a custom build.
8772
   * The result is placed in @a v_type_digest_auth_sha512_256_algo_type member.
8773
   */
8774
  MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 = 25
8775
  ,
8776
  /**
8777
   * Get whether QOP with value 'auth-int' (authentication with integrity
8778
   * protection) is supported for Digest Authorization.
8779
   * Currently it is always not supported.
8780
   * The result is placed in @a v_support_digest_auth_auth_int_bool member.
8781
   */
8782
  MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT = 28
8783
  ,
8784
  /**
8785
   * Get whether 'session' algorithms (like 'MD5-sess') are supported for Digest
8786
   * Authorization.
8787
   * Currently it is always not supported.
8788
   * The result is placed in @a v_support_digest_auth_algo_session_bool member.
8789
   */
8790
  MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION = 29
8791
  ,
8792
  /**
8793
   * Get whether 'userhash' is supported for Digest Authorization.
8794
   * Currently it is always supported if Digest Auth module is built.
8795
   * The result is placed in @a v_support_digest_auth_userhash_bool member.
8796
   */
8797
  MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH = 30
8798
  ,
8799
8800
  /* * Platform-dependent features, some are configurable at build-time * */
8801
  /* These features depends on the platform, third-party libraries and
8802
   * the toolchain.
8803
   * Some of the features can be disabled or selected at build-time. */
8804
  /**
8805
   * Get sockets polling functions/techniques supported by this MHD build.
8806
   * Some functions can be disabled (like epoll) in kernel, this is not
8807
   * checked.
8808
   * The result is placed in @a v_types_sockets_polling member.
8809
   */
8810
  MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING = 60
8811
  ,
8812
  /**
8813
   * Get whether aggregate FD external polling is supported.
8814
   * The result is placed in @a v_support_aggregate_fd_bool member.
8815
   */
8816
  MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD = 61
8817
  ,
8818
  /**
8819
   * Get whether IPv6 is supported on the platform and IPv6-only listen socket
8820
   * can be used.
8821
   * The result is placed in @a v_ipv6 member.
8822
   * @note The platform may have disabled IPv6 at run-time, it is not checked
8823
   *       by this information type.
8824
   */
8825
  MHD_LIB_INFO_FIXED_TYPE_IPV6 = 62
8826
  ,
8827
  /**
8828
   * Get whether TCP Fast Open is supported by MHD build.
8829
   * If supported then option #MHD_D_O_TCP_FASTOPEN can be used.
8830
   * The result is placed in @a v_support_tcp_fastopen_bool member.
8831
   */
8832
  MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN = 64
8833
  ,
8834
  /**
8835
   * Get whether MHD support automatic detection of bind port number.
8836
   * @sa #MHD_D_O_BIND_PORT
8837
   * The result is placed in @a v_has_autodetect_bind_port_bool member.
8838
   */
8839
  MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT = 65
8840
  ,
8841
  /**
8842
   * Get whether MHD use system's sendfile() function to send
8843
   * file-FD based responses over non-TLS connections.
8844
   * The result is placed in @a v_has_sendfile_bool member.
8845
   */
8846
  MHD_LIB_INFO_FIXED_HAS_SENDFILE = 66
8847
  ,
8848
  /**
8849
   * Get whether MHD supports automatic SIGPIPE suppression within internal
8850
   * events loop (MHD's managed threads).
8851
   * If SIGPIPE suppression is not supported, application must handle
8852
   * SIGPIPE signal by itself whem using MHD with internal events loop.
8853
   * If the platform does not have SIGPIPE the result is #MHD_YES.
8854
   * The result is placed in @a v_has_autosuppress_sigpipe_int_bool member.
8855
   */
8856
  MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT = 80
8857
  ,
8858
  /**
8859
   * Get whether MHD supports automatic SIGPIPE suppression when used with
8860
   * extenal events loop (in application thread).
8861
   * If SIGPIPE suppression is not supported, application must handle
8862
   * SIGPIPE signal by itself whem using MHD with external events loop.
8863
   * If the platform does not have SIGPIPE the result is #MHD_YES.
8864
   * The result is placed in @a v_has_autosuppress_sigpipe_ext_bool member.
8865
   */
8866
  MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT = 81
8867
  ,
8868
  /**
8869
   * Get whether MHD sets names on generated threads.
8870
   * The result is placed in @a v_has_thread_names_bool member.
8871
   */
8872
  MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES = 82
8873
  ,
8874
  /**
8875
   * Get the type of supported inter-thread communication.
8876
   * The result is placed in @a v_type_itc member.
8877
   */
8878
  MHD_LIB_INFO_FIXED_TYPE_ITC = 83
8879
  ,
8880
  /**
8881
   * Get whether reading files beyond 2 GiB boundary is supported.
8882
   * If supported then #MHD_response_from_fd() can be used with sizes and
8883
   * offsets larger than 2 GiB. If not supported value of size+offset could be
8884
   * limited to 2 GiB.
8885
   * The result is placed in @a v_support_large_file_bool member.
8886
   */
8887
  MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE = 84
8888
  ,
8889
8890
  /* * Platform-dependent features, some set on startup and some are
8891
   *   configurable at build-time * */
8892
  /* These features depends on the platform, third-party libraries availability
8893
   * and configuration. The features can be enabled/disabled during startup
8894
   * of the library depending on conditions.
8895
   * Some of the features can be disabled or selected at build-time. */
8896
  /**
8897
   * Get whether HTTPS and which types of TLS backend(s) supported by
8898
   * this build.
8899
   * The result is placed in @a v_tls_backends member.
8900
   */
8901
  MHD_LIB_INFO_FIXED_TLS_BACKENDS = 100
8902
  ,
8903
  /**
8904
  * Get whether password encrypted private key for HTTPS daemon is
8905
  * supported by TLS backends.
8906
  * If supported then option #MHD_D_OPTION_TLS_KEY_CERT can be used with
8907
  * non-NULL @a mem_pass.
8908
  * The result is placed in @a v_tls_key_password_backends member.
8909
  */
8910
  MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS = 102
8911
  ,
8912
8913
  /* * Sentinel * */
8914
  /**
8915
   * The sentinel value.
8916
   * This value enforces specific underlying integer type for the enum.
8917
   * Do not use.
8918
   */
8919
  MHD_LIB_INFO_FIXED_SENTINEL = 65535
8920
};
8921
8922
/**
8923
 * The type of the data for digest algorithm implementations.
8924
 */
8925
enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedDigestAlgoType
8926
{
8927
  /**
8928
   * The algorithm is not implemented or disabled at the build time.
8929
   */
8930
  MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_NOT_AVAILABLE = 0
8931
  ,
8932
  /**
8933
   * The algorithm is implemented by MHD internal code.
8934
   * MHD implementation of hashing can never fail.
8935
   */
8936
  MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_BUILT_IN = 1
8937
  ,
8938
  /**
8939
   * The algorithm is implemented by external code that never fails.
8940
   */
8941
  MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_NEVER_FAIL = 2
8942
  ,
8943
  /**
8944
   * The algorithm is implemented by external code that may hypothetically fail.
8945
   */
8946
  MHD_LIB_INFO_FIXED_DIGEST_ALGO_TYPE_EXTERNAL_MAY_FAIL = 3
8947
};
8948
8949
/**
8950
 * The types of the sockets polling functions/techniques supported
8951
 */
8952
struct MHD_LibInfoFixedPollingFunc
8953
{
8954
  /**
8955
   * select() function for sockets polling
8956
   */
8957
  enum MHD_Bool func_select;
8958
  /**
8959
   * poll() function for sockets polling
8960
   */
8961
  enum MHD_Bool func_poll;
8962
  /**
8963
   * epoll technique for sockets polling
8964
   */
8965
  enum MHD_Bool tech_epoll;
8966
};
8967
8968
/**
8969
 * The types of IPv6 supported
8970
 */
8971
enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedIPv6Type
8972
{
8973
  /**
8974
   * IPv6 is not supported by this MHD build
8975
   */
8976
  MHD_LIB_INFO_FIXED_IPV6_TYPE_NONE = 0
8977
  ,
8978
  /**
8979
   * IPv6 is supported only as "dual stack".
8980
   * IPv4 connections can be received by IPv6 listen socket.
8981
   */
8982
  MHD_LIB_INFO_FIXED_IPV6_TYPE_DUAL_ONLY = 1
8983
  ,
8984
  /**
8985
   * IPv6 can be used as IPv6-only (without getting IPv4 incoming connections).
8986
   * The platform may support "dual stack" too.
8987
   */
8988
  MHD_LIB_INFO_FIXED_IPV6_TYPE_IPV6_PURE = 2
8989
};
8990
8991
/**
8992
 * The types of inter-thread communication
8993
 * @note the enum can be extended in future versions with new values
8994
 */
8995
enum MHD_FIXED_ENUM_MHD_SET_ MHD_LibInfoFixedITCType
8996
{
8997
  /**
8998
   * No ITC used.
8999
   * This value is returned if MHD is built without threads support
9000
   */
9001
  MHD_LIB_INFO_FIXED_ITC_TYPE_NONE = 0
9002
  ,
9003
  /**
9004
   * The pair of sockets are used as inter-thread communication.
9005
   * The is the least efficient method of communication.
9006
   */
9007
  MHD_LIB_INFO_FIXED_ITC_TYPE_SOCKETPAIR = 1
9008
  ,
9009
  /**
9010
   * The pipe is used as inter-thread communication.
9011
   */
9012
  MHD_LIB_INFO_FIXED_ITC_TYPE_PIPE = 2
9013
  ,
9014
  /**
9015
   * The EventFD is used as inter-thread communication.
9016
   * This is the most efficient method of communication.
9017
   */
9018
  MHD_LIB_INFO_FIXED_ITC_TYPE_EVENTFD = 3
9019
};
9020
9021
9022
/**
9023
 * The types of the TLS (or TLS feature) backend supported/available/enabled
9024
 * @note the enum can be extended in future versions with new members
9025
 */
9026
struct MHD_LibInfoTLSType
9027
{
9028
  /**
9029
   * The TLS (or TLS feature) is supported/enabled.
9030
   * Set to #MHD_YES if any other member is #MHD_YES.
9031
   */
9032
  enum MHD_Bool tls_supported;
9033
  /**
9034
   * The GnuTLS backend is supported/available/enabled.
9035
   */
9036
  enum MHD_Bool backend_gnutls;
9037
  /**
9038
   * The OpenSSL backend is supported/available/enabled.
9039
   */
9040
  enum MHD_Bool backend_openssl;
9041
};
9042
9043
/**
9044
 * The data provided by #MHD_lib_get_info_fixed_sz()
9045
 */
9046
union MHD_LibInfoFixedData
9047
{
9048
  /**
9049
   * The data for the #MHD_LIB_INFO_FIXED_VERSION_NUM query
9050
   */
9051
  uint_fast32_t v_version_num_uint32;
9052
  /**
9053
   * The data for the #MHD_LIB_INFO_FIXED_VERSION_STR query
9054
   */
9055
  struct MHD_String v_version_string;
9056
  /**
9057
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LOG_MESSAGES query
9058
   */
9059
  enum MHD_Bool v_support_log_messages_bool;
9060
  /**
9061
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTO_REPLIES_BODIES query
9062
   */
9063
  enum MHD_Bool v_support_auto_replies_bodies_bool;
9064
  /**
9065
   * The data for the #MHD_LIB_INFO_FIXED_IS_NON_DEBUG query
9066
   */
9067
  enum MHD_Bool v_is_non_debug_bool;
9068
  /**
9069
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_THREADS query
9070
   */
9071
  enum MHD_Bool v_support_threads_bool;
9072
  /**
9073
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_COOKIE_PARSER query
9074
   */
9075
  enum MHD_Bool v_support_cookie_parser_bool;
9076
  /**
9077
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_POST_PARSER query
9078
   */
9079
  enum MHD_Bool v_support_post_parser_bool;
9080
  /**
9081
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_UPGRADE query
9082
   */
9083
  enum MHD_Bool v_support_upgrade_bool;
9084
  /**
9085
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_BASIC query
9086
   */
9087
  enum MHD_Bool v_support_auth_basic_bool;
9088
  /**
9089
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AUTH_DIGEST query
9090
   */
9091
  enum MHD_Bool v_support_auth_digest_bool;
9092
  /**
9093
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_RFC2069 query
9094
   */
9095
  enum MHD_Bool v_support_digest_auth_rfc2069_bool;
9096
  /**
9097
   * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_MD5 query
9098
   */
9099
  enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_md5_algo_type;
9100
  /**
9101
   * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA256 query
9102
   */
9103
  enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha256_algo_type;
9104
  /**
9105
   * The data for the #MHD_LIB_INFO_FIXED_TYPE_DIGEST_AUTH_SHA512_256 query
9106
   */
9107
  enum MHD_LibInfoFixedDigestAlgoType v_type_digest_auth_sha512_256_algo_type;
9108
  /**
9109
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_AUTH_INT query
9110
   */
9111
  enum MHD_Bool v_support_digest_auth_auth_int_bool;
9112
  /**
9113
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_ALGO_SESSION query
9114
   */
9115
  enum MHD_Bool v_support_digest_auth_algo_session_bool;
9116
  /**
9117
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_DIGEST_AUTH_USERHASH query
9118
   */
9119
  enum MHD_Bool v_support_digest_auth_userhash_bool;
9120
  /**
9121
   * The data for the #MHD_LIB_INFO_FIXED_TYPES_SOCKETS_POLLING query
9122
   */
9123
  struct MHD_LibInfoFixedPollingFunc v_types_sockets_polling;
9124
  /**
9125
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_AGGREGATE_FD query
9126
   */
9127
  enum MHD_Bool v_support_aggregate_fd_bool;
9128
  /**
9129
   * The data for the #MHD_LIB_INFO_FIXED_TYPE_IPV6 query
9130
   */
9131
  enum MHD_LibInfoFixedIPv6Type v_ipv6;
9132
  /**
9133
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_TCP_FASTOPEN query
9134
   */
9135
  enum MHD_Bool v_support_tcp_fastopen_bool;
9136
  /**
9137
   * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTODETECT_BIND_PORT query
9138
   */
9139
  enum MHD_Bool v_has_autodetect_bind_port_bool;
9140
  /**
9141
   * The data for the #MHD_LIB_INFO_FIXED_HAS_SENDFILE query
9142
   */
9143
  enum MHD_Bool v_has_sendfile_bool;
9144
  /**
9145
   * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_INT query
9146
   */
9147
  enum MHD_Bool v_has_autosuppress_sigpipe_int_bool;
9148
  /**
9149
   * The data for the #MHD_LIB_INFO_FIXED_HAS_AUTOSUPPRESS_SIGPIPE_EXT query
9150
   */
9151
  enum MHD_Bool v_has_autosuppress_sigpipe_ext_bool;
9152
  /**
9153
   * The data for the #MHD_LIB_INFO_FIXED_HAS_THREAD_NAMES query
9154
   */
9155
  enum MHD_Bool v_has_thread_names_bool;
9156
  /**
9157
   * The data for the #MHD_LIB_INFO_FIXED_TYPE_ITC query
9158
   */
9159
  enum MHD_LibInfoFixedITCType v_type_itc;
9160
  /**
9161
   * The data for the #MHD_LIB_INFO_FIXED_SUPPORT_LARGE_FILE query
9162
   */
9163
  enum MHD_Bool v_support_large_file_bool;
9164
  /**
9165
   * The data for the #MHD_LIB_INFO_FIXED_TLS_BACKENDS query
9166
   */
9167
  struct MHD_LibInfoTLSType v_tls_backends;
9168
  /**
9169
   * The data for the #MHD_LIB_INFO_FIXED_TLS_KEY_PASSWORD_BACKENDS query
9170
   */
9171
  struct MHD_LibInfoTLSType v_tls_key_password_backends;
9172
};
9173
9174
/**
9175
 * Get fixed information about MHD that is not changed at run-time.
9176
 * The returned information can be cached by application as it will be not
9177
 * changed at run-time.
9178
 *
9179
 * For any valid @a info_type the only possible returned error value is
9180
 * #MHD_SC_INFO_GET_BUFF_TOO_SMALL. If the buffer is large enough and
9181
 * the requested type of information is valid, the function always succeeds
9182
 * and returns #MHD_SC_OK.
9183
 *
9184
 * The wrapper macro #MHD_lib_get_info_fixed() may be more convenient.
9185
 *
9186
 * @param info_type the type of requested information
9187
 * @param[out] output_buf the pointer to union to be set to the requested
9188
 *                        information
9189
 * @param output_buf_size the size of the memory area pointed by @a output_buf
9190
 *                        (provided by the caller for storing the requested
9191
 *                        information), in bytes
9192
 * @return #MHD_SC_OK if succeed,
9193
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9194
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small
9195
 * @ingroup specialized
9196
 */
9197
MHD_EXTERN_ enum MHD_StatusCode
9198
MHD_lib_get_info_fixed_sz (enum MHD_LibInfoFixed info_type,
9199
                           union MHD_LibInfoFixedData *MHD_RESTRICT output_buf,
9200
                           size_t output_buf_size)
9201
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2);
9202
9203
/**
9204
 * Get fixed information about MHD that is not changed at run-time.
9205
 * The returned information can be cached by application as it will be not
9206
 * changed at run-time.
9207
 *
9208
 * @param info the type of requested information
9209
 * @param[out] output_buf the pointer to union to be set to the requested
9210
 *                        information
9211
 * @return #MHD_SC_OK if succeed,
9212
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9213
 *         or other error code
9214
 * @ingroup specialized
9215
 */
9216
#define MHD_lib_get_info_fixed(info,output_buf) \
9217
        MHD_lib_get_info_fixed_sz ((info),(output_buf),sizeof(*(output_buf)))
9218
9219
/* Application may define MHD_NO_STATIC_INLINE macro before including
9220
   libmicrohttpd headers to disable static inline functions in the headers. */
9221
#ifndef MHD_NO_STATIC_INLINE
9222
9223
/*
9224
 * A helper below can be used in a simple check preventing use of downgraded
9225
 * library version.
9226
 * As new library version may introduce new functionality, and the application
9227
 * may detect some functionality available at application build-time, use of
9228
 * previous versions may lead to run-time failures.
9229
 * To prevent run-time failures, application may use a check like:
9230
9231
 if (MHD_lib_get_info_ver_num() < ((uint_fast32_t) MHD_VERSION))
9232
   handle_init_failure();
9233
9234
 */
9235
/**
9236
 * Get the library version number.
9237
 * @return the library version number.
9238
 */
9239
MHD_STATIC_INLINE_ MHD_FN_PURE_ uint_fast32_t
9240
MHD_lib_get_info_ver_num (void)
9241
0
{
9242
0
  union MHD_LibInfoFixedData data;
9243
0
  data.v_version_num_uint32 = 0; /* Not really necessary */
9244
0
  (void) MHD_lib_get_info_fixed (MHD_LIB_INFO_FIXED_VERSION_NUM, \
9245
0
                                 &data); /* Never fail */
9246
0
  return data.v_version_num_uint32;
9247
0
}
Unexecuted instantiation: fuzz_connection.cpp:MHD_lib_get_info_ver_num()
Unexecuted instantiation: connection_helper.cpp:MHD_lib_get_info_ver_num()
Unexecuted instantiation: daemon_funcs.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: request_funcs.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: response_destroy.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: response_funcs.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: stream_funcs.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: stream_process_request.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: stream_process_reply.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: post_parser_funcs.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: response_auth_digest.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: auth_digest.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: tls_gnu_funcs.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: mhd_panic.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: http_status_str.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: daemon_logger.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: extr_events_funcs.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: request_get_value.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: respond_with_error.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: response_from.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: response_add_header.c:MHD_lib_get_info_ver_num
Unexecuted instantiation: request_auth_get.c:MHD_lib_get_info_ver_num
9248
9249
9250
MHD_STATIC_INLINE_END_
9251
9252
#endif /* ! MHD_NO_STATIC_INLINE */
9253
9254
/**
9255
 * Types of information about MHD, used by #MHD_lib_get_info_dynamic_sz().
9256
 * This information may vary over time.
9257
 */
9258
enum MHD_FIXED_ENUM_APP_SET_ MHD_LibInfoDynamic
9259
{
9260
  /* * Basic MHD information * */
9261
9262
  /**
9263
   * Get whether MHD has been successfully fully initialised.
9264
   * MHD uses lazy initialisation: a minimal initialisation is performed at
9265
   * startup, complete initialisation is performed when any daemon is created
9266
   * (or when called some function which requires full initialisation).
9267
   * The result is #MHD_NO when the library has been not yet initialised
9268
   * completely since startup.
9269
   * The result is placed in @a v_inited_fully_once_bool member.
9270
   */
9271
  MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE = 0
9272
  ,
9273
  /**
9274
   * Get whether MHD is fully initialised.
9275
   * MHD uses lazy initialisation: a minimal initialisation is performed at
9276
   * startup, complete initialisation is perfromed when any daemon is created
9277
   * (or when called some function which requires full initialisation).
9278
   * The result is #MHD_YES if library is initialised state now (meaning
9279
   * that at least one daemon is created and not destroyed or some function
9280
   * required full initialisation is running).
9281
   * The result is placed in @a v_inited_fully_now_bool member.
9282
   */
9283
  MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW = 1
9284
  ,
9285
9286
  /**
9287
   * Get whether HTTPS and which types of TLS backend(s) currently available.
9288
   * If any MHD daemons active (created and not destroyed, not necessary
9289
   * running) the result reflects the current backends availability.
9290
   * If no MHD daemon is active, then this function would try to temporarily
9291
   * enable backends to check for their availability.
9292
   * If global library initialisation failed, the function returns
9293
   * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE error code.
9294
   * The result is placed in @a v_tls_backends member.
9295
   */
9296
  MHD_LIB_INFO_DYNAMIC_TYPE_TLS = 100
9297
  ,
9298
9299
  /* * Sentinel * */
9300
  /**
9301
   * The sentinel value.
9302
   * This value enforces specific underlying integer type for the enum.
9303
   * Do not use.
9304
   */
9305
  MHD_LIB_INFO_DYNAMIC_SENTINEL = 65535
9306
};
9307
9308
9309
/**
9310
 * The data provided by #MHD_lib_get_info_dynamic_sz().
9311
 * The resulting value may vary over time.
9312
 */
9313
union MHD_LibInfoDynamicData
9314
{
9315
  /**
9316
   * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_ONCE query
9317
   */
9318
  enum MHD_Bool v_inited_fully_once_bool;
9319
9320
  /**
9321
   * The data for the #MHD_LIB_INFO_DYNAMIC_INITED_FULLY_NOW query
9322
   */
9323
  enum MHD_Bool v_inited_fully_now_bool;
9324
9325
  /**
9326
   * The data for the #MHD_LIB_INFO_DYNAMIC_TYPE_TLS query
9327
   */
9328
  struct MHD_LibInfoTLSType v_tls_backends;
9329
9330
  /**
9331
   * Unused member.
9332
   * Help enforcing future-proof alignment of the union.
9333
   * Do not use.
9334
   */
9335
  void *reserved;
9336
};
9337
9338
/**
9339
 * Get dynamic information about MHD that may be changed at run-time.
9340
 * The wrapper macro #MHD_lib_get_info_dynamic() could be more convenient.
9341
 *
9342
 * @param info_type the type of requested information
9343
 * @param[out] output_buf the pointer to union to be set to the requested
9344
 *                        information
9345
 * @param output_buf_size the size of the memory area pointed by @a output_buf
9346
 *                        (provided by the caller for storing the requested
9347
 *                        information), in bytes
9348
 * @return #MHD_SC_OK if succeed,
9349
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9350
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
9351
 *         or other error code
9352
 * @ingroup specialized
9353
 */
9354
MHD_EXTERN_ enum MHD_StatusCode
9355
MHD_lib_get_info_dynamic_sz (
9356
  enum MHD_LibInfoDynamic info_type,
9357
  union MHD_LibInfoDynamicData *MHD_RESTRICT output_buf,
9358
  size_t output_buf_size)
9359
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_OUT_ (2);
9360
9361
/**
9362
 * Get dynamic information about MHD that may be changed at run-time.
9363
 *
9364
 * @param info the type of requested information
9365
 * @param[out] output_buf the pointer to union to be set to the requested
9366
 *                        information
9367
 * @return #MHD_SC_OK if succeed,
9368
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9369
 *         or other error code
9370
 * @ingroup specialized
9371
 */
9372
#define MHD_lib_get_info_dynamic(info,output_buf) \
9373
        MHD_lib_get_info_dynamic_sz ((info),(output_buf),sizeof(*(output_buf)))
9374
9375
9376
/**
9377
 * Values of this enum are used to specify what information about a daemon is
9378
 * requested.
9379
 * These types of information do not change after the start of the daemon
9380
 * until the daemon is destroyed.
9381
 */
9382
enum MHD_DaemonInfoFixedType
9383
{
9384
9385
  /**
9386
   * Get the type of system call used for sockets polling.
9387
   * The value #MHD_SPS_AUTO is never set in the returned data.
9388
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
9389
   * does not use internal sockets polling.
9390
   * The result is placed in @a v_poll_syscall member.
9391
   */
9392
  MHD_DAEMON_INFO_FIXED_POLL_SYSCALL = 41
9393
  ,
9394
  /**
9395
   * Get the file descriptor for the single FD that triggered when
9396
   * any MHD event happens.
9397
   * This FD can be watched as aggregate indicator for all MHD events.
9398
   * The provided socket must be used as 'read-only': only select() or similar
9399
   * functions should be used. Any modifications (changing socket attributes,
9400
   * calling accept(), closing it etc.) will lead to undefined behaviour.
9401
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library
9402
   * does not support mode with agregate FD.
9403
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
9404
   * is not configured to use this mode.
9405
   * The result is placed in @a v_aggreagate_fd member.
9406
   */
9407
  MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 46
9408
  ,
9409
  /**
9410
   * Get the number of worker threads when used in MHD_WM_WORKER_THREADS mode.
9411
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
9412
   * does not use worker threads mode.
9413
   * The result is placed in @a v_num_work_threads_uint member.
9414
   */
9415
  MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS = 47
9416
  ,
9417
  /**
9418
   * Get the port number of daemon's listen socket.
9419
   * Note: if port '0' (auto port) was specified for #MHD_D_OPTION_BIND_PORT(),
9420
   * returned value will be the real port number.
9421
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
9422
   * does not have listening socket or if listening socket is non-IP.
9423
   * The function returns #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the port number
9424
   * detection failed or not supported by the platform.
9425
   * If the function succeed, the returned port number is never zero.
9426
   * The result is placed in @a v_bind_port_uint16 member.
9427
   */
9428
  MHD_DAEMON_INFO_FIXED_BIND_PORT = 80
9429
  ,
9430
  /**
9431
   * Get the file descriptor for the listening socket.
9432
   * The provided socket must be used as 'read-only': only select() or similar
9433
   * functions should be used. Any modifications (changing socket attributes,
9434
   * calling accept(), closing it etc.) will lead to undefined behaviour.
9435
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
9436
   * does not have listening socket.
9437
   * The result is placed in @a v_listen_socket member.
9438
   */
9439
  MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 82
9440
  ,
9441
  /**
9442
   * Get the TLS backend used by the daemon.
9443
   * The value #MHD_TLS_BACKEND_ANY is never set in the returned data.
9444
   * The value #MHD_TLS_BACKEND_NONE is set if the daemon does not use TLS.
9445
   * If MHD built without TLS support then #MHD_TLS_BACKEND_NONE is always set.
9446
   * The result is placed in @a v_tls_backend member.
9447
   */
9448
  MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 120
9449
  ,
9450
  /**
9451
   * Get the default inactivity timeout for connections.
9452
   * The result is placed in @a v_default_timeout_uint member.
9453
   */
9454
  MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT = 160
9455
  ,
9456
  /**
9457
   * Get the limit of number of simutaneous network connections served by
9458
   * the daemon.
9459
   * The result is placed in @a v_global_connection_limit_uint member.
9460
   */
9461
  MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT = 161
9462
  ,
9463
  /**
9464
   * Get the limit of number of simutaneous network connections served by
9465
   * the daemon for any single IP address.
9466
   * The result is placed in @a v_per_ip_limit_uint member.
9467
   */
9468
  MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT = 162
9469
  ,
9470
  /**
9471
   * Get the setting for suppression of the 'Date:' header in replies.
9472
   * The result is placed in @a v_suppress_date_header_bool member.
9473
   */
9474
  MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER = 240
9475
  ,
9476
  /**
9477
   * Get the size of buffer unsed per connection.
9478
   * The result is placed in @a v_conn_memory_limit_sizet member.
9479
   */
9480
  MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT = 280
9481
  ,
9482
  /**
9483
   * Get the limit of maximum FD value for the daemon.
9484
   * The daemon rejects (closes) any sockets with FD equal or higher
9485
   * the resulting number.
9486
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon
9487
   * is built for W32.
9488
   * The result is placed in @a v_fd_number_limit_uint member.
9489
   */
9490
  MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT = 283
9491
  ,
9492
9493
  /* * Sentinel * */
9494
  /**
9495
   * The sentinel value.
9496
   * This value enforces specific underlying integer type for the enum.
9497
   * Do not use.
9498
   */
9499
  MHD_DAEMON_INFO_FIXED_SENTINEL = 65535
9500
9501
};
9502
9503
9504
/**
9505
 * Information about an MHD daemon.
9506
 */
9507
union MHD_DaemonInfoFixedData
9508
{
9509
  /**
9510
   * The data for the #MHD_DAEMON_INFO_FIXED_POLL_SYSCALL query
9511
   */
9512
  enum MHD_SockPollSyscall v_poll_syscall;
9513
9514
  /**
9515
   * The data for the #MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS query
9516
   */
9517
  unsigned int v_num_work_threads_uint;
9518
9519
  /**
9520
   * The data for the #MHD_DAEMON_INFO_FIXED_BIND_PORT query
9521
   */
9522
  uint_least16_t v_bind_port_uint16;
9523
9524
  /**
9525
   * The data for the #MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET query
9526
   */
9527
  MHD_Socket v_listen_socket;
9528
9529
  /**
9530
   * The data for the #MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD query
9531
   */
9532
  int v_aggreagate_fd;
9533
9534
  /**
9535
   * The data for the #MHD_DAEMON_INFO_FIXED_TLS_BACKEND query
9536
   */
9537
  enum MHD_TlsBackend v_tls_backend;
9538
9539
  /**
9540
   * The data for the #MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT query
9541
   */
9542
  unsigned int v_default_timeout_uint;
9543
9544
  /**
9545
   * The data for the #MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT query
9546
   */
9547
  unsigned int v_global_connection_limit_uint;
9548
9549
  /**
9550
   * The data for the #MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT query
9551
   */
9552
  unsigned int v_per_ip_limit_uint;
9553
9554
  /**
9555
   * The data for the #MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER query
9556
   */
9557
  enum MHD_Bool v_suppress_date_header_bool;
9558
9559
  /**
9560
   * The data for the #MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT query
9561
   */
9562
  size_t v_conn_memory_limit_sizet;
9563
9564
  /**
9565
   * The data for the #MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT query
9566
   */
9567
  MHD_Socket v_fd_number_limit_socket;
9568
9569
  /**
9570
   * Unused member.
9571
   * Help enforcing future-proof alignment of the union.
9572
   * Do not use.
9573
   */
9574
  void *reserved;
9575
};
9576
9577
9578
/**
9579
 * Obtain fixed information about the given daemon.
9580
 * This information is not changed at after start of the daemon until
9581
 * the daemon is destroyed.
9582
 * The wrapper macro #MHD_daemon_get_info_fixed() may be more convenient.
9583
 *
9584
 * @param daemon the daemon to get information about
9585
 * @param info_type the type of information requested
9586
 * @param[out] output_buf pointer to union where requested information will
9587
 *                        be stored
9588
 * @param output_buf_size the size of the memory area pointed by @a output_buf
9589
 *                        (provided by the caller for storing the requested
9590
 *                        information), in bytes
9591
 * @return #MHD_SC_OK if succeed,
9592
 *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
9593
 *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
9594
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9595
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
9596
 *                                              is not available for this
9597
 *                                              daemon due to the daemon
9598
 *                                              configuration/mode,
9599
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
9600
 *                                            should be available for
9601
 *                                            the daemon, but cannot be provided
9602
 *                                            due to some error or other
9603
 *                                            reasons,
9604
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
9605
 *         other error codes in case of other errors
9606
 * @ingroup specialized
9607
 */
9608
MHD_EXTERN_ enum MHD_StatusCode
9609
MHD_daemon_get_info_fixed_sz (
9610
  struct MHD_Daemon *MHD_RESTRICT daemon,
9611
  enum MHD_DaemonInfoFixedType info_type,
9612
  union MHD_DaemonInfoFixedData *MHD_RESTRICT output_buf,
9613
  size_t output_buf_size)
9614
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
9615
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
9616
9617
/**
9618
 * Obtain fixed information about the given daemon.
9619
 * This types of information are not changed at after start of the daemon until
9620
 * the daemon is destroyed.
9621
 *
9622
 * @param daemon the daemon to get information about
9623
 * @param info_type the type of information requested
9624
 * @param[out] output_buf pointer to union where requested information will
9625
 *                          be stored
9626
 * @return #MHD_SC_OK if succeed,
9627
 *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
9628
 *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
9629
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9630
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
9631
 *                                              is not available for this
9632
 *                                              daemon due to the daemon
9633
 *                                              configuration/mode,
9634
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
9635
 *                                            should be available for
9636
 *                                            the daemon, but cannot be provided
9637
 *                                            due to some error or other
9638
 *                                            reasons,
9639
 *         other error codes in case of other errors
9640
 * @ingroup specialized
9641
 */
9642
#define MHD_daemon_get_info_fixed(daemon,info_type,output_buf) \
9643
        MHD_daemon_get_info_fixed_sz ((daemon), (info_type), (output_buf), \
9644
                                      sizeof(*(output_buf)))
9645
9646
9647
/**
9648
 * Values of this enum are used to specify what
9649
 * information about a daemon is desired.
9650
 * This types of information may be changed after the start of the daemon.
9651
 */
9652
enum MHD_DaemonInfoDynamicType
9653
{
9654
  /**
9655
   * The the maximum number of millisecond from the current moment until
9656
   * the mandatory call of the daemon data processing function (like
9657
   * #MHD_daemon_process_reg_events(), #MHD_daemon_process_blocking()).
9658
   * If resulting value is zero then daemon data processing function should be
9659
   * called as soon as possible as some data processing is already pending.
9660
   * The data processing function can also be called earlier as well.
9661
   * Available only for daemons stated in #MHD_WM_EXTERNAL_PERIODIC,
9662
   * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL, #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE
9663
   * or #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes.
9664
   * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon has
9665
   * internal handling of events (internal threads).
9666
   * The result is placed in @a v_max_time_to_wait_uint64 member.
9667
   */
9668
  MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT = 1
9669
  ,
9670
  /**
9671
   * Check whether the daemon has any connected network clients.
9672
   * The result is placed in @a v_has_connections_bool member.
9673
   */
9674
  MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS = 20
9675
  ,
9676
  /* * Sentinel * */
9677
  /**
9678
   * The sentinel value.
9679
   * This value enforces specific underlying integer type for the enum.
9680
   * Do not use.
9681
   */
9682
  MHD_DAEMON_INFO_DYNAMIC_SENTINEL = 65535
9683
};
9684
9685
9686
/**
9687
 * Information about an MHD daemon.
9688
 */
9689
union MHD_DaemonInfoDynamicData
9690
{
9691
  /**
9692
   * The data for the #MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT query
9693
   */
9694
  uint_fast64_t v_max_time_to_wait_uint64;
9695
9696
  /**
9697
   * The data for the #MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS query
9698
   */
9699
  enum MHD_Bool v_has_connections_bool;
9700
9701
  /**
9702
   * Unused member.
9703
   * Help enforcing future-proof alignment of the union.
9704
   * Do not use.
9705
   */
9706
  void *reserved;
9707
};
9708
9709
9710
/**
9711
 * Obtain dynamic information about the given daemon.
9712
 * This information may be changed after the start of the daemon.
9713
 * The wrapper macro #MHD_daemon_get_info_dynamic() could be more convenient.
9714
 *
9715
 * @param daemon the daemon to get information about
9716
 * @param info_type the type of information requested
9717
 * @param[out] output_buf the pointer to union to be set to the requested
9718
 *                        information
9719
 * @param output_buf_size the size of the memory area pointed by @a output_buf
9720
 *                        (provided by the caller for storing the requested
9721
 *                        information), in bytes
9722
 * @return #MHD_SC_OK if succeed,
9723
 *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
9724
 *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
9725
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9726
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
9727
 *                                              is not available for this
9728
 *                                              daemon due to the daemon
9729
 *                                              configuration/mode,
9730
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
9731
 *                                            should be available for
9732
 *                                            the daemon, but cannot be provided
9733
 *                                            due to some error or other
9734
 *                                            reasons,
9735
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
9736
 *         other error codes in case of other errors
9737
 * @ingroup specialized
9738
 */
9739
MHD_EXTERN_ enum MHD_StatusCode
9740
MHD_daemon_get_info_dynamic_sz (
9741
  struct MHD_Daemon *MHD_RESTRICT daemon,
9742
  enum MHD_DaemonInfoDynamicType info_type,
9743
  union MHD_DaemonInfoDynamicData *MHD_RESTRICT output_buf,
9744
  size_t output_buf_size)
9745
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
9746
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
9747
9748
/**
9749
 * Obtain dynamic information about the given daemon.
9750
 * This types of information may be changed after the start of the daemon.
9751
 *
9752
 * @param daemon the daemon to get information about
9753
 * @param info_type the type of information requested
9754
 * @param[out] output_buf the pointer to union to be set to the requested
9755
 *                        information
9756
 * @return #MHD_SC_OK if succeed,
9757
 *         #MHD_SC_TOO_EARLY if the daemon has not been started yet,
9758
 *         #MHD_SC_TOO_LATE if the daemon is being stopped or has failed,
9759
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9760
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
9761
 *                                              is not available for this
9762
 *                                              daemon due to the daemon
9763
 *                                              configuration/mode,
9764
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
9765
 *                                            should be available for
9766
 *                                            the daemon, but cannot be provided
9767
 *                                            due to some error or other
9768
 *                                            reasons,
9769
 *         other error codes in case of other errors
9770
 * @ingroup specialized
9771
 */
9772
#define MHD_daemon_get_info_dynamic(daemon,info_type,output_buf) \
9773
        MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (output_buf), \
9774
                                        sizeof(*(output_buf)))
9775
9776
9777
/**
9778
 * Select which fixed information about connection is desired.
9779
 * This information is not changed during the lifetime of the connection.
9780
 */
9781
enum MHD_ConnectionInfoFixedType
9782
{
9783
  /**
9784
   * Get the network address of the client.
9785
   * If the connection does not have known remote address (was not provided
9786
   * by the system or by the application in case of externally added
9787
   * connection) then error code #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is
9788
   * returned if connection is IP type or unknown type or error code
9789
   * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if connection type is non-IP.
9790
   * The @a sa pointer is never NULL if the function succeed (#MHD_SC_OK
9791
   * returned).
9792
   * The result is placed in @a v_client_address_sa_info member.
9793
   * @ingroup request
9794
   */
9795
  MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS = 1
9796
  ,
9797
  /**
9798
   * Get the file descriptor for the connection socket.
9799
   * The provided socket must be used as 'read-only': only select() or similar
9800
   * functions should be used. Any modifications (changing socket attributes,
9801
   * calling send() or recv(), closing it etc.) will lead to undefined
9802
   * behaviour.
9803
   * The result is placed in @a v_connection_socket member.
9804
   * @ingroup request
9805
   */
9806
  MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET = 2
9807
  ,
9808
  /**
9809
   * Get the `struct MHD_Daemon *` responsible for managing this connection.
9810
   * The result is placed in @a v_daemon member.
9811
   * @ingroup request
9812
   */
9813
  MHD_CONNECTION_INFO_FIXED_DAEMON = 20
9814
  ,
9815
  /**
9816
   * Returns the pointer to a variable pointing to connection-specific
9817
   * application context data that was (possibly) set during
9818
   * a #MHD_NotifyConnectionCallback or provided via @a connection_cntx
9819
   * parameter of #MHD_daemon_add_connection().
9820
   * By using provided pointer application may get or set the pointer to
9821
   * any data specific for the particular connection.
9822
   * Note: resulting data is NOT the context pointer itself.
9823
   * The result is placed in @a v_app_context_ppvoid member.
9824
   * @ingroup request
9825
   */
9826
  MHD_CONNECTION_INFO_FIXED_APP_CONTEXT = 30
9827
  ,
9828
9829
  /* * Sentinel * */
9830
  /**
9831
   * The sentinel value.
9832
   * This value enforces specific underlying integer type for the enum.
9833
   * Do not use.
9834
   */
9835
  MHD_CONNECTION_INFO_FIXED_SENTINEL = 65535
9836
};
9837
9838
/**
9839
 * Socket address information data
9840
 */
9841
struct MHD_ConnInfoFixedSockAddr
9842
{
9843
  /**
9844
   * The size of the @a sa
9845
   */
9846
  size_t sa_size;
9847
9848
  /**
9849
   * Socket Address type
9850
   */
9851
  const struct sockaddr *sa;
9852
};
9853
9854
/**
9855
 * Information about a connection.
9856
 */
9857
union MHD_ConnectionInfoFixedData
9858
{
9859
9860
  /**
9861
   * The data for the #MHD_CONNECTION_INFO_FIXED_CLIENT_ADDRESS query
9862
   */
9863
  struct MHD_ConnInfoFixedSockAddr v_client_address_sa_info;
9864
9865
  /**
9866
   * The data for the #MHD_CONNECTION_INFO_FIXED_CONNECTION_SOCKET query
9867
   */
9868
  MHD_Socket v_connection_socket;
9869
9870
  /**
9871
   * The data for the #MHD_CONNECTION_INFO_FIXED_DAEMON query
9872
   */
9873
  struct MHD_Daemon *v_daemon;
9874
9875
  /**
9876
   * The data for the #MHD_CONNECTION_INFO_FIXED_APP_CONTEXT query
9877
   */
9878
  void **v_app_context_ppvoid;
9879
};
9880
9881
9882
/**
9883
 * Obtain fixed information about the given connection.
9884
 * This information is not changed for the lifetime of the connection.
9885
 * The wrapper macro #MHD_connection_get_info_fixed() may be more convenient.
9886
 *
9887
 * @param connection the connection to get information about
9888
 * @param info_type the type of information requested
9889
 * @param[out] output_buf the pointer to union to be set to the requested
9890
 *                        information
9891
 * @param output_buf_size the size of the memory area pointed by @a output_buf
9892
 *                        (provided by the caller for storing the requested
9893
 *                        information), in bytes
9894
 * @return #MHD_SC_OK if succeed,
9895
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9896
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
9897
 *                                              is not available for this
9898
 *                                              connection due to the connection
9899
 *                                              configuration/mode,
9900
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
9901
 *                                            should be available for
9902
 *                                            the connection, but cannot be
9903
 *                                            provided due to some error or
9904
 *                                            other reasons,
9905
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
9906
 *         other error codes in case of other errors
9907
 * @ingroup specialized
9908
 */
9909
MHD_EXTERN_ enum MHD_StatusCode
9910
MHD_connection_get_info_fixed_sz (
9911
  struct MHD_Connection *MHD_RESTRICT connection,
9912
  enum MHD_ConnectionInfoFixedType info_type,
9913
  union MHD_ConnectionInfoFixedData *MHD_RESTRICT output_buf,
9914
  size_t output_buf_size)
9915
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
9916
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
9917
9918
9919
/**
9920
 * Obtain fixed information about the given connection.
9921
 * This information is not changed for the lifetime of the connection.
9922
 *
9923
 * @param connection the connection to get information about
9924
 * @param info_type the type of information requested
9925
 * @param[out] output_buf the pointer to union to be set to the requested
9926
 *                        information
9927
 * @return #MHD_SC_OK if succeed,
9928
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
9929
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
9930
 *                                              is not available for this
9931
 *                                              connection due to the connection
9932
 *                                              configuration/mode,
9933
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
9934
 *                                            should be available for
9935
 *                                            the connection, but cannot be
9936
 *                                            provided due to some error or
9937
 *                                            other reasons,
9938
 *         other error codes in case of other errors
9939
 * @ingroup specialized
9940
 */
9941
#define MHD_connection_get_info_fixed(connection,info_type,output_buf) \
9942
        MHD_connection_get_info_fixed_sz ((connection),(info_type), \
9943
                                          (output_buf), sizeof(*(output_buf)))
9944
9945
9946
/**
9947
 * Select which dynamic information about connection is desired.
9948
 * This information may be changed during the lifetime of the connection.
9949
 */
9950
enum MHD_ConnectionInfoDynamicType
9951
{
9952
  /**
9953
   * Get current version of HTTP protocol used for connection.
9954
   * If connection is handling HTTP/1.x requests the function may return
9955
   * error code #MHD_SC_TOO_EARLY if the full request line has not been received
9956
   * yet for the current request.
9957
   * The result is placed in @a v_http_ver member.
9958
   * @ingroup request
9959
   */
9960
  MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER = 1
9961
  ,
9962
  /**
9963
   * Get connection timeout value.
9964
   * This is the total number of seconds after which the idle connection is
9965
   * automatically disconnected.
9966
   * Note: the value set is NOT the number of seconds left before automatic
9967
   * disconnection.
9968
   * The result is placed in @a v_connection_timeout_uint member.
9969
   * @ingroup request
9970
   */
9971
  MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT = 10
9972
  ,
9973
  /**
9974
   * Check whether the connection is suspended.
9975
   * The result is placed in @a v_connection_suspended_bool member.
9976
   * @ingroup request
9977
   */
9978
  MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED = 11
9979
  ,
9980
  /**
9981
   * Get current version of TLS transport protocol used for connection
9982
   * If plain TCP connection is used then #MHD_TLS_VERSION_NO_TLS set in
9983
   * the data.
9984
   * It TLS handshake is not yet finished then error code #MHD_SC_TOO_EARLY is
9985
   * returned. If TLS has failed or being closed then #MHD_SC_TOO_LATE error
9986
   * code is returned.
9987
   * If TLS version cannot be detected for any reason then error code
9988
   * #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE is returned.
9989
   * The result is placed in @a v_tls_ver member.
9990
   * @ingroup request
9991
   */
9992
  MHD_CONNECTION_INFO_DYNAMIC_TLS_VER = 105
9993
  ,
9994
  /**
9995
   * Get the TLS backend session handle.
9996
   * If plain TCP connection is used then the function returns error code
9997
   * #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE.
9998
   * The resulting union has only one valid member.
9999
   * The result is placed in @a v_tls_session member.
10000
   * @ingroup request
10001
   */
10002
  MHD_CONNECTION_INFO_DYNAMIC_TLS_SESSION = 140
10003
  ,
10004
10005
  /* * Sentinel * */
10006
  /**
10007
   * The sentinel value.
10008
   * This value enforces specific underlying integer type for the enum.
10009
   * Do not use.
10010
   */
10011
  MHD_CONNECTION_INFO_DYNAMIC_SENTINEL = 65535
10012
};
10013
10014
10015
/**
10016
 * The versions of TLS protocol
10017
 */
10018
enum MHD_FIXED_ENUM_MHD_SET_ MHD_TlsVersion
10019
{
10020
10021
  /**
10022
   * No TLS / plain socket connection
10023
   */
10024
  MHD_TLS_VERSION_NO_TLS = 0
10025
  ,
10026
  /**
10027
   * Not supported/failed to negotiate/failed to handshake TLS
10028
   */
10029
  MHD_TLS_VERSION_BROKEN = 1
10030
  ,
10031
  /**
10032
   * TLS version 1.0
10033
   */
10034
  MHD_TLS_VERSION_1_0 = 2
10035
  ,
10036
  /**
10037
   * TLS version 1.1
10038
   */
10039
  MHD_TLS_VERSION_1_1 = 3
10040
  ,
10041
  /**
10042
   * TLS version 1.2
10043
   */
10044
  MHD_TLS_VERSION_1_2 = 4
10045
  ,
10046
  /**
10047
   * TLS version 1.3
10048
   */
10049
  MHD_TLS_VERSION_1_3 = 5
10050
  ,
10051
  /**
10052
   * Some unknown TLS version.
10053
   * The TLS version is supported by TLS backend, but unknown to MHD.
10054
   */
10055
  MHD_TLS_VERSION_UNKNOWN = 1999
10056
};
10057
10058
/**
10059
 * Connection TLS session information.
10060
 * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out
10061
 * which member should be used.
10062
 */
10063
union MHD_ConnInfoDynamicTlsSess
10064
{
10065
  /* Include <gnutls/gnutls.h> before this header to get a better type safety */
10066
  /**
10067
   * GnuTLS session handle, of type "gnutls_session_t".
10068
   */
10069
#if defined(GNUTLS_VERSION_MAJOR) && GNUTLS_VERSION_MAJOR >= 3
10070
  gnutls_session_t v_gnutls_session;
10071
#else
10072
  void * /* gnutls_session_t */ v_gnutls_session;
10073
#endif
10074
10075
  /* Include <openssl/types.h> or <openssl/crypto.h> before this header to get
10076
     a better type safety */
10077
  /**
10078
   * OpenSSL session handle, of type "SSL*".
10079
   */
10080
#if defined(OPENSSL_TYPES_H) && OPENSSL_VERSION_MAJOR >= 3
10081
  SSL *v_openssl_session;
10082
#else
10083
  void /* SSL */ *v_openssl_session;
10084
#endif
10085
};
10086
10087
/**
10088
 * Information about a connection.
10089
 */
10090
union MHD_ConnectionInfoDynamicData
10091
{
10092
  /**
10093
   * The data for the #MHD_CONNECTION_INFO_DYNAMIC_HTTP_VER query
10094
   */
10095
  enum MHD_HTTP_ProtocolVersion v_http_ver;
10096
10097
  /**
10098
   * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_TIMEOUT query
10099
   */
10100
  unsigned int v_connection_timeout_uint;
10101
10102
  /**
10103
   * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query
10104
   */
10105
  enum MHD_Bool v_connection_suspended_bool;
10106
10107
  /**
10108
   * The data for the #MHD_CONNECTION_INFO_DYNAMIC_CONNECTION_SUSPENDED query
10109
   */
10110
  enum MHD_TlsVersion v_tls_ver;
10111
10112
  /**
10113
   * Connection TLS session information.
10114
   * Only one member is valid. Use #MHD_DAEMON_INFO_FIXED_TLS_TYPE to find out
10115
   * which member should be used.
10116
   */
10117
  union MHD_ConnInfoDynamicTlsSess v_tls_session;
10118
};
10119
10120
/**
10121
 * Obtain dynamic information about the given connection.
10122
 * This information may be changed during the lifetime of the connection.
10123
 *
10124
 * The wrapper macro #MHD_connection_get_info_dynamic() may be more convenient.
10125
 *
10126
 * @param connection the connection to get information about
10127
 * @param info_type the type of information requested
10128
 * @param[out] output_buf the pointer to union to be set to the requested
10129
 *                        information
10130
 * @param output_buf_size the size of the memory area pointed by @a output_buf
10131
 *                        (provided by the caller for storing the requested
10132
 *                        information), in bytes
10133
 * @return #MHD_SC_OK if succeed,
10134
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10135
 *         #MHD_SC_TOO_EARLY if the connection has not reached yet required
10136
 *                           state,
10137
 *         #MHD_SC_TOO_LATE if the connection is already in state where
10138
 *                          the requested information is not available,
10139
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
10140
 *                                              is not available for this
10141
 *                                              connection due to the connection
10142
 *                                              configuration/mode,
10143
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
10144
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
10145
 *                                            should be available for
10146
 *                                            the connection, but cannot be
10147
 *                                            provided due to some error or
10148
 *                                            other reasons,
10149
 *         other error codes in case of other errors
10150
 * @ingroup specialized
10151
 */
10152
MHD_EXTERN_ enum MHD_StatusCode
10153
MHD_connection_get_info_dynamic_sz (
10154
  struct MHD_Connection *MHD_RESTRICT connection,
10155
  enum MHD_ConnectionInfoDynamicType info_type,
10156
  union MHD_ConnectionInfoDynamicData *MHD_RESTRICT output_buf,
10157
  size_t output_buf_size)
10158
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
10159
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
10160
10161
10162
/**
10163
 * Obtain dynamic information about the given connection.
10164
 * This information may be changed during the lifetime of the connection.
10165
 *
10166
 * @param connection the connection to get information about
10167
 * @param info_type the type of information requested
10168
 * @param[out] output_buf the pointer to union to be set to the requested
10169
 *                        information
10170
 * @return #MHD_SC_OK if succeed,
10171
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10172
 *         #MHD_SC_TOO_EARLY if the connection has not reached yet required
10173
 *                           state,
10174
 *         #MHD_SC_TOO_LATE if the connection is already in state where
10175
 *                          the requested information is not available,
10176
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
10177
 *                                              is not available for this
10178
 *                                              connection due to the connection
10179
 *                                              configuration/mode,
10180
 *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
10181
 *                                            should be available for
10182
 *                                            the connection, but cannot be
10183
 *                                            provided due to some error or
10184
 *                                            other reasons,
10185
 *         other error codes in case of other errors
10186
 * @ingroup specialized
10187
 */
10188
#define MHD_connection_get_info_dynamic(connection,info_type,output_buf) \
10189
        MHD_connection_get_info_dynamic_sz ((connection),(info_type), \
10190
                                            (output_buf),sizeof(*(output_buf)))
10191
10192
10193
/**
10194
 * Select which fixed information about stream is desired.
10195
 * This information is not changed during the lifetime of the connection.
10196
 */
10197
enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoFixedType
10198
{
10199
  /**
10200
   * Get the `struct MHD_Daemon *` responsible for managing connection which
10201
   * is responsible for this stream.
10202
   * The result is placed in @a v_daemon member.
10203
   * @ingroup request
10204
   */
10205
  MHD_STREAM_INFO_FIXED_DAEMON = 20
10206
  ,
10207
  /**
10208
   * Get the `struct MHD_Connection *` responsible for managing this stream.
10209
   * The result is placed in @a v_connection member.
10210
   * @ingroup request
10211
   */
10212
  MHD_STREAM_INFO_FIXED_CONNECTION = 21
10213
  ,
10214
10215
  /* * Sentinel * */
10216
  /**
10217
   * The sentinel value.
10218
   * This value enforces specific underlying integer type for the enum.
10219
   * Do not use.
10220
   */
10221
  MHD_STREAM_INFO_FIXED_SENTINEL = 65535
10222
};
10223
10224
10225
/**
10226
 * Fixed information about a stream.
10227
 */
10228
union MHD_StreamInfoFixedData
10229
{
10230
  /**
10231
   * The data for the #MHD_STREAM_INFO_FIXED_DAEMON query
10232
   */
10233
  struct MHD_Daemon *v_daemon;
10234
  /**
10235
   * The data for the #MHD_STREAM_INFO_FIXED_CONNECTION query
10236
   */
10237
  struct MHD_Connection *v_connection;
10238
};
10239
10240
10241
/**
10242
 * Obtain fixed information about the given stream.
10243
 * This information is not changed for the lifetime of the stream.
10244
 *
10245
 * The wrapper macro #MHD_stream_get_info_fixed() may be more convenient.
10246
 *
10247
 * @param stream the stream to get information about
10248
 * @param info_type the type of information requested
10249
 * @param[out] output_buf the pointer to union to be set to the requested
10250
 *                        information
10251
 * @param output_buf_size the size of the memory area pointed by @a output_buf
10252
 *                        (provided by the caller for storing the requested
10253
 *                        information), in bytes
10254
 * @return #MHD_SC_OK if succeed,
10255
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10256
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
10257
 *         other error codes in case of other errors
10258
 * @ingroup specialized
10259
 */
10260
MHD_EXTERN_ enum MHD_StatusCode
10261
MHD_stream_get_info_fixed_sz (
10262
  struct MHD_Stream *MHD_RESTRICT stream,
10263
  enum MHD_StreamInfoFixedType info_type,
10264
  union MHD_StreamInfoFixedData *MHD_RESTRICT output_buf,
10265
  size_t output_buf_size)
10266
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
10267
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
10268
10269
10270
/**
10271
 * Obtain fixed information about the given stream.
10272
 * This information is not changed for the lifetime of the tream.
10273
 *
10274
 * @param stream the stream to get information about
10275
 * @param info_type the type of information requested
10276
 * @param[out] output_buf the pointer to union to be set to the requested
10277
 *                        information
10278
 * @return #MHD_SC_OK if succeed,
10279
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10280
 *         other error codes in case of other errors
10281
 * @ingroup specialized
10282
 */
10283
#define MHD_stream_get_info_fixed(stream,info_type,output_buf) \
10284
        MHD_stream_get_info_fixed_sz ((stream),(info_type),(output_buf), \
10285
                                      sizeof(*(output_buf)))
10286
10287
10288
/**
10289
 * Select which fixed information about stream is desired.
10290
 * This information may be changed during the lifetime of the stream.
10291
 */
10292
enum MHD_FIXED_ENUM_APP_SET_ MHD_StreamInfoDynamicType
10293
{
10294
  /**
10295
   * Get the `struct MHD_Request *` for current request processed by the stream.
10296
   * If no request is being processed, the error code #MHD_SC_TOO_EARLY is
10297
   * returned.
10298
   * The result is placed in @a v_request member.
10299
   * @ingroup request
10300
   */
10301
  MHD_STREAM_INFO_DYNAMIC_REQUEST = 20
10302
  ,
10303
10304
  /* * Sentinel * */
10305
  /**
10306
   * The sentinel value.
10307
   * This value enforces specific underlying integer type for the enum.
10308
   * Do not use.
10309
   */
10310
  MHD_STREAM_INFO_DYNAMIC_SENTINEL = 65535
10311
};
10312
10313
10314
/**
10315
 * Dynamic information about stream.
10316
 * This information may be changed during the lifetime of the connection.
10317
 */
10318
union MHD_StreamInfoDynamicData
10319
{
10320
  /**
10321
   * The data for the #MHD_STREAM_INFO_DYNAMIC_REQUEST query
10322
   */
10323
  struct MHD_Request *v_request;
10324
};
10325
10326
/**
10327
 * Obtain dynamic information about the given stream.
10328
 * This information may be changed during the lifetime of the stream.
10329
 *
10330
 * The wrapper macro #MHD_stream_get_info_dynamic() may be more convenient.
10331
 *
10332
 * @param stream the stream to get information about
10333
 * @param info_type the type of information requested
10334
 * @param[out] output_buf the pointer to union to be set to the requested
10335
 *                        information
10336
 * @param output_buf_size the size of the memory area pointed by @a output_buf
10337
 *                        (provided by the caller for storing the requested
10338
 *                        information), in bytes
10339
 * @return #MHD_SC_OK if succeed,
10340
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10341
 *         #MHD_SC_TOO_EARLY if the stream has not reached yet required state,
10342
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
10343
 *         other error codes in case of other errors
10344
 * @ingroup specialized
10345
 */
10346
MHD_EXTERN_ enum MHD_StatusCode
10347
MHD_stream_get_info_dynamic_sz (
10348
  struct MHD_Stream *MHD_RESTRICT stream,
10349
  enum MHD_StreamInfoDynamicType info_type,
10350
  union MHD_StreamInfoDynamicData *MHD_RESTRICT output_buf,
10351
  size_t output_buf_size)
10352
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
10353
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
10354
10355
10356
/**
10357
 * Obtain dynamic information about the given stream.
10358
 * This information may be changed during the lifetime of the stream.
10359
 *
10360
 * @param stream the stream to get information about
10361
 * @param info_type the type of information requested
10362
 * @param[out] output_buf the pointer to union to be set to the requested
10363
 *                        information
10364
 * @return #MHD_SC_OK if succeed,
10365
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10366
 *         #MHD_SC_TOO_EARLY if the stream has not reached yet required state,
10367
 *         other error codes in case of other errors
10368
 * @ingroup specialized
10369
 */
10370
#define MHD_stream_get_info_dynamic(stream,info_type,output_buf) \
10371
        MHD_stream_get_info_dynamic_sz ((stream),(info_type),(output_buf), \
10372
                                        sizeof(*(output_buf)))
10373
10374
10375
/**
10376
 * Select which fixed information about request is desired.
10377
 * This information is not changed during the lifetime of the request.
10378
 */
10379
enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoFixedType
10380
{
10381
  /**
10382
   * Get the version of HTTP protocol used for the request.
10383
   * If request line has not been fully received yet then #MHD_SC_TOO_EARLY
10384
   * error code is returned.
10385
   * The result is placed in @a v_http_ver member.
10386
   * @ingroup request
10387
   */
10388
  MHD_REQUEST_INFO_FIXED_HTTP_VER = 1
10389
  ,
10390
  /**
10391
   * Get the HTTP method used for the request (as a enum).
10392
   * The result is placed in @a v_http_method member.
10393
   * @sa #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR
10394
   * @ingroup request
10395
   */
10396
  MHD_REQUEST_INFO_FIXED_HTTP_METHOD = 2
10397
  ,
10398
  /**
10399
   * Return MHD daemon to which the request belongs to.
10400
   * The result is placed in @a v_daemon member.
10401
   */
10402
  MHD_REQUEST_INFO_FIXED_DAEMON = 20
10403
  ,
10404
  /**
10405
   * Return which connection is associated with the stream which is associated
10406
   * with the request.
10407
   * The result is placed in @a v_connection member.
10408
   */
10409
  MHD_REQUEST_INFO_FIXED_CONNECTION = 21
10410
  ,
10411
  /**
10412
   * Return which stream the request is associated with.
10413
   * The result is placed in @a v_stream member.
10414
   */
10415
  MHD_REQUEST_INFO_FIXED_STREAM = 22
10416
  ,
10417
  /**
10418
   * Returns the pointer to a variable pointing to request-specific
10419
   * application context data. The same data is provided for
10420
   * #MHD_EarlyUriLogCallback and #MHD_RequestTerminationCallback.
10421
   * By using provided pointer application may get or set the pointer to
10422
   * any data specific for the particular request.
10423
   * Note: resulting data is NOT the context pointer itself.
10424
   * The result is placed in @a v_app_context_ppvoid member.
10425
   * @ingroup request
10426
   */
10427
  MHD_REQUEST_INFO_FIXED_APP_CONTEXT = 30
10428
  ,
10429
10430
  /* * Sentinel * */
10431
  /**
10432
   * The sentinel value.
10433
   * This value enforces specific underlying integer type for the enum.
10434
   * Do not use.
10435
   */
10436
  MHD_REQUEST_INFO_FIXED_SENTINEL = 65535
10437
};
10438
10439
10440
/**
10441
 * Fixed information about a request.
10442
 */
10443
union MHD_RequestInfoFixedData
10444
{
10445
10446
  /**
10447
   * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_VER query
10448
   */
10449
  enum MHD_HTTP_ProtocolVersion v_http_ver;
10450
10451
  /**
10452
   * The data for the #MHD_REQUEST_INFO_FIXED_HTTP_METHOD query
10453
   */
10454
  enum MHD_HTTP_Method v_http_method;
10455
10456
  /**
10457
   * The data for the #MHD_REQUEST_INFO_FIXED_DAEMON query
10458
   */
10459
  struct MHD_Daemon *v_daemon;
10460
10461
  /**
10462
   * The data for the #MHD_REQUEST_INFO_FIXED_CONNECTION query
10463
   */
10464
  struct MHD_Connection *v_connection;
10465
10466
  /**
10467
   * The data for the #MHD_REQUEST_INFO_FIXED_STREAM query
10468
   */
10469
  struct MHD_Stream *v_stream;
10470
10471
  /**
10472
   * The data for the #MHD_REQUEST_INFO_FIXED_APP_CONTEXT query
10473
   */
10474
  void **v_app_context_ppvoid;
10475
};
10476
10477
/**
10478
 * Obtain fixed information about the given request.
10479
 * This information is not changed for the lifetime of the request.
10480
 *
10481
 * The wrapper macro #MHD_request_get_info_fixed() may be more convenient.
10482
 *
10483
 * @param request the request to get information about
10484
 * @param info_type the type of information requested
10485
 * @param[out] output_buf the pointer to union to be set to the requested
10486
 *                        information
10487
 * @param output_buf_size the size of the memory area pointed by @a output_buf
10488
 *                        (provided by the caller for storing the requested
10489
 *                        information), in bytes
10490
 * @return #MHD_SC_OK if succeed,
10491
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10492
 *         #MHD_SC_TOO_EARLY if the request processing has not reached yet
10493
 *                           the required state,
10494
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
10495
 *         other error codes in case of other errors
10496
 * @ingroup specialized
10497
 */
10498
MHD_EXTERN_ enum MHD_StatusCode
10499
MHD_request_get_info_fixed_sz (
10500
  struct MHD_Request *MHD_RESTRICT request,
10501
  enum MHD_RequestInfoFixedType info_type,
10502
  union MHD_RequestInfoFixedData *MHD_RESTRICT output_buf,
10503
  size_t output_buf_size)
10504
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
10505
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
10506
10507
10508
/**
10509
 * Obtain fixed information about the given request.
10510
 * This information is not changed for the lifetime of the request.
10511
 *
10512
 * @param request the request to get information about
10513
 * @param info_type the type of information requested
10514
 * @param[out] output_buf the pointer to union to be set to the requested
10515
 *                        information
10516
 * @return #MHD_SC_OK if succeed,
10517
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if @a info_type value is unknown,
10518
 *         #MHD_SC_TOO_EARLY if the request processing has not reached yet
10519
 *                           the required state,
10520
 *         other error codes in case of other errors
10521
 * @ingroup specialized
10522
 */
10523
#define MHD_request_get_info_fixed(request,info_type,output_buf) \
10524
        MHD_request_get_info_fixed_sz ((request), (info_type), (output_buf), \
10525
                                       sizeof(*(output_buf)))
10526
10527
10528
/**
10529
 * Select which dynamic information about request is desired.
10530
 * This information may be changed during the lifetime of the request.
10531
 * Any returned string pointers are valid only until a response is provided.
10532
 */
10533
enum MHD_FIXED_ENUM_APP_SET_ MHD_RequestInfoDynamicType
10534
{
10535
  /**
10536
   * Get the HTTP method used for the request (as a MHD_String).
10537
   * The resulting string pointer in valid only until a response is provided.
10538
   * The result is placed in @a v_http_method_string member.
10539
   * @sa #MHD_REQUEST_INFO_FIXED_HTTP_METHOD
10540
   * @ingroup request
10541
   */
10542
  MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING = 1
10543
  ,
10544
  /**
10545
   * Get the URI used for the request (as a MHD_String), excluding
10546
   * the parameter part (anything after '?').
10547
   * The resulting string pointer in valid only until a response is provided.
10548
   * The result is placed in @a v_uri_string member.
10549
   * @ingroup request
10550
   */
10551
  MHD_REQUEST_INFO_DYNAMIC_URI = 2
10552
  ,
10553
  /**
10554
   * Get the number of URI parameters (the decoded part of the original
10555
   * URI string after '?'). Sometimes it is called "GET parameters".
10556
   * The result is placed in @a v_number_uri_params_sizet member.
10557
   * @ingroup request
10558
   */
10559
  MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS = 3
10560
  ,
10561
  /**
10562
   * Get the number of cookies in the request.
10563
   * The result is placed in @a v_number_cookies_sizet member.
10564
   * If cookies parsing is disabled in MHD build then the function returns
10565
   * error code #MHD_SC_FEATURE_DISABLED.
10566
   * If cookies parsing is disabled this daemon then the function returns
10567
   * error code #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE.
10568
   * @ingroup request
10569
   */
10570
  MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES = 4
10571
  ,
10572
  /**
10573
   * Return length of the client's HTTP request header.
10574
   * This is a total raw size of the header (after TLS decipher if any)
10575
   * The result is placed in @a v_header_size_sizet member.
10576
   * @ingroup request
10577
   */
10578
  MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE = 5
10579
  ,
10580
  /**
10581
   * Get the number of decoded POST entries in the request.
10582
   * The result is placed in @a v_number_post_params_sizet member.
10583
   * @ingroup request
10584
   */
10585
  MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS = 6
10586
  ,
10587
  /**
10588
   * Get whether the upload content is present in the request.
10589
   * The result is #MHD_YES if any upload content is present, even
10590
   * if the upload content size is zero.
10591
   * The result is placed in @a v_upload_present_bool member.
10592
   * @ingroup request
10593
   */
10594
  MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT = 10
10595
  ,
10596
  /**
10597
   * Get whether the chunked upload content is present in the request.
10598
   * The result is #MHD_YES if chunked upload content is present.
10599
   * The result is placed in @a v_upload_chunked_bool member.
10600
   * @ingroup request
10601
   */
10602
  MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED = 11
10603
  ,
10604
  /**
10605
   * Get the total content upload size.
10606
   * Resulted in zero if no content upload or upload content size is zero,
10607
   * #MHD_SIZE_UNKNOWN if size is not known (chunked upload).
10608
   * The result is placed in @a v_upload_size_total_uint64 member.
10609
   * @ingroup request
10610
   */
10611
  MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL = 12
10612
  ,
10613
  /**
10614
   * Get the total size of the content upload already received from the client.
10615
   * This is the total size received, could be not yet fully processed by the
10616
   * application.
10617
   * The result is placed in @a v_upload_size_recieved_uint64 member.
10618
   * @ingroup request
10619
   */
10620
  MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED = 13
10621
  ,
10622
  /**
10623
   * Get the total size of the content upload left to be received from
10624
   * the client.
10625
   * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload).
10626
   * The result is placed in @a v_upload_size_to_recieve_uint64 member.
10627
   * @ingroup request
10628
   */
10629
  MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE = 14
10630
  ,
10631
  /**
10632
   * Get the total size of the content upload already processed (upload callback
10633
   * called and completed (if any)).
10634
   * If the value is requested from #MHD_UploadCallback, then result does NOT
10635
   * include the current data being processed by the callback.
10636
   * The result is placed in @a v_upload_size_processed_uint64 member.
10637
   * @ingroup request
10638
   */
10639
  MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED = 15
10640
  ,
10641
  /**
10642
   * Get the total size of the content upload left to be processed.
10643
   * The resulting value includes the size of the data not yet received from
10644
   * the client.
10645
   * If the value is requested from #MHD_UploadCallback, then result includes
10646
   * the current data being processed by the callback.
10647
   * Resulted in #MHD_SIZE_UNKNOWN if total size is not known (chunked upload).
10648
   * The result is placed in @a v_upload_size_to_process_uint64 member.
10649
   * @ingroup request
10650
   */
10651
  MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS = 16
10652
  ,
10653
  /**
10654
   * Returns pointer to information about digest auth in client request.
10655
   * The resulting pointer is NULL if no digest auth header is set by
10656
   * the client or the format of the digest auth header is broken.
10657
   * Pointers in the returned structure (if any) are valid until response
10658
   * is provided for the request.
10659
   * The result is placed in @a v_auth_digest_info member.
10660
   */
10661
  MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO = 42
10662
  ,
10663
  /**
10664
   * Returns information about Basic Authentication credentials in the request.
10665
   * Pointers in the returned structure (if any) are valid until any MHD_Action
10666
   * or MHD_UploadAction is provided. If the data is needed beyond this point,
10667
   * it should be copied.
10668
   * If #MHD_request_get_info_dynamic_sz() returns #MHD_SC_OK then
10669
   * @a v_auth_basic_creds is NOT NULL and at least the username data
10670
   * is provided.
10671
   * The result is placed in @a v_auth_basic_creds member.
10672
   */
10673
  MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS = 51
10674
  ,
10675
  /* * Sentinel * */
10676
  /**
10677
   * The sentinel value.
10678
   * This value enforces specific underlying integer type for the enum.
10679
   * Do not use.
10680
   */
10681
  MHD_REQUEST_INFO_DYNAMIC_SENTINEL = 65535
10682
};
10683
10684
10685
/**
10686
 * Dynamic information about a request.
10687
 */
10688
union MHD_RequestInfoDynamicData
10689
{
10690
10691
  /**
10692
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING query
10693
   */
10694
  struct MHD_String v_http_method_string;
10695
10696
  /**
10697
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_URI query
10698
   */
10699
  struct MHD_String v_uri_string;
10700
10701
  /**
10702
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS query
10703
   */
10704
  size_t v_number_uri_params_sizet;
10705
10706
  /**
10707
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES query
10708
   */
10709
  size_t v_number_cookies_sizet;
10710
10711
  /**
10712
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE query
10713
   */
10714
  size_t v_header_size_sizet;
10715
10716
  /**
10717
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS query
10718
   */
10719
  size_t v_number_post_params_sizet;
10720
10721
  /**
10722
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT query
10723
   */
10724
  enum MHD_Bool v_upload_present_bool;
10725
10726
  /**
10727
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED query
10728
   */
10729
  enum MHD_Bool v_upload_chunked_bool;
10730
10731
  /**
10732
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL query
10733
   */
10734
  uint_fast64_t v_upload_size_total_uint64;
10735
10736
  /**
10737
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED query
10738
   */
10739
  uint_fast64_t v_upload_size_recieved_uint64;
10740
10741
  /**
10742
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE query
10743
   */
10744
  uint_fast64_t v_upload_size_to_recieve_uint64;
10745
10746
  /**
10747
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED query
10748
   */
10749
  uint_fast64_t v_upload_size_processed_uint64;
10750
10751
  /**
10752
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS query
10753
   */
10754
  uint_fast64_t v_upload_size_to_process_uint64;
10755
10756
  /**
10757
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO query
10758
   */
10759
  const struct MHD_AuthDigestInfo *v_auth_digest_info;
10760
10761
  /**
10762
   * The data for the #MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS query
10763
   */
10764
  const struct MHD_AuthBasicCreds *v_auth_basic_creds;
10765
};
10766
10767
10768
/**
10769
 * Obtain dynamic information about the given request.
10770
 * This information may be changed during the lifetime of the request.
10771
 * Most of the data provided is available only when the request line or complete
10772
 * request headers are processed and not available if responding has been
10773
 * started.
10774
 *
10775
 * The wrapper macro #MHD_request_get_info_dynamic() may be more convenient.
10776
 *
10777
 * Any pointers in the returned data are valid until any MHD_Action or
10778
 * MHD_UploadAction is provided. If the data is needed beyond this point,
10779
 * it should be copied.
10780
 *
10781
 * @param request the request to get information about
10782
 * @param info_type the type of information requested
10783
 * @param[out] output_buf the pointer to union to be set to the requested
10784
 *                        information
10785
 * @param output_buf_size the size of the memory area pointed by @a output_buf
10786
 *                        (provided by the caller for storing the requested
10787
 *                        information), in bytes
10788
 * @return #MHD_SC_OK if succeed,
10789
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is
10790
 *                                       not recognized by MHD,
10791
 *         #MHD_SC_TOO_LATE if request is already being closed or the response
10792
 *                          is being sent
10793
 *         #MHD_SC_TOO_EARLY if requested data is not yet ready (for example,
10794
 *                           headers are not yet received),
10795
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is
10796
 *                                              not available for this request
10797
 *                                              due to used configuration/mode,
10798
 *         #MHD_SC_FEATURE_DISABLED if requested functionality is not supported
10799
 *                                  by this MHD build,
10800
 *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
10801
 *         #MHD_SC_AUTH_ABSENT if request does not have particular Auth data,
10802
 *         #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool
10803
 *                                                  has no space to put decoded
10804
 *                                                  authentication data,
10805
 *         #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is
10806
 *                                      incorrect or broken,
10807
 *         other error codes in case of other errors
10808
 * @ingroup specialized
10809
 */
10810
MHD_EXTERN_ enum MHD_StatusCode
10811
MHD_request_get_info_dynamic_sz (
10812
  struct MHD_Request *MHD_RESTRICT request,
10813
  enum MHD_RequestInfoDynamicType info_type,
10814
  union MHD_RequestInfoDynamicData *MHD_RESTRICT output_buf,
10815
  size_t output_buf_size)
10816
MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ (1)
10817
MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
10818
10819
10820
/**
10821
 * Obtain dynamic information about the given request.
10822
 * This information may be changed during the lifetime of the request.
10823
 * Most of the data provided is available only when the request line or complete
10824
 * request headers are processed and not available if responding has been
10825
 * started.
10826
 *
10827
 * Any pointers in the returned data are valid until any MHD_Action or
10828
 * MHD_UploadAction is provided. If the data is needed beyond this point,
10829
 * it should be copied.
10830
 *
10831
 * @param request the request to get information about
10832
 * @param info_type the type of information requested
10833
 * @param[out] output_buf the pointer to union to be set to the requested
10834
 *                        information
10835
 * @return #MHD_SC_OK if succeed,
10836
 *         #MHD_SC_INFO_GET_TYPE_UNKNOWN if requested information type is
10837
 *                                       not recognized by MHD,
10838
 *         #MHD_SC_TOO_LATE if request is already being closed or the response
10839
 *                          is being sent
10840
 *         #MHD_SC_TOO_EARLY if requested data is not yet ready (for example,
10841
 *                           headers are not yet received),
10842
 *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information is
10843
 *                                              not available for this request
10844
 *                                              due to used configuration/mode,
10845
 *         #MHD_SC_FEATURE_DISABLED if requested functionality is not supported
10846
 *                                  by this MHD build,
10847
 *         #MHD_SC_AUTH_ABSENT if request does not have particular Auth data,
10848
 *         #MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA if connection memory pool
10849
 *                                                  has no space to put decoded
10850
 *                                                  authentication data,
10851
 *         #MHD_SC_REQ_AUTH_DATA_BROKEN if the format of authentication data is
10852
 *                                      incorrect or broken,
10853
 *         other error codes in case of other errors
10854
 * @ingroup specialized
10855
 */
10856
#define MHD_request_get_info_dynamic(request,info_type,output_buf) \
10857
        MHD_request_get_info_dynamic_sz ((request), (info_type), \
10858
                                         (output_buf), \
10859
                                         sizeof(*(output_buf)))
10860
10861
/**
10862
 * Callback for serious error condition. The default action is to print
10863
 * an error message and `abort()`.
10864
 * The callback should not return.
10865
 * Some parameters could be empty strings (the strings with zero-termination at
10866
 * zero position) if MHD built without log messages (only for embedded
10867
 * projects).
10868
 *
10869
 * @param cls user specified value
10870
 * @param file where the error occurred, could be empty
10871
 * @param func the name of the function, where the error occurred, may be empty
10872
 * @param line where the error occurred
10873
 * @param message the error details, could be empty
10874
 * @ingroup logging
10875
 */
10876
typedef void
10877
(*MHD_PanicCallback) (void *cls,
10878
                      const char *file,
10879
                      const char *func,
10880
                      unsigned int line,
10881
                      const char *message);
10882
10883
10884
/**
10885
 * Sets the global error handler to a different implementation.
10886
 * The @a cb will only be called in the case of typically fatal, serious
10887
 * internal consistency issues.
10888
 * These issues should only arise in the case of serious memory corruption or
10889
 * similar problems with the architecture.
10890
 * The @a cb should not return.
10891
 *
10892
 * The default implementation that is used if no panic function is set
10893
 * simply prints an error message and calls `abort()`.  Alternative
10894
 * implementations might call `exit()` or other similar functions.
10895
 *
10896
 * @param cb new error handler, NULL to reset to default handler
10897
 * @param cls passed to @a cb
10898
 * @ingroup logging
10899
 */
10900
MHD_EXTERN_ void
10901
MHD_lib_set_panic_func (MHD_PanicCallback cb,
10902
                        void *cls);
10903
10904
#define MHD_lib_set_panic_func_default() \
10905
        MHD_lib_set_panic_func (MHD_STATIC_CAST_ (MHD_PanicCallback,NULL),NULL)
10906
MHD_C_DECLRATIONS_FINISH_HERE_
10907
10908
#endif /* ! MICROHTTPD2_H */