[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd2] branch master updated: more chapters
From: |
Admin |
Subject: |
[libmicrohttpd2] branch master updated: more chapters |
Date: |
Thu, 13 Feb 2025 00:05:21 +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 924a42c more chapters
924a42c is described below
commit 924a42cd01ac5055b077d72d4e5ec771112879bc
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Feb 13 00:05:15 2025 +0100
more chapters
---
doc/examples/host-example.c | 55 ++++
doc/libmicrohttpd2.texi | 32 ++-
doc/manual/actions.inc | 387 ++++++++++++++++++++++++++
doc/manual/init.inc | 1 +
doc/manual/introduction.inc | 2 +
doc/manual/requests.inc | 649 ++++++++++++++++++++++++++++++++++++++++----
doc/manual/responses.inc | 6 +
7 files changed, 1065 insertions(+), 67 deletions(-)
diff --git a/doc/examples/host-example.c b/doc/examples/host-example.c
new file mode 100644
index 0000000..c27f9a2
--- /dev/null
+++ b/doc/examples/host-example.c
@@ -0,0 +1,55 @@
+#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)
+{
+ struct MHD_String *host;
+
+ /* We passed NULL in main() for the closure */
+ assert (NULL == cls);
+ /* MHD_HTTP_HEADER_HOST is literally just "Host" */
+ host = MHD_request_get_value (request,
+ MHD_VK_HEADER,
+ MHD_HTTP_HEADER_HOST);
+ if (NULL == host)
+ {
+ /* In HTTP/1.0, the 'Host' header was optional! */
+ fprintf (stderr,
+ "No 'Host:' header provided\n");
+ }
+ else
+ {
+ fprintf (stderr,
+ "'Host:' is %s\n",
+ host->cstr);
+ }
+ /* 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 b000f39..a5b9ddd 100644
--- a/doc/libmicrohttpd2.texi
+++ b/doc/libmicrohttpd2.texi
@@ -59,13 +59,14 @@ Free Documentation License".
* libmicrohttpd2-doptions:: Configuring your HTTP server.
* libmicrohttpd2-threadmodes:: Using different thread modes.
* libmicrohttpd2-requests:: Accessing client request data.
-* libmicrohttpd2-action:: Acting on HTTP requests.
+* libmicrohttpd2-actions:: Acting on HTTP requests.
* libmicrohttpd2-responses:: Generating HTTP responses.
* libmicrohttpd2-auth:: Utilizing HTTP authentication.
* libmicrohttpd2-post:: Parsing @code{POST} data.
* libmicrohttpd2-upgrade:: Upgrading HTTP/1.1 connections.
* libmicrohttpd2-introspection:: Obtaining status information.
* libmicrohttpd2-util:: Utilities.
+* libmicrohttpd2-migration:: Migration from GNU libmicrohttpd 1.0.
* libmicrohttpd2-flow:: Flow control?
Appendices
@@ -93,23 +94,30 @@ Indices
@chapter Starting and stopping the HTTP server
@include manual/init.inc
+@node libmicrohttpd2-requests
+@chapter Accessing client request data
+@include manual/requests.inc
+
+@node libmicrohttpd2-actions
+@chapter Reacting to HTTP requests with actions
+@include manual/actions.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 - thread modes [Do]
+@c - post [Fr]
+@c - auth [Sa]
+@c - introspection [Su]
+@c - upgrade + response-upgrade [Mo]
+@c - migration! [Di]
+@c - add more examples! [Mi]
+@c - doptions! [Do]
+@c - request options! [Fr]
+@c - other options (connection, session?) [Sa]
@c - what about flow?
-@c - finally: add more examples!
@bye
diff --git a/doc/manual/actions.inc b/doc/manual/actions.inc
new file mode 100644
index 0000000..0ba9741
--- /dev/null
+++ b/doc/manual/actions.inc
@@ -0,0 +1,387 @@
+When handling HTTP requests from clients in a
+@code{MHD_RequestCallback} the main result of the handler is always a
+@code{struct MHD_Action}. The action returned by the handler
+determines how the processing of the HTTP request should continue.
+
+@anchor{MHD_Action}
+@deftp {C Struct} MHD_Action
+Actions are returned by the application to MHD
+to drive the request handling of MHD.
+@end deftp
+
+It is important to remember that the
+@ref{MHD_RequestCallback,,@code{MHD_RequestCallback}} is
+invoked immediately after MHD has parsed the HTTP request
+@emph{headers}. This means, the client may not yet have uploaded the
+request body (for example, if the request is using the POST
+method). Depending on the HTTP protocol version and the size of the
+upload, the client may actually wait for confirmation (``101
+Continue'') from the HTTP server before proceeding with the upload.
+Thus, when the @code{MHD_RequestCallback} is invoked, we generally
+have several choices:
+
+@itemize @bullet{}
+@item Return an HTTP response immediately. If the client would have
+proceeded to send a body, this may possibly preempt it from
+uploading a body by denying the request.
+@item Fail hard by closing the connection. This is usually the
+least desirable choice and should be reserved to cases where the
+server has no resources to generate even an response to indicate
+a failure.
+@item Suspend handling the request. This can be useful if generating
+a response requires some other server-side process to make progress
+or to rate-limit overly eager clients.
+@item Allow the client to upload data, parse it and eventually
+return a response (or fail hard by closing the connection).
+@end itemize
+
+@ref{libmicrohttpd2-responses} discusses generating responses in
+detail. This chapter will focus on the @emph{other} three
+cases.@footnote{There is a special forth case which applies when an
+HTTP/1.x client requests a ``protocol upgrade''. This is most often
+used to create a WebSocket. Creating an action for such protocol
+upgrades is described in @ref{libmicrohttpd2-upgrade}.}
+
+@node libmicrohttpd-actions-fail
+@section Failing hard by closing the connection
+
+The simplest way to handle a request is to simply close the
+connection, not returning any data to the client. This violates
+the HTTP protocol, but is of course the ultimate fallback when
+regular error handling is not possible.
+
+@deftypefun {const struct MHD_Action *} MHD_action_abort_request (struct
MHD_Request *request)
+
+Creates an action to tell MHD to close the connection hard
+(kind-of breaking HTTP specification). 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{request}.
+@end deftypefun
+
+
+
+@node libmicrohttpd-actions-suspend
+@section Suspend handling the request
+
+The @code{MHD_action_suspend()} is used to suspend a client's
+request. MHD will keep the network connection open until the
+application explicitly tells it to resume processing.
+
+@deftypefun {const struct MHD_Action *} MHD_action_suspend (struct MHD_Request
*request)
+
+Suspend handling of network data for a given request. This can
+be used to dequeue a request from MHD's event loop for a while.
+
+Suspended requests continue to count against the total number of
+requests allowed (per daemon, as well as per IP, if such limits
+are set). Suspended requests will NOT time out; timeouts will
+restart when the request handling is resumed. While a
+request is suspended, MHD may not detect disconnects by the
+client.
+
+@table @var
+@item ctx request
+the request for which the action is generated
+@end table
+
+The function returns an action to cause a request to be suspended.
+@c FIXME: is this check implemented?
+NULL is returned if any action has been already created for the @var{request}.
+@end deftypefun
+
+After suspending a request, the application must eventually resume
+request handling via @code{MHD_request_resume()}. MHD will then call
+the @code{MHD_RequestCallback} again for the @var{request}, allowing
+the application to again inspect the request and return a new action.
+
+@anchor{MHD_request_resume}
+@deftypefun void MHD_request_resume (struct MHD_Request *request)
+
+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.
+
+@table @var
+@item ctx request
+the request to resume
+@end table
+@end deftypefun
+
+If you are using this function in @emph{external} select mode, you
+must make sure to run @code{MHD_daemon_process_blocking()} afterwards
+(as otherwise the change may not be reflected in the set returned to
+your @code{MHD_SocketRegistrationUpdateCallback} and you may end up
+with a request that is stuck until the next network activity.
+
+
+@node libmicrohttpd-actions-upload
+@section Processing a request body
+
+There are various ways to create an action that tells MHD that the
+application wants to process the body being uploaded by the client. If
+the client sent an ``Expect: 100-Continue'' header with its request,
+returning any of these will automatically cause MHD to respond with a
+``100 Continue'' status and initiate receiving the response from the
+client. Thus, applications should never attempt to explicitly return
+``100 Continue'' themselves.
+
+The main function to call to handle uploads discussed in this
+section is @code{MHD_action_process_upload()}. While this function
+in principle works for any kind of upload, it is not the most
+convenient when handling structured data from an HTML form that
+is encoded as ``application/x-www-form-urlencoded'' or
+``multipart/form-data'' or the (less common) ``text/plain''
+HTML5 form. When handling uploads of these formats, it is
+usually better to use the @code{MHD_action_parse_post()}
+which is described in @ref{libmicrohttpd2-post}.
+
+@deftypefun {const struct MHD_Action *} MHD_action_process_upload (struct
MHD_Request *request, size_t large_buffer_size, MHD_UploadCallback uc_full,
void *uc_full_cls, MHD_UploadCallback uc_inc, void *uc_inc_cls)
+
+Creates an action that handles an upload from a client.
+
+If @var{uc_inc} is @code{NULL} and the body does not fit
+into the allocated buffer, the request is aborted without
+any response by closing the connection.
+
+@table @var
+@item request
+the request to create action for;
+
+@item large_buffer_size
+how large should the upload buffer be.
+May allocate memory from the shared "large"
+memory pool if necessary and non-zero is given.
+Must be zero if @var{uc_full} is @code{NULL};
+
+@item uc_full
+function to call when complete body is
+received (only if it fits into @var{upload_buffer_size} bytes;
+can be @code{NULL} if @var{uc_inc} is not @code{NULL};
+must be @code{NULL} is @var{upload_buffer_size} is zero;
+
+@item uc_full_cls
+closure for @var{uc_full};
+
+@item uc_inc
+function to call to incrementally process the uploaded data
+if the upload if larger than @var{upload_buffer_size}
+or if @var{upload_buffer_size} cannot be allocated or
+if @var{uc_full} is @code{NULL};
+can be @code{NULL} if @var{uc_full} is not @code{NULL};
+
+@item uc_inc_cls
+closure for @var{uc_inc}.
+@end table
+
+The function returns @code{NULL} on error (out of memory, invalid parameters)
+or if any action has been already created for the @var{request},
+and otherwise a pointer to the action.
+@end deftypefun
+
+@code{MHD_action_process_upload()} is a bit overly complicated
+as it conflates the two main use-cases:
+
+@itemize
+@item handling of the entire data body in one buffer in memory, and
+@item incremental parsing of the upload over time.
+@end itemize
+
+In practice, applications are expected to use the two APIs
+that separate these use-cases, specifically
+@code{MHD_action_process_upload_full()} and
+@code{MHD_action_process_upload_inc()}.
+
+@deftypefun {const struct MHD_Action *} MHD_action_process_upload_full (struct
MHD_Request *request, size_t large_buffer_size, MHD_UploadCallback uc_full,
void *uc_full_cls)
+
+Creates an action that handles an upload from a client
+as a full upload data where MHD places all uploaded data
+into a buffer and then gives the result to the application
+all at once.
+
+@table @var
+@item request
+the request to create action for
+
+@item large_buffer_size
+how large should the upload buffer be.
+May allocate memory from the shared "large"
+memory pool if necessary. Usually the value
+given here will be the size of the upload as
+provided by the HTTP request header.
+
+@item uc_full
+function to call when complete body is
+received (only if it fits into @var{upload_buffer_size} bytes;
+
+@item uc_full_cls
+closure for @var{uc_full}.
+@end table
+
+The function returns @code{NULL} on error (out of memory, invalid parameters)
+or if any action has been already created for the @var{request},
+and otherwise a pointer to the action.
+@end deftypefun
+
+@deftypefun {const struct MHD_Action *} MHD_action_process_upload_inc (struct
MHD_Request *request, MHD_UploadCallback uc_inc, void *uc_inc_cls)
+
+Creates an action that handles an upload from a client incrementally.
+
+@table @var
+@item request
+the request to create action for;
+
+@item uc_inc
+function to call to incrementally process the uploaded data;
+
+@item uc_inc_cls
+closure for @var{uc_inc}.
+@end table
+@end deftypefun
+
+In all three cases, the application must provide callbacks to handle
+the uploaded data. These callbacks have the type @code{MHD_UploadCallback}.
+The application is provided with the uploaded data (either all of it at
+once or just the latest increment) and must return a
+@code{struct MHD_UploadAction} to determine how to continue handling
+the @var{request}.
+
+
+
+@deftypefn {Function Pointer} struct MHD_UploadAction * (*MHD_UploadCallback)
(void *cls, struct MHD_Request *request, size_t content_data_size, void
*content_data)
+
+FFunctions of this type are invoked by MHD whenever an application
+should process the HTTP body of a client's request.
+
+@table @var
+@item upload_cls
+custom closure provided by the application together with the
+pointer to the function
+
+@item request
+the request that is being processed
+
+@item content_data_size
+number of bytes in @var{content_data},
+zero when all data have been processed;
+
+@item content_data
+@var{content_data_size} bytes of the HTTP request body;
+can be safely modified in the callback;
+the buffer is valid only until the application
+returns from the callback;
+@code{NULL} when all data of the body have been processed;
+
+@end table
+The returned @code{struct MHD_UploadAction}
+informs MHD how to proceed further with the
+@var{request}. Returning @code{NULL} is
+equivalent to @code{MHD_upload_action_abort_request()}.
+@end deftypefn
+
+The @code{struct MHD_UploadAction} is quite similar to
+the @ref{MHD_Action,,@code{struct MHD_Action}} except that it is only
+applicable when processing client uploads.
+
+@anchor{MHD_UploadAction}
+@deftp {C Struct} MHD_UploadAction
+Actions are returned by the application to MHD
+to drive the request handling of MHD.
+@end deftp
+
+There are four basic @code{struct MHD_UploadAction}s that
+applications can use:
+
+@itemize
+@item continue processing the upload (for incremental upload processing only)
+@item suspend processing the upload (say to slow down the client to allow
+ the application to keep up)
+@item abort handling the request (closing the connection), and
+@item returning an HTTP response
+@end itemize
+
+The following functions generate the respective upload actions.
+
+
+
+@deftypefun {const struct MHD_UploadAction *} MHD_upload_action_continue
(struct MHD_Request *request)
+
+Action telling MHD to continue processing the upload.
+Valid only for incremental upload processing.
+
+@table @var
+@item request
+the request to create the upload action for;
+@end table
+
+Fails and returns @code{NULL} when used in combination with a
+full upload callback, for the final (with zero bytes of data)
+call to an incremental callback or on a request that is not
+handling an upload.
+@end deftypefun
+
+
+@deftypefun {const struct MHD_UploadAction *} MHD_upload_action_abort_request
(struct MHD_Request *request)
+
+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{request}.
+
+@table @var
+@item request
+the request to create the upload action for;
+@end table
+@end deftypefun
+
+
+@deftypefun {const struct MHD_UploadAction *} MHD_upload_action_from_response
(struct MHD_Request *request, struct MHD_Response *response)
+
+Converts a @var{response} to an upload action. If
+@code{MHD_R_O_REUSABLE} is not set, the reference to the
+@var{response} is consumed by the conversion. If
+@code{MHD_R_O_REUSABLE} is @code{MHD_YES}, then the @var{response} can
+be used again to create other actions in the future. However, the
+@var{response} is frozen by this step and must no longer be modified
+(i.e. by setting headers).
+
+@table @var
+@item request
+the request to create the upload action for;
+
+@item response
+the response to return to the client.
+@end table
+
+The function returns a pointer to the upload action; the upload action
+must be consumed otherwise the response object may leak; The function
+returns @code{NULL} if it failed (no memory) or if any other upload
+action has been already created for the @var{request} (or if the
+request is currently not in a state of handling an upload). When the
+function fails, the response object is nevertheless consumed and need
+not be "destroyed" by the application.
+
+@end deftypefun
+
+@deftypefun {const struct MHD_UploadAction *} MHD_upload_action_suspend
(struct MHD_Request *request)
+
+Suspend handling of network data for the given @var{request}. This can
+be used to dequeue a request from MHD's event loop for a while.
+
+Suspended requests continue to count against the total number of
+requests allowed (per daemon, as well as per IP, if such limits
+are set). Suspended requests will NOT time out; timeouts will
+restart when the request handling is resumed. While a
+request is suspended, MHD may not detect disconnects by the
+client.
+
+@table @var
+@item request
+the request to create the upload action for;
+@end table
+@end deftypefun
+
+After suspending an upload action, applications must
+use @ref{MHD_request_resume,,@code{MHD_request_resume()}}
+to resume processing the upload.
\ No newline at end of file
diff --git a/doc/manual/init.inc b/doc/manual/init.inc
index 688ef06..70f666e 100644
--- a/doc/manual/init.inc
+++ b/doc/manual/init.inc
@@ -90,6 +90,7 @@ 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.
+@anchor{MHD_RequestCallback}
@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.
diff --git a/doc/manual/introduction.inc b/doc/manual/introduction.inc
index 1508973..d3fcf82 100644
--- a/doc/manual/introduction.inc
+++ b/doc/manual/introduction.inc
@@ -328,6 +328,7 @@ avoid messing with other parts of the application that may
need to
handle SIGPIPE in a particular way. You can make your application
handle SIGPIPE by calling the following function in @code{main()}:
+@example
@verbatim
static void
catcher (int sig)
@@ -355,6 +356,7 @@ ignore_sigpipe (void)
"Failed to install SIGPIPE handler: %s\n", strerror (errno));
}
@end verbatim
+@end example
@section Portability to W32
diff --git a/doc/manual/requests.inc b/doc/manual/requests.inc
index 990c8d9..92a27c8 100644
--- a/doc/manual/requests.inc
+++ b/doc/manual/requests.inc
@@ -1,80 +1,619 @@
+A @code{struct MHD_Request} is given by MHD to the application
+to refer to an individual HTTP request by a client. Applications
+primarily are given a request handle as part of the arguments given
+to the central @ref{MHD_RequestCallback,,@code{MHD_RequestCallback}}
+of each @code{struct MHD_Daemon}.
+@deftp {C Struct} MHD_Request
+Handle representing an HTTP request.
-@deftypefun int MHD_get_connection_values (struct MHD_Connection *connection,
enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls)
-Get all the headers matching @var{kind} from the request. The @var{kind}
-argument can be a bitmask, ORing the various header kinds that are
-requested.
+With HTTP/1.1, multiple requests can be run over the same
+stream. However, MHD will only show one request per data
+stream to the application at any given time.
+@end deftp
-The @var{iterator} callback is invoked once for each header, with
-@var{iterator_cls} as first argument. After version 0.9.19, the
+This chapter discusses how to inspect the information
+from the request @emph{header}.
+@xref{libmicrohttpd-actions-upload} for handling data uploaded
+by HTTP clients in the body of a request.
+
+
+@node libmicrohttpd-requests-info
+@section Inspecting request name-value pairs
+
+When inspecting requests, MHD classifies values from a client's
+request into various @emph{kinds} of values. The different kinds
+are represented by the @code{enum MHD_ValueKind}.
+
+@anchor{MHD_ValueKind}
+@deftp {Enumeration} MHD_ValueKind
+
+Specifies the source of the name-value pairs in the HTTP protocol.
+
+@table @code
+@item MHD_VK_HEADER
+HTTP header (single line in the header).
+
+@item MHD_VK_COOKIE
+Cookies. Note that the original HTTP header containing
+all the cookie(s) is also available via @code{MHD_VK_HEADER}.
+
+@c FIXME: rename to VK_URL_ARGUMENT? Might be clearer!
+@item MHD_VK_GET_ARGUMENT
+URL arguments. Not actually limited to the HTTP GET method.
+
+@item MHD_VK_POSTDATA
+POST data.
+This is available only if @code{MHD_action_parse_post()} is used,
+a content encoding is supported by MHD, and only if the posted content
+fits within the specified memory buffers.
+
+Warning: The encoding ``multipart/form-data'' has more fields than just
+``name'' and ``value'' which are not available via the APIs discussed
+in this chapter. @xref{MHD_request_get_post_data_cb()} and
+@ref{MHD_request_get_post_data_list()} for more information.
+In particular it could be important
+to check the ``Transfer-Encoding''.
+
+@item MHD_VK_FOOTER
+Data from client request HTTP footer (only for HTTP 1.1 chunked encodings).
+
+@item MHD_VK_HEADER_FOOTER
+Values from both the HTTP header and footer.
+
+@c FIXME: rename to VK_URL_OR_POST? Might be clearer!
+@item MHD_VK_GET_POST
+Values from URL arguments or post data.
+
+@end table
+@end deftp
+
+Given a value @var{kind} (or possibly a bitmask combining different
+kinds), MHD offers various ways to access values from of that kind
+for a given @var{request}.
+
+@deftypefun int MHD_request_get_values_cb (struct MHD_Request *request, enum
MHD_ValueKind kind, MHD_NameValueIterator iterator, void *iterator_cls)
+Get all the headers matching @var{kind} from the request.
+
+@table @var
+@item request
+the HTTP request to inspect;
+
+@item kind
+kinds of name-value pairs of the request to pass to @var{iterator},
+can be a bitmask, ORing the various header kinds that are requested
+(@xref{MHD_ValueKind});
+
+@item iterator
+This callback function is invoked once for each header, with
+@var{iterator_cls} as first argument. The
headers are iterated in the same order as they were received from
-the network; previous versions iterated over the headers in reverse
-order.
+the network.
+@var{iterator} can be @code{NULL}: in this case this function just counts
+and returns the number of headers;
+
+@item iterator_cls
+closure argument for @var{iterator}.
+@end table
-@code{MHD_get_connection_values} returns the number of entries
+The function returns the number of entries
iterated over; this can be less than the number of headers if, while
iterating, @var{iterator} returns @code{MHD_NO}.
+@end deftypefun
-@var{iterator} can be @code{NULL}: in this case this function just counts
-and returns the number of headers.
+@var{iterator}s implementing the @code{MHD_NameValueIterator}
+are simply given the specific @var{kind} and name-and-value pair.
+
+
+@anchor{MHD_NameValueIterator}
+@deftypefn {Function Pointer} enum MHD_Bool (*MHD_NameValueIterator) (void
*cls, enum MHD_ValueKind kind, const struct MHD_NameAndValue *nv)
+Functions of this type are invoked by MHD for each matching
+name-value pair.
+
+@table @var
+@item cls
+custom value provided by the application to @code{MHD_daemon_create()};
+
+@item kind
+the type (kind) of the element; will only have one bit set
+(@xref{MHD_ValueKind});
+
+@item nv
+the name and the value of the element,
+the referenced data is valid only until the
+application returns from this function.
+@end table
+The function should return @code{MHD_YES} to continue to
+iterate, and @code{MHD_NO} to abort the iteration.
+@end deftypefn
-In the case of @code{MHD_GET_ARGUMENT_KIND}, the @var{value} argument
-will be @code{NULL} if the URL contained a key without an equals operator.
+
+@anchor{MHD_NameAndValue}
+@deftp {C Struct} MHD_NameAndValue name value
+Represents a pair of a name and a value.
+@table @code
+@item @code{struct MHD_String} name
+Name under which the value is stored, some kinds allow empty strings;
+
+@item @code{struct MHD_StringNullable} value
+The value of the field. Some kinds allow absence of the value;
+The absence is indicated by NULL pointer to the C string.
+@end table
+@end deftp
+
+
+If @var{kind} is @code{MHD_GET_ARGUMENT_KIND}, the @var{value} argument
+given to the @var{iterator} callback will be @code{NULL} if the URL
+contained a key without an equals operator.
For example, for a HTTP request to the URL ``http://foo/bar?key'', the
@var{value} argument is @code{NULL}; in contrast, a HTTP request to the URL
``http://foo/bar?key='', the @var{value} argument is the empty string.
The normal case is that the URL contains ``http://foo/bar?key=value''
in which case @var{value} would be the string ``value'' and @var{key}
would contain the string ``key''.
-@end deftypefun
-@deftypefun enum MHD_Result MHD_set_connection_value (struct MHD_Connection
*connection, enum MHD_ValueKind kind, const char *key, const char *value)
-This function can be used to append an entry to
-the list of HTTP headers of a connection (so that the
-@code{MHD_get_connection_values function} will return
-them -- and the MHD PostProcessor will also
-see them). This maybe required in certain
-situations (see Mantis #1399) where (broken)
-HTTP implementations fail to supply values needed
-by the post processor (or other parts of the
-application).
-
-This function MUST only be called from within
-the MHD_AccessHandlerCallback (otherwise, access
-maybe improperly synchronized). Furthermore,
-the client must guarantee that the key and
-value arguments are 0-terminated strings that
-are NOT freed until the connection is closed.
-(The easiest way to do this is by passing only
-arguments to permanently allocated strings.).
-
-@var{connection} is the connection for which
-the entry for @var{key} of the given @var{kind}
-should be set to the given @var{value}.
-
-The function returns @code{MHD_NO} if the operation
-could not be performed due to insufficient memory
-and @code{MHD_YES} on success.
+@deftypefun int MHD_request_get_values_list (struct MHD_Request *request, enum
MHD_ValueKind kind, size_t num_elements, struct MHD_NameValueKind
elements[num_elements])
+Get all the headers matching @var{kind} from the request.
+
+The pointers to the strings returned in @var{elements} are valid until
+any @code{struct MHD_Action} or @code{struct MHD_UploadAction} is
+provided for the @var{request}. If the data is needed beyond this
+point, it should be copied to an application buffer before returning
+an action.
+
+@table @var
+@item request
+the HTTP request to inspect;
+
+@item kind
+kinds of name-value pairs of the request to pass to @var{iterator},
+can be a bitmask, ORing the various header kinds that are requested;
+
+@item num_elements
+length of the @var{elements} array provided
+
+@item elements
+array of length @var{num_elements} to be filled with
+the key-value pairs; if @var{request} has more matching elements
+than @var{num_elements} than any @var{num_elements} are stored.
+@end table
+
+The function returns the number of entries
+stored in @var{elements}, the number cannot be larger
+than @var{num_elements}, zero if there were no matching
+elements or on any error.
@end deftypefun
+@deftp {C Struct} MHD_NameValueKind nv kind
+Represents a triplet of a name, value and kind.
+@table @code
+@item @code{struct MHD_NameAndValue} nv
+The name and value of the field
+(@xref{MHD_NameAndValue});
+
+@item @code{struct MHD_ValueKind} kind
+The kind of the field
+(@xref{MHD_ValueKind}).
+@end table
+@end deftp
+
+
+@deftypefun {const struct MHD_StringNullable *} MHD_request_get_value (struct
MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
+Returns a particular data value from a @var{request}.
-@deftypefun {const char *} MHD_lookup_connection_value (struct MHD_Connection
*connection, enum MHD_ValueKind kind, const char *key)
-Get a particular header value. If multiple values match the
-@var{kind}, return one of them (the ``first'', whatever that means).
+@table @var
+@item request
+the HTTP request to inspect;
+
+@item kind
+kinds of name-value pairs of the request to pass to @var{iterator},
+can be a bitmask, ORing the various header kinds that are requested
+(@xref{MHD_ValueKind});
+
+@item key
+the name of the value to look for (used for case-insensitive
+match), use an empty string to lookup 'trailing' values without a key;
@var{key} must reference a zero-terminated ASCII-coded string
-representing the header to look for: it is compared against the
-headers using (basically) @code{strcasecmp()}, so case is ignored.
+representing the value to look for.
+@end table
+The function returns @code{NULL} if no matching item was found.
+If multiple values match the
+@var{kind} and @var{key}, returns the first of them.
+@end deftypefun
+
+
+The following code is a simple example to determine the
+value of a ``Host:'' header.
+
+@example
+@verbatiminclude examples/host-example.c
+@end example
+
+
+
+@node libmicrohttpd-requests-info
+@section Obtaining request status information
+
+
+@deftypefun {enum MHD_StatusCode} MHD_request_get_info_fixed_sz (struct
MHD_Request *request, enum MHD_RequestInfoFixedType info_type, union
MHD_RequestInfoFixedData *output_buf, size_t output_buf_size)
+
+Obtain fixed information about the given request.
+This information is not changed for the lifetime of the request.
+
+@table @var
+@item request
+the request to get information about;
+
+@item info_type
+the type of information requested;
+
+@item output_buf
+output_buf the pointer to union to be set to the requested
+information;
+
+@item output_buf_size
+size of @var{output_buf} in bytes
+@end table
+
+The function returns
+@table @code
+@item MHD_SC_OK
+on success,
+
+@item MHD_SC_INFO_GET_TYPE_UNKNOWN
+if @var{info_type} is unknown,
+
+@item MHD_SC_TOO_EARLY
+if request processing has not yet reached the
+stage where this information is available, and
+
+@item MHD_SC_INFO_GET_BUFF_TOO_SMALL
+if @var{output_buf_size} is too
+small.
+@end table
+
+Specific @var{info_type} values may yield additional
+type-specific error codes.
+@end deftypefun
+
+Using the above function directly is not recommended.
+Instead, applications should use @code{MHD_request_get_info_fixed()}
+which is more convenient as it uses a macro to automatically
+provide the @var{output_buf_size}.
+
+@deftypefun {enum MHD_StatusCode} MHD_request_get_info_fixed (struct
MHD_Request *request, enum MHD_RequestInfoFixedType info_type, union
MHD_RequestInfoFixedData *output_buf)
+
+Obtain fixed information about the given request.
+This information is not changed for the lifetime of the request.
+
+@table @var
+@item request
+the request to get information about;
+
+@item info_type
+the type of information requested;
+
+@item output_buf
+output_buf the pointer to union to be set to the requested
+information;
+@end table
+
+The macro returns the same values as
+@code{MHD_request_get_info_fixed_sz()}
+@end deftypefun
+
+
+@deftp {Enumeration} MHD_RequestInfoFixedType
+Selects which fixed information about the request is desired.
+
+@table @code
+@item MHD_REQUEST_INFO_FIXED_HTTP_VER
+Get the version of HTTP protocol used for the request.
+If request line has not been fully received yet then @code{MHD_SC_TOO_EARLY}
+is returned.
+The result is placed in @var{v_http_ver} member.
+
+@item MHD_REQUEST_INFO_FIXED_HTTP_METHOD
+Get the HTTP method used for the request (as an enum).
+The result is placed in @var{v_http_method} member.
+@xref{MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR}
+
+@item MHD_REQUEST_INFO_FIXED_DAEMON
+Return MHD daemon to which the request belongs to.
+The result is placed in @var{v_daemon} member.
+
+@item MHD_REQUEST_INFO_FIXED_CONNECTION
+Return which connection is associated with the stream which is associated
+with the request. The result is placed in @var{v_connection} member.
+
+@item MHD_REQUEST_INFO_FIXED_STREAM
+Return which stream the request is associated with.
+The result is placed in @var{v_stream} member.
+
+@item MHD_REQUEST_INFO_FIXED_APP_CONTEXT
+Returns the pointer to a variable pointing to request-specific
+application context data. The same data is provided for
+@ref{MHD_EarlyUriLogCallback,,@code{MHD_EarlyUriLogCallback}} and
+@ref{MHD_RequestTerminationCallback,,@code{MHD_RequestTerminationCallback}}.
+By using provided pointer application may get or set the pointer to
+any data specific for the particular request.
+The result is placed in @var{v_ppvoid} member.
+
+@end table
+@end deftp
+
+
+@deftp {C Union} MHD_RequestInfoFixedType
+
+Fixed information about a request.
+This information will not change during the lifetime of the request.
+
+@table @var
+@item @code{struct MHD_Stream *} v_stream
+The stream of the request.
+
+@item @code{struct MHD_Connection *} v_connection
+The connection of the request.
+
+@item @code{struct MHD_Daemon *} v_daemon
+The daemon handling the request.
+
+@item @code{enum MHD_HTTP_ProtocolVersion} v_http_ver
+The HTTP protocol version used for the request.
+
+@item @code{enum MHD_HTTP_Method} v_http_method
+The HTTP method of the request.
+
+@item @code{void **} v_ppvoid
+The pointer to a pointer where the application can store
+contextual data for the request.
+@end table
+@end deftp
+
+
+
+
+@deftypefun {enum MHD_StatusCode} MHD_request_get_info_dynamic_sz (struct
MHD_Request *request, enum MHD_RequestInfoDynamicType info_type, union
MHD_RequestInfoFixedData *output_buf, size_t output_buf_size)
+
+Obtain dynamic information about the given request.
+This information may be changed during the lifetime of the request.
+Most of the data provided is available only when the request line or complete
+request headers are processed and not available if responding has been
+started.
+
+Any pointers in the returned data are only valid until any
+@code{struct MHD_Action} or @code{struct MHD_UploadAction} is
+returned to MHD. If the data is needed beyond this point,
+it should be copied into an application buffer before returning the
+action.
+
+@table @var
+@item request
+the request to get information about;
+
+@item info_type
+the type of information requested;
+
+@item output_buf
+output_buf the pointer to union to be set to the requested
+information;
+
+@item output_buf_size
+size of @var{output_buf} in bytes
+@end table
+
+The function returns
+@table @code
+@item MHD_SC_OK
+on success
+
+@item MHD_SC_INFO_GET_TYPE_UNKNOWN
+if @var{info_type} is unknown
+
+@item MHD_SC_TOO_EARLY
+if request processing has not yet reached the
+stage where this information is available,
+
+@item MHD_SC_TOO_LATE if request processing is past the
+stage where this information was available,
+
+@item MHD_SC_FEATURE_DISABLED if requested functionality is
+not supported by this MHD build,
+
+@item MHD_SC_INFO_GET_BUFF_TOO_SMALL if @var{output_buf_size} is too
+small,
+
+@item MHD_SC_AUTH_ABSENT
+if request does not have particular authentication data,
+
+@item MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA
+if connection memory pool has no space to put decoded
+authentication data,
+
+@item MHD_SC_REQ_AUTH_DATA_BROKEN
+if the format of authentication data is incorrect or broken,
+@end table
+
+Specific @var{info_type} values may yield additional
+type-specific error codes.
@end deftypefun
-@deftypefun {const char *} MHD_lookup_connection_value_n (struct
MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, size_t
key_size, const char **value_ptr, size_t *value_size_ptr)
-Get a particular header value. If multiple values match the
-@var{kind}, return one of them (the ``first'', whatever that means).
-@var{key} must reference an ASCII-coded string
-representing the header to look for: it is compared against the
-headers using (basically) @code{strncasecmp()}, so case is ignored.
-The @var{value_ptr} is set to the address of the value found,
-and @var{value_size_ptr} is set to the number of bytes in the
-value.
+Using the above function directly is not recommended.
+Instead, applications should probably use
+@code{MHD_request_get_info_dynamic()}
+which is more convenient as it uses a macro to automatically
+provide the @var{output_buf_size}.
+
+@deftypefun {enum MHD_StatusCode} MHD_request_get_info_dynamic (struct
MHD_Request *request, enum MHD_RequestInfoDynamicType info_type, union
MHD_RequestInfoDynamicData *output_buf)
+
+Obtain fixed information about the given request.
+This information is not changed for the lifetime of the request.
+
+@table @var
+@item request
+the request to get information about;
+
+@item info_type
+the type of information requested;
+
+@item output_buf
+output_buf the pointer to union to be set to the requested
+information;
+@end table
+
+The macro returns the same values as
+@code{MHD_request_get_info_dynamic_sz()}
@end deftypefun
+
+
+@deftp {Enumeration} MHD_RequestInfoDynamicType
+
+Selects what dynamic information about request is desired.
+This information may be changed during the lifetime of the request.
+Any returned string pointers are valid only until a response is
+provided for the request by the application!
+
+@table @code
+
+@item MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STR
+Get the HTTP method used for the request (as a MHD_String).
+The result is placed in @var{v_str} member.
+The resulting string pointer in valid only until a response is provided.
+@xref{MHD_REQUEST_INFO_FIXED_HTTP_METHOD}
+
+@item MHD_REQUEST_INFO_DYNAMIC_URI
+Get the URI used for the request (as a MHD_String), excluding
+the parameter part (anything after '?').
+The result is placed in @var{v_str} member.
+The resulting string pointer in valid only until a response is provided.
+
+@item MHD_REQUEST_INFO_DYNAMIC_NUMBER_GET_PARAMS
+Get the number of GET parameters (the decoded part of the original
+URI string after '?')
+The result is placed in @var{v_sizet} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES
+Get the number of cookies in the request.
+The result is placed in @var{v_sizet} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE
+Return length of the client's HTTP request header.
+This is a total raw size of the header (after TLS decipher if any)
+The result is placed in @var{v_sizet} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_NUMBER_POST_PARAMS
+Get the number of decoded POST entries in the request.
+The result is placed in @var{v_sizet} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_UPLOAD_PRESENT
+Get whether the upload content is present in the request.
+The result is @code{MHD_YES} if any upload content is present, even
+if the upload content size is zero.
+The result is placed in @var{v_bool} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_UPLOAD_CHUNKED
+Get whether the chunked upload content is present in the request.
+The result is @code{MHD_YES} if chunked upload content is present.
+The result is placed in @var{v_bool} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TOTAL
+Get the total content upload size.
+Resulted in zero if no content upload or upload content size is zero,
+@code{MHD_SIZE_UNKNOWN} if size is not known (chunked upload).
+The result is placed in @var{v_uint64} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_RECIEVED
+Get the total size of the content upload already received from the client.
+This is the total size received, could be not yet fully processed by the
+application.
+The result is placed in @var{v_uint64} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_RECIEVE
+Get the total size of the content upload left to be received from
+the client.
+Resulted in @code{MHD_SIZE_UNKNOWN} if total size is not known (chunked
upload).
+The result is placed in @var{v_uint64} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_PROCESSED
+Get the total size of the content upload already processed (upload callback
+called and completed (if any)).
+If the value is requested from @code{MHD_UploadCallback}, then result does NOT
+include the current data being processed by the callback.
+The result is placed in @var{v_uint64} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_UPLOAD_SIZE_TO_PROCESS
+Get the total size of the content upload left to be processed.
+The resulting value includes the size of the data not yet received from
+the client.
+If the value is requested from @code{MHD_UploadCallback}, then result includes
+the current data being processed by the callback.
+Resulted in @code{MHD_SIZE_UNKNOWN} if total size is not
+known (for example, in the case of a chunked upload).
+The result is placed in @var{v_uint64} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_USERNAME
+Returns pointer to information about username in client's digest auth
+request.
+The resulting pointer is NULL if no digest auth header is set by
+the client, the format of the digest auth header is broken, no
+username is provided or the format of the username parameter is broken.
+Pointers in the returned structure (if any) are valid until response
+is provided for the request.
+The result is placed in @var{v_auth_digest_uname} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO
+Returns pointer to information about digest auth in client request.
+The resulting pointer is NULL if no digest auth header is set by
+the client or the format of the digest auth header is broken.
+Pointers in the returned structure (if any) are valid until response
+is provided for the request.
+The result is placed in @var{v_auth_digest_info} member.
+
+@item MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS
+Returns information about Basic Authentication credentials in the request.
+Pointers in the returned structure (if any) are valid until
+any @code{struct MHD_Action} or @code{struct MHD_UploadAction}
+is provided. If the data is needed beyond this point,
+it must be copied to an application buffer before providing the action.
+If @code{MHD_request_get_info_dynamic_sz()} returns @code{MHD_SC_OK} then
+@var{v_auth_basic_creds} is not @code{NULL} and at least the username data
+is provided.
+The result is placed in @var{v_auth_basic_creds} member.
+@end table
+@end deftp
+
+
+
+
+
+@deftp {C Union} MHD_RequestInfoDynamicData
+Stores dynamic information about a request.
+
+@table @var
+@item @code{struct MHD_String} v_str
+Used when the requested information is a string.
+
+@item @code{size_t} v_sizet
+Used when the requested information is a size.
+
+@item @code{enum MHD_Bool} v_bool
+Used when the requested information is a boolean.
+
+@item @code{uint_fast64_t} v_uint64
+Used when the requested information is an unsigned 64-bit integer.
+
+@item @code{const struct MHD_AuthDigestUsernameInfo *} v_auth_digest_uname
+Information about client-provided username for digest authentication.
+
+@item @code{const struct MHD_AuthDigestInfo *} v_auth_digest_info
+Information about client's digest authentication.
+
+@item @code{const struct MHD_AuthBasicCreds *} v_auth_basic_creds
+The username and password provided by the client's basic authentication header.
+If @code{MHD_request_get_info_dynamic_sz()} returns
+@code{MHD_SC_OK} then this pointer is not @code{NULL} and
+at least the @var{username} is provided.
+@end table
+@end deftp
diff --git a/doc/manual/responses.inc b/doc/manual/responses.inc
index 06b404e..a5b5715 100644
--- a/doc/manual/responses.inc
+++ b/doc/manual/responses.inc
@@ -5,6 +5,12 @@ 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.
+@deftp {C Struct} MHD_Response
+Handle for a response to be returned to an HTTP client.
+A response includes the HTTP status code, HTTP headers,
+a body and possibly HTTP footers.
+@end deftp
+
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:
--
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: more chapters,
Admin <=