[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd2] branch master updated: work on manual
From: |
Admin |
Subject: |
[libmicrohttpd2] branch master updated: work on manual |
Date: |
Wed, 12 Feb 2025 01:48:52 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository libmicrohttpd2.
The following commit(s) were added to refs/heads/master by this push:
new a1fd4e2 work on manual
a1fd4e2 is described below
commit a1fd4e2caee803ab3e0fd95aeb1e2e51a44ed35d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Feb 12 01:48:41 2025 +0100
work on manual
---
doc/examples/init-example.c | 36 ++
doc/libmicrohttpd2.texi | 17 +
doc/manual/http-status-texi.gen | 130 ++++++
doc/manual/init.inc | 40 +-
doc/manual/introduction.inc | 10 +-
doc/manual/responses.inc | 911 ++++++++++++++++++++++++++++------------
6 files changed, 867 insertions(+), 277 deletions(-)
diff --git a/doc/examples/init-example.c b/doc/examples/init-example.c
new file mode 100644
index 0000000..ae3eab0
--- /dev/null
+++ b/doc/examples/init-example.c
@@ -0,0 +1,36 @@
+#include <microhttpd2.h>
+#include <assert.h>
+
+static struct MHD_Action *
+handle_request (void *cls,
+ struct MHD_Request *request,
+ const struct MHD_String *path,
+ enum MHD_HTTP_Method method,
+ uint_fast64_t upload_size)
+{
+ /* We passed NULL in main() for the closure */
+ assert (NULL == cls);
+ /* This simply closes the connection after receiving
+ the HTTP header, never return actually returning
+ any data. */
+ return MHD_action_abort_request (request);
+}
+
+
+int
+main ()
+{
+ struct MHD_Daemon *d;
+
+ /* Create an HTTP server and use "handle_request()" to
+ handle all requests. */
+ d = MHD_daemon_create (&handle_request,
+ NULL);
+ /* We run with everything on default, so port 80, no TLS */
+ MHD_daemon_start (d);
+ /* Wait for input on stdin */
+ (void) getchar ();
+ /* Then just shut everything down */
+ MHD_daemon_stop (d);
+ return 0;
+}
diff --git a/doc/libmicrohttpd2.texi b/doc/libmicrohttpd2.texi
index b80a9d3..b000f39 100644
--- a/doc/libmicrohttpd2.texi
+++ b/doc/libmicrohttpd2.texi
@@ -93,6 +93,23 @@ Indices
@chapter Starting and stopping the HTTP server
@include manual/init.inc
+@node libmicrohttpd2-responses
+@chapter Responses to HTTP requests
+@include manual/responses.inc
+
+@c NEXT:
+@c - actions
+@c - thread modes
+@c - requests
+@c - post
+@c - auth
+@c - introspection
+@c - upgrade + response-upgrade
+@c - doptions!
+@c - request options!
+@c - other options (connection, session?)
+@c - what about flow?
+@c - finally: add more examples!
@bye
diff --git a/doc/manual/http-status-texi.gen b/doc/manual/http-status-texi.gen
new file mode 100644
index 0000000..849ad8d
--- /dev/null
+++ b/doc/manual/http-status-texi.gen
@@ -0,0 +1,130 @@
+@item MHD_HTTP_STATUS_CONTINUE
+100: Continue [RFC7231, Section 6.2.1]
+@item MHD_HTTP_STATUS_SWITCHING_PROTOCOLS
+101: Switching Protocols [RFC7231, Section 6.2.2]
+@item MHD_HTTP_STATUS_PROCESSING
+102: Processing [RFC2518]
+@item MHD_HTTP_STATUS_EARLY_HINTS
+103: Early Hints [RFC8297]
+@item MHD_HTTP_STATUS_OK
+200: OK [RFC7231, Section 6.3.1]
+@item MHD_HTTP_STATUS_CREATED
+201: Created [RFC7231, Section 6.3.2]
+@item MHD_HTTP_STATUS_ACCEPTED
+202: Accepted [RFC7231, Section 6.3.3]
+@item MHD_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION
+203: Non-Authoritative Information [RFC7231, Section 6.3.4]
+@item MHD_HTTP_STATUS_NO_CONTENT
+204: No Content [RFC7231, Section 6.3.5]
+@item MHD_HTTP_STATUS_RESET_CONTENT
+205: Reset Content [RFC7231, Section 6.3.6]
+@item MHD_HTTP_STATUS_PARTIAL_CONTENT
+206: Partial Content [RFC7233, Section 4.1]
+@item MHD_HTTP_STATUS_MULTI_STATUS
+207: Multi-Status [RFC4918]
+@item MHD_HTTP_STATUS_ALREADY_REPORTED
+208: Already Reported [RFC5842]
+@item MHD_HTTP_STATUS_IM_USED
+226: IM Used [RFC3229]
+@item MHD_HTTP_STATUS_MULTIPLE_CHOICES
+300: Multiple Choices [RFC7231, Section 6.4.1]
+@item MHD_HTTP_STATUS_MOVED_PERMANENTLY
+301: Moved Permanently [RFC7231, Section 6.4.2]
+@item MHD_HTTP_STATUS_FOUND
+302: Found [RFC7231, Section 6.4.3]
+@item MHD_HTTP_STATUS_SEE_OTHER
+303: See Other [RFC7231, Section 6.4.4]
+@item MHD_HTTP_STATUS_NOT_MODIFIED
+304: Not Modified [RFC7232, Section 4.1]
+@item MHD_HTTP_STATUS_USE_PROXY
+305: Use Proxy [RFC7231, Section 6.4.5]
+@item MHD_HTTP_STATUS_SWITCH_PROXY
+306: Switch proxy (not used) [RFC7231, Section 6.4.6]
+@item MHD_HTTP_STATUS_TEMPORARY_REDIRECT
+307: Temporary Redirect [RFC7231, Section 6.4.7]
+@item MHD_HTTP_STATUS_PERMANENT_REDIRECT
+308: Permanent Redirect [RFC7538]
+@item MHD_HTTP_STATUS_BAD_REQUEST
+400: Bad Request [RFC7231, Section 6.5.1]
+@item MHD_HTTP_STATUS_UNAUTHORIZED
+401: Unauthorized [RFC7235, Section 3.1]
+@item MHD_HTTP_STATUS_PAYMENT_REQUIRED
+402: Payment Required [RFC7231, Section 6.5.2]
+@item MHD_HTTP_STATUS_FORBIDDEN
+403: Forbidden [RFC7231, Section 6.5.3]
+@item MHD_HTTP_STATUS_NOT_FOUND
+404: Not Found [RFC7231, Section 6.5.4]
+@item MHD_HTTP_STATUS_METHOD_NOT_ALLOWED
+405: Method Not Allowed [RFC7231, Section 6.5.5]
+@item MHD_HTTP_STATUS_NOT_ACCEPTABLE
+406: Not Acceptable [RFC7231, Section 6.5.6]
+@item MHD_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED
+407: Proxy Authentication Required [RFC7235, Section 3.2]
+@item MHD_HTTP_STATUS_REQUEST_TIMEOUT
+408: Request Timeout [RFC7231, Section 6.5.7]
+@item MHD_HTTP_STATUS_CONFLICT
+409: Conflict [RFC7231, Section 6.5.8]
+@item MHD_HTTP_STATUS_GONE
+410: Gone [RFC7231, Section 6.5.9]
+@item MHD_HTTP_STATUS_LENGTH_REQUIRED
+411: Length Required [RFC7231, Section 6.5.10]
+@item MHD_HTTP_STATUS_PRECONDITION_FAILED
+412: Precondition Failed [RFC7232, Section 4.2][RFC8144, Section 3.2]
+@item MHD_HTTP_STATUS_CONTENT_TOO_LARGE
+413: Content Too Large [RFC9110, Section 15.5.14]
+@item MHD_HTTP_STATUS_URI_TOO_LONG
+414: URI Too Long [RFC7231, Section 6.5.12]
+@item MHD_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE
+415: Unsupported Media Type [RFC7231, Section 6.5.13][RFC7694, Section 3]
+@item MHD_HTTP_STATUS_RANGE_NOT_SATISFIABLE
+416: Range Not Satisfiable [RFC7233, Section 4.4]
+@item MHD_HTTP_STATUS_EXPECTATION_FAILED
+417: Expectation Failed [RFC7231, Section 6.5.14]
+@item MHD_HTTP_STATUS_MISDIRECTED_REQUEST
+421: Misdirected Request [RFC7540, Section 9.1.2]
+@item MHD_HTTP_STATUS_UNPROCESSABLE_CONTENT
+422: Unprocessable Content [RFC9110, Sectio 15.5.21]
+@item MHD_HTTP_STATUS_LOCKED
+423: Locked [RFC4918]
+@item MHD_HTTP_STATUS_FAILED_DEPENDENCY
+424: Failed Dependency [RFC4918]
+@item MHD_HTTP_STATUS_TOO_EARLY
+425: Too Early [RFC8470]
+@item MHD_HTTP_STATUS_UPGRADE_REQUIRED
+426: Upgrade Required [RFC7231, Section 6.5.15]
+@item MHD_HTTP_STATUS_PRECONDITION_REQUIRED
+428: Precondition Required [RFC6585]
+@item MHD_HTTP_STATUS_TOO_MANY_REQUESTS
+429: Too Many Requests [RFC6585]
+@item MHD_HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE
+431: Request Header Fields Too Large [RFC6585]
+@item MHD_HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS
+451: Unavailable For Legal Reasons [RFC7725]
+@item MHD_HTTP_STATUS_INTERNAL_SERVER_ERROR
+500: Internal Server Error [RFC7231, Section 6.6.1]
+@item MHD_HTTP_STATUS_NOT_IMPLEMENTED
+501: Not Implemented [RFC7231, Section 6.6.2]
+@item MHD_HTTP_STATUS_BAD_GATEWAY
+502: Bad Gateway [RFC7231, Section 6.6.3]
+@item MHD_HTTP_STATUS_SERVICE_UNAVAILABLE
+503: Service Unavailable [RFC7231, Section 6.6.4]
+@item MHD_HTTP_STATUS_GATEWAY_TIMEOUT
+504: Gateway Timeout [RFC7231, Section 6.6.5]
+@item MHD_HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED
+505: HTTP Version Not Supported [RFC7231, Section 6.6.6]
+@item MHD_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES
+506: Variant Also Negotiates [RFC2295]
+@item MHD_HTTP_STATUS_INSUFFICIENT_STORAGE
+507: Insufficient Storage [RFC4918]
+@item MHD_HTTP_STATUS_LOOP_DETECTED
+508: Loop Detected [RFC5842]
+@item MHD_HTTP_STATUS_NOT_EXTENDED
+510: Not Extended [RFC2774]
+@item MHD_HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED
+511: Network Authentication Required [RFC6585]
+@item MHD_HTTP_STATUS_RETRY_WITH
+449: Retry with [MS IIS extension]
+@item MHD_HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED
+509: Bandwidth Limit Exceeded [Apache extension]
+@item MHD_HTTP_STATUS_UNINITIALIZED
+0: No status code, used if no HTTP status is available (uninitialized) [None]
diff --git a/doc/manual/init.inc b/doc/manual/init.inc
index 284a38c..688ef06 100644
--- a/doc/manual/init.inc
+++ b/doc/manual/init.inc
@@ -59,8 +59,6 @@ closure argument for @var{cb}; the other arguments are the
name of the source fi
@node libmicrohttpd-init-create
@section Creating an HTTP daemon
-The @code{MHD_daemon_create()} function creates an @code{struct MHD_Daemon}.
-
@deftp {C Struct} MHD_Daemon
Handle for an HTTP daemon. A daemon contains the MHD configuration
and state to listening on a socket for HTTP clients and handle
@@ -70,6 +68,8 @@ their requests.
An application can in principle create multiple daemons, for example
to listen on both port 80 and port 443. Each daemon handles request
from at most one @code{listen()} socket.
+The @code{MHD_daemon_create()} function is used by applications to
+create a @code{struct MHD_Daemon}.
@deftypefun {struct MHD_Daemon *} MHD_daemon_create (MHD_RequestCallback
req_cb, void *req_cb_cls)
Create a new HTTP daemon object. Does not actually start
@@ -90,18 +90,9 @@ When creating an HTTP daemon the application must pass the
address of
a function of type @code{MHD_RequestCallback} which MHD will call for
each HTTP request that daemon receives from the network.
-@deftypefn {Function Pointer} struct MHD_Action * {*MHD_RequestCallback} (void
*cls, struct MHD_Request *request, const struct MHD_String *path, enum
MHD_HTTP_Method method, uint_fast64_t upload_size)
+@deftypefn {Function Pointer} struct MHD_Action * (*MHD_RequestCallback) (void
*cls, struct MHD_Request *request, const struct MHD_String *path, enum
MHD_HTTP_Method method, uint_fast64_t upload_size)
Functions of this type are invoked by MHD whenever it received an HTTP
-request and needs to handle it. Implementations must call MHD
-functions to create a @code{struct MHD_Action} which informs MHD about
-the next steps to take to handle the request.
-
-@ref{libmicrohttpd-actions} explains in more detail how to create the
-various possible actions. It is also possible to return @code{NULL},
-in which case MHD will close the HTTP connection without returning
-anything (not even an error message). This can be used if the socket
-must be closed due to a serious error while handling the request (such
-as being out-of-memory).
+request and needs to handle it.
@table @var
@item cls
@@ -121,6 +112,18 @@ in the request body; a special value of
@code{MHD_SIZE_UNKNOWN}
is provided if the client indicated the use of chunked encoding
and the final upload size is not yet known;
@end table
+
+The returned @code{struct MHD_Action} determines how MHD should continue
+handling the request. Implementations must call MHD
+functions to create a @code{struct MHD_Action} which then determines
+the next steps.
+
+@ref{libmicrohttpd-actions} explains in more detail how to create
+various possible actions. It is also possible to return @code{NULL},
+in which case MHD will close the HTTP connection without returning
+anything (not even an error message). This can be used if the socket
+must be closed due to a serious error while handling the request (such
+as being out-of-memory).
@end deftypefn
The HTTP @var{method} is not provided as a string as comparing
@@ -285,3 +288,14 @@ resources still associated with the daemon.
Handle to the HTTP daemon to destroy.
@end table
@end deftypefun
+
+
+@node libmicrohttpd-init-example
+@section Example: Starting with GNU libmicrohttpd
+
+The following is a minimal starting point for implementing
+an application that uses MHD to add an HTTP server:
+
+@example c
+@verbatiminclude examples/init-example.c
+@end example
\ No newline at end of file
diff --git a/doc/manual/introduction.inc b/doc/manual/introduction.inc
index 633056e..1508973 100644
--- a/doc/manual/introduction.inc
+++ b/doc/manual/introduction.inc
@@ -292,10 +292,10 @@ a @code{struct MHD_StringNullable}.
@deftp {C Struct} MHD_String len cstr
Represents a string. The pointer is never NULL.
-@table @code
-@item len
+@table @var
+@item @code{size_t} len
Number of characters in @var{str}, not counting 0-termination.
-@item cstr
+@item @code{const char *} cstr
0-terminated C-string. Guaranteed to not be NULL.
@end table
@end deftp
@@ -303,9 +303,9 @@ Number of characters in @var{str}, not counting
0-termination.
@deftp {C Struct} MHD_StringNullable len cstr
Represents a string that could also be NULL.
@table @code
-@item len
+@item @code{size_t} len
Number of characters in @var{str}, not counting 0-termination.
-@item cstr
+@item @code{const char *} cstr
0-terminated C-string. Could be NULL in some cases.
@end table
@end deftp
diff --git a/doc/manual/responses.inc b/doc/manual/responses.inc
index 7249426..06b404e 100644
--- a/doc/manual/responses.inc
+++ b/doc/manual/responses.inc
@@ -1,25 +1,46 @@
@noindent
Response objects handling by MHD is asynchronous with respect to the
-application execution flow. Instances of the @code{MHD_Response}
-structure are not associated to a daemon and neither to a client
-connection: they are managed with reference counting.
+application execution flow. Instances of the @code{struct MHD_Response}
+structure are not associated to a daemon or a daemon;
+they are managed with reference counting.
-In the simplest case: we allocate a new @code{MHD_Response} structure
-for each response, we use it once and finally we destroy it.
+In the simplest case we allocate a new @code{struct MHD_Response} structure
+for each response, use it to create an action and it is (automatically)
+destroyed:
-MHD allows more efficient resources usages.
+@example
+struct MHD_Action *
+simple_reply_to_request (struct MHD_Request *request)
+{
+ const char *data = "<html><body><p>Error!</p></body></html>";
+
+ return MHD_action_from_response (
+ request,
+ MHD_response_from_buffer_static (
+ MHD_HTTP_STATUS_NOT_FOUND,
+ strlen(data),
+ data);
+ );
+}
+@end example
-Example: we allocate a new @code{MHD_Response} structure for each
-response @strong{kind}, we use it every time we have to give that
-response and we finally destroy it only when the daemon shuts down.
+The above code will cause MHD to @code{close()} a connection in
+case the memory allocation failed (and log nothing), but unless
+an application really needs to handle even such an error more
+gracefully, the above code is already fine even in terms of
+error handling and leaks no memory (assuming the action is
+returned to MHD).
+
+However, MHD also allows responses to be reused and the same response
+structure to be used multiple times. This is explained in more detail
+in the chapter on setting response options.
@menu
-* microhttpd-response enqueue:: Enqueuing a response.
-* microhttpd-response create:: Creating a response object.
+* microhttpd-response enqueue:: Returning a response.
+* microhttpd-response create:: Creating responses.
* microhttpd-response headers:: Adding headers to a response.
* microhttpd-response options:: Setting response options.
-* microhttpd-response inspect:: Inspecting a response object.
* microhttpd-response upgrade:: Creating a response for protocol upgrades.
@end menu
@@ -29,359 +50,760 @@ response and we finally destroy it only when the daemon
shuts down.
@node microhttpd-response enqueue
@section Enqueuing a response
+As we have discussed in the previous chapters and shown in the example
+above, handling a request requires applications to return a
+@code{struct MHD_Action} that tells MHD how to continue. The most
+common way to create an action is from a @code{struct MHD_Response}
+via @code{MHD_action_from_response}.
-@deftypefun enum MHD_Result MHD_queue_response (struct MHD_Connection
*connection, unsigned int status_code, struct MHD_Response *response)
-Queue a response to be transmitted to the client as soon as possible
-but only after MHD_AccessHandlerCallback returns. This function
-checks that it is legal to queue a response at this time for the
-given connection. It also increments the internal reference
-counter for the response object (the counter will be decremented
-automatically once the response has been transmitted).
+@deftypefun struct MHD_Action * MHD_action_from_response (struct MHD_Request
*request, struct MHD_Response *response)
+This instructs MHD to transmit the given @var{response} to
+the client. The @var{request} must match the request handle
+given to the call that is returning the action.
@table @var
-@item connection
-the connection identifying the client;
-
-@item status_code
-HTTP status code (i.e. @code{200} for OK);
+@item request
+the request to create an action for;
@item response
-response to transmit.
+the response to convert. If this argument is NULL then this
+function will behave equivalent to @code{MHD_action_abort_connection()}.
@end table
-Return @code{MHD_YES} on success or if message has been queued. Return
-@code{MHD_NO}: if arguments are invalid (example: @code{NULL} pointer); on
-error (i.e. reply already sent).
+Returns an action on success. The action returned must be returned to
+MHD, otherwise there @emph{may} be a memory leak. This function
+checks that no other action was already created for the given
+@var{request} and returns @code{NULL} on API usage errors or possibly
+in out-of-memory situations. The application @emph{may} try to create
+a different action in this case, but most likely should just give MHD
+the @code{NULL} value for the action to close the connection.
+
@end deftypefun
+Note that calling @code{MHD_action_from_response()} will typically
+consume a response object and cause its resources to be released
+by MHD once the response has been sent. Thus, after converting
+a response to an action applications do not have to call
+@code{MHD_response_destroy()} @emph{unless} they used
+@code{MHD_R_OPTION_REUSABLE} as explained below.
+
-@deftypefun void MHD_destroy_response (struct MHD_Response *response)
-Destroy a response object and associated resources (decrement the
+@node microhttpd-response create
+@section Creating responses
+
+@cindex lifetime
+@subsection Destroying responses
+
+There are various ways for applications to create a @code{struct
+MHD_Response}. Almost all of these functions will have to allocate
+memory and may fail, returning @code{NULL} to indicate that the
+response generation failed. To avoid leaking memory, any response that
+was successfull created must @emph{either} be converted into an action
+via @code{MHD_action_from_response()} or explicitly destroyed via
+@code{MHD_response_destroy()}.
+
+@deftypefun void MHD_response_destroy (struct MHD_Response *response)
+Destroys a response object and associated resources (decrement the
reference counter). Note that MHD may keep some of the resources
around if the response is still in the queue for some clients, so the
memory may not necessarily be freed immediately.
+
+@table @var
+@item response
+the response to destroy.
+@end table
@end deftypefun
+@subsection HTTP status codes
-An explanation of reference counting@footnote{Note to readers acquainted
-to the Tcl API: reference counting on @code{MHD_Connection}
-structures is handled in the same way as Tcl handles @code{Tcl_Obj}
-structures through @code{Tcl_IncrRefCount()} and
-@code{Tcl_DecrRefCount()}.}:
+When creating a response object, you must always specify the HTTP
+status code that should be returned with the response. MHD provides
+@code{enum MHD_HTTP_StatusCode} with all supported HTTP status
+codes. Using other numeric values is possible but not advised: in such
+cases MHD will be unable to provide the human-readable status code
+description and clients are likely to be unhappy about the use of
+non-standard codes.
-@enumerate
-@item
-a @code{MHD_Response} object is allocated:
-@example
-struct MHD_Response * response = MHD_create_response_from_buffer(...);
-/* here: reference counter = 1 */
-@end example
+@deftp {Enumeration} MHD_HTTP_StatusCode
-@item
-the @code{MHD_Response} object is enqueued in a @code{MHD_Connection}:
+Represents canonical HTTP status codes.
-@example
-MHD_queue_response(connection, , response);
-/* here: reference counter = 2 */
-@end example
+@table @code
+@include manual/http-status-texi.gen
+@end table
+@end deftp
-@item
-the creator of the response object discharges responsibility for it:
-@example
-MHD_destroy_response(response);
-/* here: reference counter = 1 */
-@end example
+@subsection Responses from memory buffers
-@item
-the daemon handles the connection sending the response's data to the
-client then decrements the reference counter by calling
-@code{MHD_destroy_response()}: the counter's value drops to zero and
-the @code{MHD_Response} object is released.
-@end enumerate
+You can use any of the following functions (or convenience macros)
+to create responses from static data in memory:
+@deftypefun {struct MHD_Response *} MHD_response_from_buffer (enum
MHD_HTTP_StatusCode sc, size_t buffer_size, const char *buffer,
MHD_FreeCallback free_cb, void *free_cb_cls)
+Create a response object with a callback that can be used to free resources
after the response has been sent to the client.
-@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+@table @var
+@item sc
+HTTP status code for the response.
-@c ------------------------------------------------------------
-@node microhttpd-response create
-@section Creating a response object
+@item size
+size of the data portion of the response;
+
+@item buffer
+the body to return, must contain at least @var{size} bytes of data;
+the application must ensure that data in @var{buffer} remains valid
+at least until the response was sent;
+
+@item free_cb
+function to call to release application data associated with
+the response (usually @var{buffer}) after transmitting the
+response is complete. For example, if @var{buffer} is the
+result of @code{mmap()} the callback may invoke
+@code{munmap()}. Similarly, if @var{buffer} was part of an
+allocation on the heap, the callback may simply call
+@code{free()}. You may pass @code{NULL} to indicate that
+no cleanup function is needed; however, in that case it
+might be simpler to use @code{MHD_response_from_buffer_static()}.
+
+@item free_cb_cls
+additional argument to pass to the @var{free_cb}.
+A common value to pass is @var{buffer}.
+@end table
+
+Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@end deftypefun
+
+
+@deftypefn {Function Pointer} void (*MHD_FreeCallback) (void *cls)
+Functions of this type are invoked by MHD whenever it wants to give
+the application a chance to free resources.
+
+@table @var
+@item cls
+custom value provided by the application together with the
+actual function pointer; should identify the resources to be released
+@end table
+@end deftypefn
+
+When releasing resources is unnecessary, applications can instead
+use the simplified @code{MHD_response_from_buffer_static()} API
+that simply omits the @var{free_cb} and @var{free_cb_cls} arguments.
+
+@deftypefun {struct MHD_Response *} MHD_response_from_buffer_static (enum
MHD_HTTP_StatusCode sc, size_t buffer_size, const char *buffer)
+Create a response object without the need to free resources after the response
has been sent to the client.
+
+@table @var
+@item sc
+HTTP status code for the response.
+
+@item size
+size of the data portion of the response;
+
+@item buffer
+the body to return, must contain at least @var{size} bytes of data;
+the application must ensure that data in @var{buffer} remains valid
+at least until the response was sent; can be NULL if @var{size} is zero,
+but in this case it might be simpler to use @code{MHD_response_from_empty()}.
+@end table
+Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@end deftypefun
-@deftypefun {struct MHD_Response *} MHD_create_response_from_callback
(uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void
*crc_cls, MHD_ContentReaderFreeCallback crfc)
-Create a response object. The response object can be extended with
-header information and then it can be used any number of times.
+
+@deftypefun {struct MHD_Response *} MHD_response_from_buffer_copy (enum
MHD_HTTP_StatusCode sc, size_t buffer_size, const char buffer[buffer_size])
+Create a response object from an ephemeral @var{buffer}. The data
+in the @var{buffer} will be copied into internal storage of MHD.
@table @var
+@item sc
+HTTP status code for the response.
+
@item size
-size of the data portion of the response, @code{-1} for unknown;
+size of the data portion of the response;
+
+@item buffer
+the body to return, must contain at least @var{size} bytes of data;
+the @var{buffer} can become invalid immediately after the
+call to @code{MHD_response_from_buffer_copy()} returns as MHD
+will make a copy of the data contained in it.
+@end table
-@item block_size
-preferred block size for querying @var{crc} (advisory only, MHD may
-still call @var{crc} using smaller chunks); this is essentially the
-buffer size used for @acronym{IO}, clients should pick a value that is
-appropriate for @acronym{IO} and memory performance requirements;
+Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@end deftypefun
-@item crc
-callback to use to obtain response data;
-@item crc_cls
-extra argument to @var{crc};
+@deftypefun {struct MHD_Response *} MHD_response_from_empty (enum
MHD_HTTP_StatusCode sc)
+Create an response with an empty body.
-@item crfc
-callback to call to free @var{crc_cls} resources.
+@table @var
+@item sc
+HTTP status code for the response. A common value would be
@code{MHD_HTTP_NO_CONTENT}.
@end table
Return @code{NULL} on error (i.e. invalid arguments, out of memory).
@end deftypefun
+Finally, in rare cases, the response data may not be available in a
+continuous block in memory and it might be more efficient to not copy
+the data into a continous area just for the network transfer (or
+encryption). In this case, applications can initialize an array of
+@code{struct MHD_IoVec} data structures and use
+@code{MHD_response_from_iovec()} to point MHD to the various fragments
+of the body and enable (if supported) the kernel (or NIC) to assemble
+the final response dynamcially from the fragments in
+memory.@footnote{See the @code{writev()} POSIX call for an example of
+the type of scatter input operationg system interface that MHD might
+use to implement this.}
+
+@deftypefun {struct MHD_Response *} MHD_response_from_iovec (enum
MHD_HTTP_StatusCode sc, unsigned int iov_count, const struct MHD_IoVec
iov[iov_count], MHD_FreeCallback free_cb, void *free_cb_cls)
+Create a response object from an array of memory buffers.
+@table @var
+@item sc
+HTTP status code for the response.
+@item iov_count
+the number of elements in @var{iov};
-@deftypefun {struct MHD_Response *} MHD_create_response_from_fd (uint64_t
size, int fd)
-Create a response object. The response object can be extended with
-header information and then it can be used any number of times.
+@item iov
+the array for response data buffers of length @var{iov_count}, an internal
copy of the @var{iov} will be made; however, note that the data pointed to by
the @var{iov} is @strong{not} copied and must be preserved unchanged at the
given locations until the response is no longer in use and the @var{free_cb} is
called;
+
+@item free_cb
+the callback to call to free resources associated with @var{iov};
+You may pass @code{NULL} to indicate that no cleanup function is needed.
+@item free_cb_cls
+additional argument to pass to the @var{free_cb}.
+@end table
+
+Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@end deftypefun
+
+
+@deftp {C Struct} MHD_IoVec
+Input/output vector type. Informations MHD about a fragment of
+data in memory for assembly as part of an HTTP response body.
@table @var
-@item size
-size of the data portion of the response (should be smaller or equal to the
-size of the file)
+@item @code{const void *} iov_base
+Pointer to the memory region for I/O.
+@item @code{size_t} iov_len
+The size (in bytes) of the memory region pointed to by @var{iov_base}.
+@end table
+@end deftp
+
+
+@subsection Responses from file descriptors
+
+@deftypefun {struct MHD_Response *} MHD_response_from_fd (enum
MHD_HTTP_StatusCode sc, int fd, uint_fast64_t offset, uint_fast64_t size)
+Create a response object based on a file descriptor @var{fd} from
+which the body is supposed to be read.
+
+@table @var
+@item sc
+HTTP status code for the response.
@item fd
-file descriptor referring to a file on disk with the data; will be
-closed when response is destroyed; note that 'fd' must be an actual
-file descriptor (not a pipe or socket) since MHD might use 'sendfile'
-or 'seek' on it. The descriptor should be in blocking-IO mode.
+file descriptor referring to a file on disk with the
+data; MHD will @code{close()} the file descriptor when
+the response is destroyed; @var{fd} should be in @emph{blocking} mode;
+@var{fd} must be an actual file descriptor (not a pipe or socket)
+since MHD might use @code{sendfile()} or @code{seek()} on it;
+
+@item offset
+offset to start reading from in the file;
+readings file beyond 2 GiB may be not supported by some
+operationg systems or MHD builds.
+@xref{MHD_LIB_INFO_FIXED_HAS_LARGE_FILE}.
+
+@item size
+size size of the data portion of the response;
+sizes larger than 2 GiB may be not supported by
+some operating systems or MHD builds.
+@xref{MHD_LIB_INFO_FIXED_HAS_LARGE_FILE}.
@end table
-Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+Returns @code{NULL} on error (i.e. invalid arguments, out of memory).
+@c FIXME: closes fd on error?
@end deftypefun
-@deftypefun {struct MHD_Response *} MHD_create_response_from_pipe (int fd)
-Create a response object. The response object can be extended with
-header information and then it can be used ONLY ONCE.
+@deftypefun {struct MHD_Response *} MHD_response_from_pipe (enum
MHD_HTTP_StatusCode sc, int fd)
+Create a response object where the response body is created by reading from
+the provided pipe.
@table @var
+@item sc
+HTTP status code for the response.
+
@item fd
-file descriptor of the read-end of the pipe; will be
+file descriptor of the read-end of a pipe; will be
closed when response is destroyed.
The descriptor should be in blocking-IO mode.
@end table
-Return @code{NULL} on error (i.e. out of memory).
+Returns @code{NULL} on error (i.e. out of memory).
+@c FIXME: closes fd on error?
@end deftypefun
-@deftypefun {struct MHD_Response *} MHD_create_response_from_fd_at_offset
(size_t size, int fd, off_t offset)
-Create a response object. The response object can be extended with
-header information and then it can be used any number of times.
-Note that you need to be a bit careful about @code{off_t} when
-writing this code. Depending on your platform, MHD is likely
-to have been compiled with support for 64-bit files. When you
-compile your own application, you must make sure that @code{off_t}
-is also a 64-bit value. If not, your compiler may pass a 32-bit
-value as @code{off_t}, which will result in 32-bits of garbage.
-
-If you use the autotools, use the @code{AC_SYS_LARGEFILE} autoconf
-macro and make sure to include the generated @file{config.h} file
-before @file{microhttpd.h} to avoid problems. If you do not have a
-build system and only want to run on a GNU/Linux system, you could
-also use
-@verbatim
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <microhttpd.h>
-@end verbatim
-to ensure 64-bit @code{off_t}. Note that if your operating system
-does not support 64-bit files, MHD will be compiled with a 32-bit
-@code{off_t} (in which case the above would be wrong).
+@subsection Responses from dynamic generators
+
+This API is useful for applications that dynamically create the
+response body, possibly even with significant delays between
+chunks. This is also the only API that applications can use to
+return responses for which they do not know the length up-front.
+
+@deftypefun {struct MHD_Response *} MHD_response_from_callback (enum
MHD_HTTP_StatusCode sc, uint_fast64_t size, MHD_DynamicContentCreator dyn_cont,
void *dyn_cont_cls, MHD_FreeCallback dyn_cont_fc)
+Create a response object with a body that will be yielded over
+time by the @code{dyn_cont} callback.
@table @var
+@item sc
+HTTP status code for the response.
+
@item size
-size of the data portion of the response (number of bytes to transmit from the
-file starting at offset).
+size of the body of the response, applications should pass
+@code{MHD_SIZE_UNKNOWN} if the size of the body is not yet known;
-@item fd
-file descriptor referring to a file on disk with the data; will be
-closed when response is destroyed; note that 'fd' must be an actual
-file descriptor (not a pipe or socket) since MHD might use 'sendfile'
-or 'seek' on it. The descriptor should be in blocking-IO mode.
+@item dyn_cont
+callback that MHD will use to obtain the response body
-@item offset
-offset to start reading from in the file
+@item dyn_cont_cls
+extra argument that MHD will pass to @var{dyn_cont} and
+@var{dyn_cont_fc}
+
+@item dyn_cont_fc
+callback that MHD will call to allow the application to
+free resources associated with @var{dyn_cont_cls}.
@end table
Return @code{NULL} on error (i.e. invalid arguments, out of memory).
@end deftypefun
+The interesting work for dynamic response generation happens in the
+dynamic content creation callback, which must be a function of
+type @code{MHD_DynamicContentCreator}.
-@deftypefun {struct MHD_Response *} MHD_create_response_from_buffer (size_t
size, void *data, enum MHD_ResponseMemoryMode mode)
-Create a response object. The response object can be extended with
-header information and then it can be used any number of times.
+@deftypefn {Function Pointer} struct MHD_DynamicContentCreatorAction *
(*MHD_DynamicContentCreator) (void *dyn_cont_cls, struct
MHD_DynamicContentCreatorContext *ctx, uint_fast64_t pos, void *buf, size_t max)
@table @var
-@item size
-size of the data portion of the response;
+@item dyn_cont_cls
+closure argument that was associated with the callback
+
+@item ctx
+the context to produce the action to return;
+the pointer is only valid until the callback returns;
+equivalent to the @var{request} argument given to
+functions of type @code{MHD_RequestCallback};
+
+@item pos
+position in the datastream to access;
+note that if a @code{struct MHD_Response} is re-used,
+it is possible for the same dynamic content creator to
+be queried multiple times for the same data;
+however, if a @code{struct MHD_Response} is not re-used,
+libmicrohttpd guarantees that @var{pos} will be
+the sum of all data sizes previously yielded by this callback
+
+@item buf
+buffer where the application may write data that should be
+included in the body at offset @var{pos}; @var{buf} has
+@var{max} bytes available;
+
+@item max
+maximum number of bytes the application may copy to @var{buf};
+if the size of the content of the response is known then the
+size of the buffer is never larger than amount of data left
+@end table
-@item buffer
-the data itself;
-
-@item mode
-memory management options for buffer; use
-MHD_RESPMEM_PERSISTENT if the buffer is static/global memory,
-use MHD_RESPMEM_MUST_FREE if the buffer is heap-allocated and
-should be freed by MHD and MHD_RESPMEM_MUST_COPY if the
-buffer is in transient memory (i.e. on the stack) and must
-be copied by MHD;
+Most importantly, the callback must also return a
+@code{struct MHD_DynamicContentCreatorAction} which determines
+the next step in creating the body. Applications may
+return @code{NULL} in which case response generation will
+be aborted and MHD will @code{close()} the connection.
+@end deftypefn
+
+@deftp {C Struct} MHD_DynamicContentCreatorAction
+Special type of action that must be returned by a
+@code{MHD_DynamicContentCreator}.
+@end deftp
+
+Various possibilities exist for applications to create
+an @code{struct MHD_DynamicContentCreatorAction} (DCC action). Note
+that at most one @code{struct MHD_DynamicContentCreatorAction}
+can be created per @var{ctx}.
+
+We begin with DCC actions that end the process of
+dynamic response generation:
+
+@deftypefun {struct MHD_DynamicContentCreatorAction *} MHD_DCC_action_abort
(struct MHD_DynamicContentCreatorContext *ctx)
+
+Aborts handling the request by closing the connection. This
+is actually simply a macro that is equivalent to just @code{NULL},
+except that it also suggests to the compiler that it it should
+not emit a warning for not using @var{ctx}.
+
+@end deftypefun
+
+@deftypefun {struct MHD_DynamicContentCreatorAction *} MHD_DCC_action_finish
(struct MHD_DynamicContentCreatorContext *ctx)
+
+Create a "finished" action that signals MHD that the dynamic content creation
+is finished. Note that this will cause MHD to @code{close()} the connection
+if the amount of data yielded by the content creation logic is less than
+the @var{size} promised to @code{MHD_response_from_callback()}.
+
+@table @var
+@item ctx
+context that was given to the @code{MHD_DynamicContentCreator} for
+which a @code{struct MHD_DynamicContentCreatorAction} should be generated.
@end table
-Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@code{NULL} is returned in case of any error.
@end deftypefun
-@deftypefun {struct MHD_Response *}
MHD_create_response_from_buffer_with_free_callback (size_t size, void *data,
MHD_ContentReaderFreeCallback crfc)
-Create a response object. The buffer at the end must be free'd
-by calling the @var{crfc} function.
+HTTP has not only headers, but also the lesser-known concept of
+@emph{footers}. Applications can specify footers (for example,
+to append a checksum after dynamic content creation) using
+@code{MHD_DCC_action_finish_with_footer()}.
+
+@deftypefun {struct MHD_DynamicContentCreatorAction *}
MHD_DCC_action_finish_with_footer (struct MHD_DynamicContentCreatorContext
*ctx, size_t num_footers, const struct MHD_NameValueCStr *footers)
+
+Create a "finished" action that signals MHD that the dynamic content creation
+is finished. Note that this will cause MHD to @code{close()} the connection
+if the amount of data yielded by the content creation logic is less than
+the @var{size} promised to @code{MHD_response_from_callback()}.
@table @var
-@item size
-size of the data portion of the response;
+@item ctx
+context that was given to the @code{MHD_DynamicContentCreator} for
+which a @code{struct MHD_DynamicContentCreatorAction} should be generated;
-@item buffer
-the data itself;
+@item num_footers
+length of the @var{footers} array;
-@item crfc
-function to call at the end to free memory allocated at @var{buffer}.
+@item footers
+array of @var{num_footers} HTTP footers to return.
@end table
-Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@code{NULL} is returned in case of any error.
@end deftypefun
-@deftypefun {struct MHD_Response *} MHD_create_response_from_data (size_t
size, void *data, int must_free, int must_copy)
-Create a response object. The response object can be extended with
-header information and then it can be used any number of times.
-This function is deprecated, use @code{MHD_create_response_from_buffer}
instead.
+The @var{footers} are provided as key-value pairs of 0-terminated C strings
+in a @code{struct MHD_NameValueCStr}. In this context, both members must
+not be @code{NULL}.
+@deftp {C Struct} MHD_NameValueCStr name value
+Name with value pair as C strings.
@table @var
-@item size
-size of the data portion of the response;
+@item @code{const char *} name
+The name or key of the field. Must never be @code{NULL}.
+@item @code{const char *} value
+The value to be returned under the name or key.
+In some cases, @var{value} is allowed to be absent,
+which is indicated by a @code{NULL} pointer.
+@end table
+@end deftp
-@item data
-the data itself;
+@cindex long-polling
-@item must_free
-if true: MHD should free data when done;
+Applications may not want to finish generating a response, but also
+may not (yet) have more data to return to the client. In this case,
+applications must @emph{suspend} response generation. This is done
+using @code{MHD_DCC_action_suspend()}.
-@item must_copy
-if true: MHD allocates a block of memory and use it to make a copy of
-@var{data} embedded in the returned @code{MHD_Response} structure;
-handling of the embedded memory is responsibility of MHD; @var{data}
-can be released anytime after this call returns.
+@deftypefun {struct MHD_DynamicContentCreatorAction *} MHD_DCC_action_suspend
(struct MHD_DynamicContentCreatorContext *ctx)
+
+Creates a DCC action that suspends response generation. The connection
+is not closed! MHD merely waits for the application to resume response
+generation via a call to @code{MHD_request_resume()}. This is
+especially useful for long-polling where response generation is not
+computationally bound. This is common in cases where client and server
+need to wait (possibly for an extended period of time) on some
+external event to happen before the server can generate a response.
+
+@table @var
+@item ctx
+context that was given to the @code{MHD_DynamicContentCreator} for
+which a @code{struct MHD_DynamicContentCreatorAction} should be generated;
@end table
-Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@code{NULL} is returned in case of any error.
@end deftypefun
+After dynamic content creation was suspended with
+@code{MHD_DCC_action_suspend()}, applications @strong{must}
+(eventually) call @code{MHD_request_resume()} to continue
+processing the client's request.
-Example: create a response from a statically allocated string:
+@cindex long-polling
+@deftypefun void MHD_request_resume (struct MHD_Request *request)
-@example
-const char * data = "<html><body><p>Error!</p></body></html>";
+Resume handling of network data for suspended request. It is
+safe to resume a suspended request at any time. Calling this
+function on a request that was not previously suspended will
+result in undefined behaviour.
-struct MHD_Connection * connection = ...;
-struct MHD_Response * response;
+If you are using this function in ``external'' select mode
+(@xref{libmicrohttpd-threadmodes}), you must
+additionally make sure to call @code{MHD_daemon_process_blocking()}
+afterwards! Otherwise the change may not be reflected in the set
+returned to your @code{MHD_SocketRegistrationUpdateCallback} and the
+application may end up with a request that is stuck until the next
+network activity.
-response = MHD_create_response_from_buffer (strlen(data), data,
- MHD_RESPMEM_PERSISTENT);
-MHD_queue_response(connection, 404, response);
-MHD_destroy_response(response);
-@end example
+@table @var
+@item request
+identifies the request to resume
+@end table
+@end deftypefun
-@deftypefun {struct MHD_Response *} MHD_create_response_from_iovec (const
struct MHD_IoVec *iov, int iovcnt, MHD_ContentReaderFreeCallback crfc, void
*cls)
-Create a response object from an array of memory buffers.
-The response object can be extended with header information and then be used
-any number of times.
+Finally, we consider DCC actions that can be used to signal MHD data to be
+returned in the MHD body.
+
+@deftypefun {struct MHD_DynamicContentCreatorAction *} MHD_DCC_action_continue
(struct MHD_DynamicContentCreatorContext *ctx, size_t data_size)
+
+Creates an action that indicates that a chunk of @var{data_size} bytes
+was provided in the @var{buf} that MHD provided to the
+@code{MHD_DynamicContentCreator} callback
+and that MHD should continue to call the content generator for more
+(as soon as MHD has more buffer space available).
+
@table @var
-@item iov
-the array for response data buffers, an internal copy of this will be made;
however, note that the data pointed to by the @var{iov} is not copied and must
be preserved unchanged at the given locations until the response is no longer
in use and the @var{crfc} is called;
+@item ctx
+context that was given to the @code{MHD_DynamicContentCreator} for
+which a @code{struct MHD_DynamicContentCreatorAction} should be generated;
-@item iovcnt
-the number of elements in @var{iov};
+@item data_size
+number of bytes that were written by the application into @var{buf};
+must be non-zero;
+@end table
-@item crfc
-the callback to call to free resources associated with @var{iov};
+@code{NULL} is returned in case of any error.
+@end deftypefun
-@item cls
-the argument to @var{crfc};
+A small variation of the above API can be used to associate
+a chunk-extension (see RFC 9112, 7.1) with the chunk:
+
+@deftypefun {struct MHD_DynamicContentCreatorAction *}
MHD_DCC_action_continue_ce (struct MHD_DynamicContentCreatorContext *ctx,
size_t data_size, const char *chunk_ext)
+
+Creates an action that indicates that a chunk of @var{data_size} bytes
+was provided in the @var{buf} that MHD provided to the
+@code{MHD_DynamicContentCreator} callback
+and that MHD should continue to call the content generator for more
+(as soon as MHD has more buffer space available).
+Furthermore, the chunk of data that was returned is optionally
+associated with a chunk-extension (@var{ce}) that MHD should
+include in the transmission if possible.
+
+@table @var
+@item ctx
+context that was given to the @code{MHD_DynamicContentCreator} for
+which a @code{struct MHD_DynamicContentCreatorAction} should be generated;
+
+@item data_size
+number of bytes that were written by the application into @var{buf};
+must be non-zero;
+
+@item chunk_ext
+optional pointer to a chunk extension string;
+can be @code{NULL} to not use chunk extension,
+ignored if chunked encoding is not used by MHD
+(say because the client is using HTTP/1.0 and
+the connection is only used for a single request).
@end table
-Return @code{NULL} on error (i.e. invalid arguments, out of memory).
+@code{NULL} is returned in case of any error.
@end deftypefun
+While writing new data that an application may dynamically generate
+directly into MHD's @var{buf} is usually ideal, copying existing
+data over into the buffer provided by MHD may not be ideal.
+Applications can also instruct MHD to include data from
+locations in the application's memory, and in fact it is
+possible to @emph{mix} both strategies using
+@code{MHD_DCC_action_continue_zc()}:
+@deftypefun {struct MHD_DynamicContentCreatorAction *}
MHD_DCC_action_continue_zc (struct MHD_DynamicContentCreatorContext *ctx,
size_t data_size, const struct MHD_DynContentZCIoVec *iov_data, const char
*chunk_ext)
-@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+Yields a chunk of body data to MHD with (optional) chunk-extension.
+The data is provided in the MHD buffer and/or in the zero-copy @var{iov_data}.
-@c ------------------------------------------------------------
-@node microhttpd-response headers
-@section Adding headers to a response
+If data is provided both in the MHD buffer and @var{ivo_data} then
+data in the MHD buffer sent first, following the @var{iov_data}.
+The total size of the data in the buffer and in @var{iov_data} @strong{must}
+be non-zero.
+@table @var
+@item ctx
+context that was given to the @code{MHD_DynamicContentCreator} for
+which a @code{struct MHD_DynamicContentCreatorAction} should be generated;
+
+@item data_size
+the amount of the data placed to the provided MHD buffer (@var{buf}),
+cannot be larger than provided buffer size,
+must be non-zero if @var{iov_data} is @code{NULL} or has no data;
+
+@item iov_data
+optional pointer to a vector of data fragments to send,
+must not be NULL and have non-zero bytes of data if @var{data_size}
+is zero;
+
+@item chunk_ext
+optional pointer to a chunk extension string;
+can be @code{NULL} to not use chunk extension,
+ignored if chunked encoding is not used by MHD
+(say because the client is using HTTP/1.0 and
+the connection is only used for a single request).
+@end table
+
+It is an error if the total response body size is known and the
+amount of data yielded in total by the dynamic content creation logic
+exceeds that amount. In this case, this function will fail and
+return @code{NULL}.
+
+@end deftypefun
+
+The @code{struct MHD_DynContentZCIoVec} adds cleanup logic to
+an array of @code{struct MHD_IoVec}s:
-@deftypefun enum MHD_Result MHD_add_response_header (struct MHD_Response
*response, const char *header, const char *content)
-Add a header line to the response. The strings referenced by
-@var{header} and @var{content} must be zero-terminated and they are
-duplicated into memory blocks embedded in @var{response}.
-Notice that the strings must not hold newlines, carriage returns or tab
-chars.
+@deftp {C Struct} MHD_DynContentZCIoVec
+Structure to pass various memory buffers to MHD together with
+a callback for cleaning up after MHD is done using the data.
+@table @var
+@item @code{size_t} iov_count
+The length of the @var{iov} array;
-MHD_add_response_header() prevents applications from setting a
+@item @code{const struct MHD_ioVec *} iov
+Pointer to an array of length @var{iov_count} identifying data chunks
+to return as part of the body;
+
+@item @code{MHD_FreeCallback} iov_fcb
+Function to call to free resources associated with @var{iov}.
+Can be @code{NULL} if releasing these resources is not necessary
+after finishing the response generation;
+
+@item @code{void *} iov_fcb_cls
+Parameter to pass to @var{iov_fcb}.
+@end table
+
+@end deftp
+
+
+@node microhttpd-response headers
+@section Adding headers to a response
+
+After creating a response, but @emph{before} using it to create an
+@code{struct MHD_Action}, applications may add custom HTTP headers
+to a response. Note that MHD will automatically set some common
+HTTP headers, in particular ``Content-Length'', ``Transfer-Encoding'',
+``Date`` and ``Connection''.
+
+@code{MHD_response_add_header()} prevents applications from setting a
``Transfer-Encoding'' header to values other than ``identity'' or
``chunked'' as other transfer encodings are not supported by MHD. Note
-that usually MHD will pick the transfer encoding correctly
-automatically, but applications can use the header to force a
+that usually MHD will pick the correct transfer encoding
+automatically; however, applications can use the header to force a
+particular behavior.
+
+@code{MHD_response_add_header()} prevents applications from setting a
+``Connection'' header to values other than ``close'' or
+``keep-alive''. Note that usually MHD will pick a sane value
+automatically; however, applications can use the header to force a
particular behavior.
MHD_add_response_header() also prevents applications from setting a
-``Content-Length'' header. MHD will automatically set a correct
-``Content-Length'' header if it is possible and allowed.
+``Content-Length'' header unless special options are set for the
+response (@xref{microhttpd-response options}) as MHD will
+automatically set a correct ``Content-Length'' header if it is
+possible and allowed by the HTTP protocol.
-Return @code{MHD_NO} on error (i.e. invalid header or content format or
-memory allocation error).
+
+@deftypefun enum MHD_StatusCode MHD_response_add_header (struct MHD_Response
*response, const char *name, const char *value)
+Add a header line to the response.
+
+@table @var
+@item response
+which response to add a header for, @code{NULL} is tolerated;
+
+@item name
+the name of the header to add,
+an internal copy of the string will be made;
+
+@item value
+the value of the header to add
+ an internal copy of the string will be made.
+@end table
+
+Notice that both strings must not contain newlines, carriage returns or
+tabulator characters. On success @code{MHD_SC_OK} is returned.
@end deftypefun
-@deftypefun enum MHD_Result MHD_add_response_footer (struct MHD_Response
*response, const char *footer, const char *content)
-Add a footer line to the response. The strings referenced by
-@var{footer} and @var{content} must be zero-terminated and they are
-duplicated into memory blocks embedded in @var{response}.
+HTTP2 introduced @emph{predefined} (standard) HTTP headers. For such
+headers, it is (slightly) more efficient to set the headers using
+values from the @code{enum MHD_PredefinedHeader} instead of specifying
+the name as a string.@footnote{The main reason being that HTTP2 can
+encode these headers using a number instead of a string, and by having
+the application directly provide the numeric value MHD does not have
+to map the string to the number.}
+
+@deftypefun enum MHD_StatusCode MHD_response_add_predef_header (struct
MHD_Response *response, enum MHD_PredefinedHeader stk, const char *content)
+Adds a header line to the response.
+
+@table @var
+@item response
+which response to add a header for, @code{NULL} is tolerated;
+
+@item stk
+code of the predefined header;
-Notice that the strings must not hold newlines, carriage returns or tab
-chars. You can add response footers at any time before signalling the
-end of the response to MHD (not just before calling 'MHD_queue_response').
-Footers are useful for adding cryptographic checksums to the reply or to
-signal errors encountered during data generation. This call was introduced
-in MHD 0.9.3.
+@item content
+the value of the header to add
+ an internal copy of the string will be made.
+@end table
-Return @code{MHD_NO} on error (i.e. invalid header or content format or
-memory allocation error).
+Notice that the content must not contain newlines, carriage returns or
+tabulator characters. On success @code{MHD_SC_OK} is returned.
@end deftypefun
+@deftp {Enumeration} MHD_PredefinedHeader
+
+Predefined list of canonical HTTP headers, useful for HTTP2
+header packing (HPACK).
+
+@c FIXME: the table seems rather incomplete (also in microhttpd2.h),
+@c and we should probably generate it via GANA (like HTTP status codes)
+@table @code
+@item MHD_PREDEF_ACCEPT_CHARSET
+15: ``Accept-Charset``
+@item MHD_PREDEF_ACCEPT_LANGUAGE
+17: ``Accept-Language``
+@end table
+@end deftp
+
+MHD provides a convenience function to map @code{enum MHD_PredefinedHeader}
+values to the human readable names:
+@deftypefun const struct MHD_String * MHD_predef_header_to_string (enum
MHD_PredefinedHeader stk)
+Get textual representation of the predefined header.
-@deftypefun enum MHD_Result MHD_del_response_header (struct MHD_Response
*response, const char *header, const char *content)
-Delete a header (or footer) line from the response. Return @code{MHD_NO} on
error
-(arguments are invalid or no such header known).
+@table @var
+@item stk
+code of the predefined header;
+@end table
+
+Returns a pointer to the text version, or @code{NULL} if
+@var{stk} is not known.
@end deftypefun
-@c ------------------------------------------------------------
+
+@c FIXME: TBD!
@node microhttpd-response options
-@section Setting response options
+@section Setting response options (TBD)
@deftypefun enum MHD_Result MHD_set_response_options (struct MHD_Response
*response, enum MHD_ResponseFlags flags, ...)
@@ -407,39 +829,11 @@ Return @code{MHD_NO} on error, @code{MHD_YES} on success.
@end deftypefun
-@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-@c ------------------------------------------------------------
-@node microhttpd-response inspect
-@section Inspecting a response object
-
-
-@deftypefun int MHD_get_response_headers (struct MHD_Response *response,
MHD_KeyValueIterator iterator, void *iterator_cls)
-Get all of the headers added to a response.
-
-Invoke the @var{iterator} callback for each header in the response,
-using @var{iterator_cls} as first argument. Return number of entries
-iterated over. @var{iterator} can be @code{NULL}: in this case the function
-just counts headers.
-
-@var{iterator} should not modify the its key and value arguments, unless
-we know what we are doing.
-@end deftypefun
-
-
-@deftypefun {const char *} MHD_get_response_header (struct MHD_Response
*response, const char *key)
-Find and return a pointer to the value of a particular header from the
-response. @var{key} must reference a zero-terminated string
-representing the header to look for. The search is case sensitive.
-Return @code{NULL} if header does not exist or @var{key} is @code{NULL}.
-
-We should not modify the value, unless we know what we are doing.
-@end deftypefun
-@c ------------------------------------------------------------
+@c FIXME: TBD!
@node microhttpd-response upgrade
-@section Creating a response for protocol upgrades
+@section Creating a response for protocol upgrades (TBD)
@cindex WebSockets
@cindex Upgrade
@cindex HTTP2
@@ -533,4 +927,3 @@ Disable corking on the underlying socket.
@end table
@end deftp
-
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libmicrohttpd2] branch master updated: work on manual,
Admin <=