docs from Marco Maggi

This commit is contained in:
Christian Grothoff
2007-12-30 20:07:39 +00:00
parent 54489aba79
commit 435bef8e63
4 changed files with 9082 additions and 1 deletions
+5 -1
View File
@@ -1,3 +1,7 @@
man_MANS = libmicrohttpd.3
EXTRA_DIST = $(man_MANS)
#DISTCLEANFILES = microhttpd.cps
#info_TEXINFOS = microhttpd.texi
#microhttpd_TEXINFOS = gpl.texi
+397
View File
@@ -0,0 +1,397 @@
@node Copying
@appendix GNU GENERAL PUBLIC LICENSE
@cindex GPL, GNU General Public License
@center Version 2, June 1991
@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display
@appendixsubsec Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software---to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
@iftex
@appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end ifinfo
@enumerate
@item
This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The ``Program'', below,
refers to any such program or work, and a ``work based on the Program''
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term ``modification''.) Each licensee is addressed as ``you''.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
@item
You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
@item
You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
@enumerate a
@item
You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
@item
You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
@item
If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
@end enumerate
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
@item
You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
@enumerate a
@item
Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
@item
Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
@item
Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
@end enumerate
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
@item
You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
@item
You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
@item
Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
@item
If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
@item
If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
@item
The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and ``any
later version'', you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
@item
If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo
@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
@item
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
@end enumerate
@iftex
@heading END OF TERMS AND CONDITIONS
@end iftex
@ifinfo
@center END OF TERMS AND CONDITIONS
@end ifinfo
@page
@unnumberedsec How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the ``copyright'' line and a pointer to where the full notice is found.
@smallexample
@var{one line to give the program's name and an idea of what it does.}
Copyright (C) 19@var{yy} @var{name of author}
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
@end smallexample
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'. This is free software, and you are welcome
to redistribute it under certain conditions; type `show c'
for details.
@end smallexample
The hypothetical commands @samp{show w} and @samp{show c} should show
the appropriate parts of the General Public License. Of course, the
commands you use may be called something other than @samp{show w} and
@samp{show c}; they could even be mouse-clicks or menu items---whatever
suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a ``copyright disclaimer'' for the program, if
necessary. Here is a sample; alter the names:
@smallexample
@group
Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written
by James Hacker.
@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end group
@end smallexample
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
+1198
View File
@@ -0,0 +1,1198 @@
@setfilename microhttpd.info
@macro gnu{}
@acronym{GNU}
@end macro
@macro gpl{}
@acronym{GPL}
@end macro
@macro http{}
@acronym{HTTP}
@end macro
@macro tcp{}
@acronym{TCP}
@end macro
@macro api{}
@acronym{API}
@end macro
@macro urloc{}
@acronym{URL}
@end macro
@macro uri{}
@acronym{URI}
@end macro
@macro ascii{}
@acronym{ASCII}
@end macro
@c ............................................................
@macro cfunction{NAME}
@code{\NAME\()}
@end macro
@macro null{}
@code{NULL}
@end macro
@c ............................................................
@macro glibcref{NODE, NODE}
@pxref{\NODE\, \NODE\, \NODE\, libc}
@end macro
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd
@appendix Libmicrohttpd documentation
@macro mhd{}
@acronym{MHD}
@end macro
@noindent
This appendix documents Libmicrohttpd version 0.1.2. It is built upon
the documentation in the header file @file{microhttpd.h}.
@menu
* microhttpd intro:: Introduction.
* microhttpd const:: Constants.
* microhttpd struct:: Structures type definition.
* microhttpd cb:: Callback functions definition.
* microhttpd init:: Starting and stopping the server.
* microhttpd inspect:: Inspection.
* microhttpd requests:: Handling requests.
* microhttpd responses:: Building responses to requests.
* microhttpd post:: Adding a @code{POST} processor.
@end menu
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd intro
@appendixsec Introduction
@noindent
All symbols defined in the public @api{} start with @code{MHD_}. @mhd{}
is a small @http{} daemon library. As such, it does not have any @api{}
for logging errors (you can only enable or disable logging to stderr).
Also, it may not support all of the @http{} features directly, where
applicable, portions of @http{} may have to be handled by clients of the
library.
The library is supposed to handle everything that it must handle
(because the @api{} would not allow clients to do this), such as basic
connection management; however, detailed interpretations of headers ---
such as range requests --- and @http{} methods are left to clients. The
library does understand @code{HEAD} and will only send the headers of
the response and not the body, even if the client supplied a body. The
library also understands headers that control connection management
(specifically, @code{Connection: close} and @code{Expect: 100 continue}
are understood and handled automatically).
@mhd{} understands @code{POST} data and is able to decode certain
formats (at the moment only @code{application/x-www-form-urlencoded}) if
the entire data fits into the allowed amount of memory for the
connection. Unsupported encodings and large @code{POST} submissions are
provided as a stream to the main application (and thus can be processed,
just not conveniently by @mhd{}).
The header file defines various constants used by the @http{} protocol.
This does not mean that @mhd{} actually interprets all of these values.
The provided constants are exported as a convenience for users of the
library. @mhd{} does not verify that transmitted @http{} headers are
part of the standard specification; users of the library are free to
define their own extensions of the @http{} standard and use those with
@mhd{}.
All functions are guaranteed to be completely reentrant and
thread--safe.
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd const
@appendixsec Constants
@deftp {Enumeration} MHD_FLAG
Options for the @mhd{} daemon.
Note that if neither @code{MHD_USER_THREAD_PER_CONNECTION} nor
@code{MHD_USE_SELECT_INTERNALLY} are used, the client wants control over
the process and will call the appropriate microhttpd callbacks.
Starting the daemon may also fail if a particular option is not
implemented or not supported on the target platform (i.e. no support for
@acronym{SSL}, threads or IPv6).
@table @code
@item MHD_NO_FLAG
No options selected.
@item MHD_USE_DEBUG
Run in debug mode. If this flag is used, the library should print error
messages and warnings to stderr.
@item MHD_USE_SSL
Run in https mode.
@item MHD_USE_THREAD_PER_CONNECTION
Run using one thread per connection.
@item MHD_USE_SELECT_INTERNALLY
Run using an internal thread doing @code{SELECT}.
@item MHD_USE_IPv6
Run using the IPv6 protocol (otherwise, @mhd{} will just support IPv4).
@item MHD_USE_PEDANTIC_CHECKS
Be pedantic about the protocol (as opposed to as tolerant as possible).
Specifically, at the moment, this flag causes @mhd{} to reject @http{}
1.1 connections without a @code{Host} header. This is required by the
standard, but of course in violation of the ``be as liberal as possible
in what you accept'' norm. It is recommended to turn this @strong{ON}
if you are testing clients against @mhd{}, and @strong{OFF} in
production.
@end table
@end deftp
@deftp {Enumeration} MHD_OPTION
@mhd{} options. Passed in the varargs portion of
@cfunction{MHD_start_daemon}.
@table @code
@item MHD_OPTION_END
No more options / last option. This is used to terminate the VARARGs
list.
@item MHD_OPTION_CONNECTION_MEMORY_LIMIT
Maximum memory size per connection (followed by an @code{unsigned int}).
@item MHD_OPTION_CONNECTION_LIMIT
Maximum number of concurrenct connections to accept (followed by an
@code{unsigned int}).
@item MHD_OPTION_CONNECTION_TIMEOUT
After how many seconds of inactivity should a connection automatically
be timed out? (followed by an @code{unsigned int}; use zero for no
timeout).
@item MHD_OPTION_NOTIFY_COMPLETED
Register a function that should be called whenever a request has been
completed (this can be used for application--specific clean up).
Requests that have never been presented to the application (via
@cfunction{MHD_AccessHandlerCallback}) will not result in
notifications.
This option should be followed by @strong{TWO} pointers. First a
pointer to a function of type @cfunction{MHD_RequestCompletedCallback}
and second a pointer to a closure to pass to the request completed
callback. The second pointer maybe @null{}.
@end table
@end deftp
@deftp {Enumeration} MHD_ValueKind
The @code{MHD_ValueKind} specifies the source of the key--value pairs in
the @http{} protocol.
@table @code
@item MHD_RESPONSE_HEADER_KIND
Response header.
@item MHD_HEADER_KIND
@http{} header.
@item MHD_COOKIE_KIND
Cookies. Note that the original @http{} header containing the cookie(s)
will still be available and intact.
@item MHD_POSTDATA_KIND
@code{POST} data. This is available only if a content encoding
supported by @mhd{} is used (currently only @acronym{URL} encoding), and
only if the posted content fits within the available memory pool. Note
that in that case, the upload data given to the
@cfunction{MHD_AccessHandlerCallback} will be empty (since it has
already been processed).
@item MHD_GET_ARGUMENT_KIND
@code{GET} (@uri{}) arguments.
@end table
@end deftp
@deftp {Enumeration} MHD_RequestTerminationCode
The @code{MHD_RequestTerminationCode} specifies reasons why a request
has been terminated (or completed).
@table @code
@item MHD_REQUEST_TERMINATED_COMPLETED_OK
We finished sending the response.
@item MHD_REQUEST_TERMINATED_WITH_ERROR
Error handling the connection (resources exhausted, other side closed
connection, application error accepting request, etc.)
@item MHD_REQUEST_TERMINATED_TIMEOUT_REACHED
No activity on the connection for the number of seconds specified using
@code{MHD_OPTION_CONNECTION_TIMEOUT}.
@item MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN
We had to close the session since @mhd{} was being shut down.
@end table
@end deftp
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd struct
@appendixsec Structures type definition
@deftp {C Struct} MHD_Daemon
Handle for the daemon (listening on a socket for @http{} traffic).
@end deftp
@deftp {C Struct} MHD_Connection
Handle for a connection / @http{} request. With @http{}/1.1, multiple
requests can be run over the same connection. However, @mhd{} will only
show one request per @tcp{} connection to the client at any given time.
@end deftp
@deftp {C Struct} MHD_Response
Handle for a response.
@end deftp
@deftp {C Struct} MHD_PostProcessor
Handle for @code{POST} processing.
@end deftp
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd cb
@appendixsec Callback functions definition
@deftypefn {Function Pointer} int {*MHD_AcceptPolicyCallback} (void *cls, const struct sockaddr * addr, socklen_t addrlen)
Invoked in the context of a connection to allow or deny a client to
connect. This callback return @code{MHD_YES} if connection is allowed,
@code{MHD_NO} if not.
@table @var
@item cls
custom value selected at callback registration time;
@item addr
address information from the client;
@item addrlen
length of the address information.
@end table
@end deftypefn
@deftypefn {Function Pointer} int {*MHD_AccessHandlerCallback} (void *cls, struct MHD_Connection * connection, const char *url, const char *method, const char *version, const char *upload_data, unsigned int *upload_data_size, void **con_cls)
Invoked in the context of a connection to answer a request from the
client. This callback must call @mhd{} functions (example: the
@code{MHD_Response} ones) to provide content to give back to the client
and return an @http{} status code (i.e. @code{200} for OK, @code{404},
etc.).
@ref{microhttpd post}, for details on how to code this callback.
Must return @code{MHD_YES} if the connection was handled successfully,
@code{MHD_NO} if the socket must be closed due to a serious error while
handling the request
@table @var
@item cls
custom value selected at callback registration time;
@item url
the @urloc{} requested by the client;
@item method
the @http{} method used by the client (@code{GET}, @code{PUT},
@code{DELETE}, @code{POST}, etc.);
@item version
the @http{} version string (i.e. @code{HTTP/1.1});
@item upload_data
the data being uploaded (excluding headers):
@itemize
@item
for a @code{POST} that fits into memory and that is encoded with a
supported encoding, the @code{POST} data will @strong{NOT} be given in
@var{upload_data} and is instead available as part of
@cfunction{MHD_get_connection_values};
@item
very large @code{POST} data @strong{will} be made available
incrementally in @var{upload_data};
@end itemize
@item upload_data_size
set initially to the size of the @var{upload_data} provided; this
callback must update this value to the number of bytes @strong{NOT}
processed;
@item con_cls
reference to a pointer, initially set to @null{}, that this callback can
set to some address and that will be preserved by @mhd{} for future
calls for this request;
since the access handler may be called many times (i.e., for a
@code{PUT}/@code{POST} operation with plenty of upload data) this allows
the application to easily associate some request--specific state;
if necessary, this state can be cleaned up in the global
@code{MHD_RequestCompletedCallback} (which can be set with the
@code{MHD_OPTION_NOTIFY_COMPLETED}).
@end table
@end deftypefn
@deftypefn {Function Pointer} void {*MHD_RequestCompletedCallback} (void *cls, struct MHD_Connectionconnection, void **con_cls, enum MHD_RequestTerminationCode toe)
Signature of the callback used by @mhd{} to notify the application about
completed requests.
@table @var
@item cls
custom value selected at callback registration time;
@item connection
connection handle;
@item con_cls
value as set by the last call to the
@code{MHD_AccessHandlerCallback};
@item toe
reason for request termination see @code{MHD_OPTION_NOTIFY_COMPLETED}.
@end table
@end deftypefn
@deftypefn {Function Pointer} int {*MHD_KeyValueIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
Iterator over key--value pairs. This iterator can be used to iterate
over all of the cookies, headers, or @code{POST}--data fields of a
request, and also to iterate over the headers that have been added to a
response.
Return @code{MHD_YES} to continue iterating, @code{MHD_NO} to abort the
iteration.
@end deftypefn
@deftypefn {Function Pointer} int {*MHD_ContentReaderCallback} (void *cls, size_t pos, char *buf, int max)
Callback used by @mhd{} in order to obtain content. The callback has to
copy at most @var{max} bytes of content into @var{buf}. The total
number of bytes that has been placed into @var{buf} should be returned.
Note that returning zero will cause @mhd{} to try again, either
``immediately'' if in multi--threaded mode (in which case the callback
may want to do blocking operations) or in the next round if MHD_run is
used. Returning zero for a daemon that runs in internal
@cfunction{select} mode is an error (since it would result in busy
waiting) and will cause the program to be aborted (@cfunction{abort}).
@table @var
@item cls
custom value selected at callback registration time;
@item pos
position in the datastream to access; note that if an
@code{MHD_Response} object is re--used, it is possible for the same
content reader to be queried multiple times for the same data; however,
if an @code{MHD_Response} is not re--used, @mhd{} guarantees that
@var{pos} will be the sum of all non--negative return values obtained
from the content reader so far.
@end table
Return @code{-1} on error (@mhd{} will no longer try to read content and
instead close the connection with the client).
@end deftypefn
@deftypefn {Function Pointer} void {*MHD_ContentReaderFreeCallback} (void *cls)
This method is called by @mhd{} if we are done with a content reader.
It should be used to free resources associated with the content reader.
@end deftypefn
@deftypefn {Function Pointer} int {*MHD_PostDataIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, size_t off, size_t size)
Iterator over key--value pairs where the value maybe made available in
increments and/or may not be zero--terminated. Used for processing
@code{POST} data.
@table @var
@item cls
custom value selected at callback registration time;
@item kind
type of the value;
@item key
zero--terminated key for the value;
@item filename
name of the uploaded file, @null{} if not known;
@item content_type
mime--type of the data, @null{} if not known;
@item transfer_encoding
encoding of the data, @null{} if not known;
@item data
pointer to size bytes of data at the specified offset;
@item off
offset of data in the overall value;
@item size
number of bytes in data available.
@end table
Return @code{MHD_YES} to continue iterating, @code{MHD_NO} to abort the
iteration.
@end deftypefn
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd init
@appendixsec Starting and stopping the server
@deftypefun {struct MHD_Daemon *} MHD_start_daemon (unsigned int flags, unsigned short port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, ...)
Start a webserver on the given port.
@table @var
@item flags
OR--ed combination of @code{MHD_FLAG} values;
@item port
port to bind to;
@item apc
callback to call to check which clients will be allowed to connect; you
can pass @null{} in which case connections from any @acronym{IP} will be
accepted;
@item apc_cls
extra argument to @var{apc};
@item dh
default handler for all @uri{}s;
@item dh_cls
extra argument to @var{dh}.
@end table
Additional arguments are a list of options (type--value pairs,
terminated with @code{MHD_OPTION_END}). It is mandatory to use
@code{MHD_OPTION_END} as last argument, even when there are no
additional arguments.
Return @null{} on error, handle to daemon on success.
@end deftypefun
@deftypefun void MHD_stop_daemon (struct MHD_Daemon *daemon)
Shutdown an @http{} daemon.
@end deftypefun
@deftypefun int MHD_run (struct MHD_Daemon *daemon)
Run webserver operations (without blocking unless in client callbacks).
This method should be called by clients in combination with
@cfunction{MHD_get_fdset} if the client--controlled @cfunction{select}
method is used.
Return @code{MHD_YES} on success, @code{MHD_NO} if this daemon was not
started with the right options for this call.
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd inspect
@appendixsec Inspection
@deftypefun int MHD_get_fdset (struct MHD_Daemon *daemon, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd)
Obtain the @cfunction{select} sets for this daemon. The daemon's socket
is added to @var{read_fd_set}. The list of currently existent
connections is scanned and their file descriptors added to the correct
set.
@glibcref{Waiting for I/O}, for details on file descriptor sets.
After the call completed successfully: the variable referenced by
@var{max_fd} references the file descriptor with highest integer
identifier. The variable must be set to zero before invoking this
function.
Return @code{MHD_YES} on success, @code{MHD_NO} if: the arguments are
invalid (example: @null{} pointers); this daemon was not started with
the right options for this call.
@end deftypefun
@deftypefun int MHD_get_timeout (struct MHD_Daemon *daemon, unsigned long long *timeout)
Obtain timeout value for select for this daemon (only needed if
connection timeout is used). The returned value is how long
@cfunction{select} should at most block, not the timeout value set for
connections.
@table @var
@item timeout
set to the timeout (in milliseconds).
@end table
Return @code{MHD_YES} on success, @code{MHD_NO} if timeouts are not used
(or no connections exist that would necessiate the use of a timeout
right now).
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd requests
@appendixsec Handling requests
@menu
* microhttpd handlers:: @uri{} specific handlers.
* microhttpd values:: Connection headers and small
@code{POST} data.
@end menu
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd handlers
@appendixsubsec @uri{} specific handlers
@noindent
A set of callbacks can be registered in the state of a daemon
(@code{MHD_Daemon}) to handle request for specific sets of
resources. The set is selected by specifying the prefix string of the
@uri{}, example:
@example
/bookcase
@end example
@noindent
matches all of the following:
@example
/bookcase/book.html
/bookcase/pencil.html
/bookcase/strawberry.html
@end example
Handlers are stored in a linked list (managed with @cfunction{malloc}
and @cfunction{free}). Prefixes are compared with @cfunction{strcmp}.
@deftypefun int MHD_register_handler (struct MHD_Daemon *daemon, const char *uri_prefix, MHD_AccessHandlerCallback dh, void *dh_cls)
Register an access handler for all @uri{}s beginning with
@var{uri_prefix}, a zero--terminated @ascii{}--coded string.
Return @code{MRI_NO} if: the arguments are invalid (example: @null{}
pointers); a handler for this exact prefix already exists; an error
allocating memory happens.
@end deftypefun
@deftypefun int MHD_unregister_handler (struct MHD_Daemon *daemon, const char *uri_prefix, MHD_AccessHandlerCallback dh, void *dh_cls)
Unregister an access handler for the @uri{}s beginning with
@var{uri_prefix}.
Return @code{MHD_NO} if: the arguments are invalid (example: @null{}
pointers); a handler for this exact prefix is not known for this daemon.
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd values
@appendixsubsec Connection headers and small @code{POST} data
@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{iterator} callback is invoked once for each header, with
@var{iterator_cls} as first argument. Return the number of entries
iterated over; this can be less than the number of headers if, while
iterating, @var{iterator} returns @code{MHD_NO}.
@var{iterator} can be @null{}: in this case this function just counts
and returns the number of headers.
@end deftypefun
@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). @var{key} must
reference a zero--terminated @ascii{}--coded string representing the
header to look for: it is compared against the headers using
@cfunction{strcasecmp}, so case is ignored. Return @null{} if no such
item was found.
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd responses
@appendixsec Building answers to responses
@menu
* microhttpd response enqueue:: Enqueuing a response.
* microhttpd response create:: Creating a response object.
* microhttpd response headers:: Adding headers to a response.
* microhttpd response inspect:: Inspecting a response object.
@end menu
@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.
In the simplest case: we allocate a new @code{MHD_Response} structure
for each response, we use it once and finally we destroy it.
@mhd{} allows more efficient resources usages.
Example: we allocate a new @code{MHD_Response} structure for each
response @strong{kind}, we use it every time we have to give that
responce and we finally destroy it only when the daemon shuts down.
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd response enqueue
@appendixsubsec Enqueuing a response
@deftypefun int 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
(increment the reference counter).
@table @var
@item connection
the connection identifying the client;
@item status_code
@http{} status code (i.e. @code{200} for OK);
@item response
response to transmit.
@end table
Return @code{MHD_YES} on success or if message has been queued. Return
@code{MHD_NO}: if arguments are invalid (example: @null{} pointer); on
error (i.e. reply already sent).
@end deftypefun
@deftypefun void MHD_destroy_response (struct MHD_Response *response)
Destroy 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 immediatley.
@end deftypefun
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 @cfunction{Tcl_IncrRefCount} and
@cfunction{Tcl_DecrRefCount}.}:
@enumerate
@item
a @code{MHD_Response} object is allocated:
@example
struct MHD_Response * response = MHD_create_response_from_data(...);
/* here: reference counter = 1 */
@end example
@item
the @code{MHD_Response} object is enqueued in a @code{MHD_Connection}:
@example
MHD_queue_response(connection, , response);
/* here: reference counter = 2 */
@end example
@item
the creator of the response object discharges responsibility for it:
@example
MHD_destroy_response(response);
/* here: reference counter = 1 */
@end example
@item
the daemon handles the connection sending the response's data to the
client then decrements the reference counter by calling
@cfunction{MHD_destroy_response}: the counter's value drops to zero and
the @code{MHD_Response} object is released.
@end enumerate
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd response create
@appendixsubsec Creating response objects
@deftypefun {struct MHD_Response *} MHD_create_response_from_callback (size_t size, unsigned int 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.
@table @var
@item size
size of the data portion of the response, @code{-1} for unknown;
@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;
@item crc
callback to use to obtain response data;
@item crc_cls
extra argument to @var{crc};
@item crfc
callback to call to free @var{crc_cls} resources.
@end table
Return @null{} on error (i.e. invalid arguments, out of memory).
@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.
@table @var
@item size
size of the data portion of the response;
@item data
the data itself;
@item must_free
if true: @mhd{} should free data when done;
@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.
@end table
Return @null{} on error (i.e. invalid arguments, out of memory).
@end deftypefun
Example: create a response from a statically allocated string:
@example
const char * data = "<html><body><p>Error!</p></body></html>";
struct MHD_Connection * connection = ...;
struct MHD_Response * response;
response = MHD_create_response_from_data(strlen(data), data,
MHD_NO, MHD_NO);
MHD_queue_response(connection, 404, response);
MHD_destroy_response(response);
@end example
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd response headers
@appendixsubsec Adding headers to a response
@deftypefun int 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.
Return @code{MHD_NO} on error (i.e. invalid header or content format or
memory allocation error).
@end deftypefun
@deftypefun int MHD_del_response_header (struct MHD_Response *response, const char *header, const char *content)
Delete a header line from the response. Return @code{MHD_NO} on error
(arguments are invalid or no such header known).
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd response inspect
@appendixsubsec 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 @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 @null{} if header does not exist or @var{key} is @null{}.
We should not modify the value, unless we know what we are doing.
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd post
@appendixsec Adding a @code{POST} processor
@menu
* microhttpd post api:: Programming interface for the
@code{POST} processor.
@end menu
@noindent
When a small amount of data comes from a client's @code{POST} request:
the data is available through the values interface. @ref{microhttpd
values}, for details. In this case @mhd{} invokes
@code{MHD_AccessHandlerCallback} only once and the callback must process
all the data during that invocation.
When a big amount of data comes from a client's @code{POST} request: the
@code{MHD_AccessHandlerCallback} will be invoked multiple times to
process data as it arrives; at each invocation a new chunk of data must
be processed. The arguments @var{upload_data} and @var{upload_data_size}
are used to reference the chunk of data.
When @code{MHD_AccessHandlerCallback} is invoked for a new connection:
its @code{*@var{con_cls}} argument is set to @null{}. When @code{POST}
data comes in the upload buffer it is @strong{mandatory} to use the
@var{con_cls} to hold data or to mark an ongoing process.
To detect that a new connection has come with the @code{POST} method:
@example
int
access_handler (void *cls,
struct MHD_Connection * connection,
const char *url,
const char *method, const char *version,
const char *upload_data, unsigned int *upload_data_size,
void **con_cls)
@{
static int old_connection_marker;
int new_connection = (NULL == *con_cls);
int method_is_post = strcmp("POST",method);
if (new_connection && method_is_post)
@{
/* new connection with POST */
*con_cls = &old_connection_marker;
@}
...
@}
@end example
@noindent
in this example the value of @code{*con_cls} is just an unused pointer
to an unused integer: its purpose is to make @code{*con_cls} different
from @null{}. When serious processing of @code{POST} data is needed: it
can be a pointer to a dynamically allocated data structure.
To detect that @code{POST} data is in the upload buffer:
@example
int
access_handler (void *cls,
struct MHD_Connection * connection,
const char *url,
const char *method, const char *version,
const char *upload_data, unsigned int *upload_data_size,
void **con_cls)
@{
static int old_connection_marker;
int new_connection = (NULL == *con_cls);
int method_is_post = strcmp("POST",method);
if (new_connection && method_is_post)
@{
int data_in_upload_buffer = (0 != *upload_data_size);
if (data_in_upload_buffer)
@{
*con_cls = &old_connection_marker;
/* POST data in the buffer */
@}
else
/* POST data accessible with the values API */
@}
...
@}
@end example
At each invocation there are two options:
@enumerate
@item
the callback can process the whole chunk by itself; every time @mhd{}
invokes it a new chunk is fully processed; with this mode the callback
has to @code{*upload_data_size = 0} before returning @code{MHD_YES};
@item
the callback can process a section of the chunk by itself; every time
@mhd{} invokes it the buffer holds the old data as well as new data
coming from the client; with this mode the callback has to set
@code{*upload_data_size} to the numbe of bytes still to process before
returning @code{MHD_YES};
example: @mhd{} invokes the callback with @code{100 ==
*upload_data_size}; the callback processes the first 80 bytes and before
returning the callback sets @code{*upload_data_size = 20}; the last
unprocessed 20 bytes will be the first 20 at the next invocation;
@item
when a new connection with @code{POST} data in the buffer comes: the
callback allocates a PostProcessor and hand to it the responsibility of
processing data; a pointer to the PostProcessor structure is saved in
@code{*con_cls}, so that it is available at each subsequent invocation;
the post processor data can be freed by a later invocation to an
appropriate callback.
@end enumerate
Let's see how to implement strategy 1:
@example
int
access_handler (void *cls,
struct MHD_Connection * connection,
const char *url,
const char *method, const char *version,
const char *upload_data, unsigned int *upload_data_size,
void **con_cls)
@{
static int old_connection_marker;
int new_connection = (NULL == *con_cls);
int method_is_post = strcmp("POST",method);
if (new_connection && method_is_post)
@{
int data_in_upload_buffer = (0 != *upload_data_size);
if (data_in_upload_buffer)
@{
*con_cls = &old_connection_marker;
@}
else
@{
/* POST data accessible with the values API */
return MHD_YES;
@}
@}
if (&old_connection_marker == *con_cls)
@{
consume_data(upload_data, *upload_data_size);
*upload_data_size = 0;
return MHD_YES;
@}
/* process other methods */
return MHD_YES;
@}
@end example
Let's see how to implement strategy 2:
@example
int
access_handler (void *cls,
struct MHD_Connection * connection,
const char *url,
const char *method, const char *version,
const char *upload_data, unsigned int *upload_data_size,
void **con_cls)
@{
static int old_connection_marker;
int new_connection = (NULL == *con_cls);
int method_is_post = strcmp("POST",method);
if (new_connection && method_is_post)
@{
int data_in_upload_buffer = (0 != *upload_data_size);
if (data_in_upload_buffer)
@{
*con_cls = &old_connection_marker;
@}
else
@{
/* POST data accessible with the values API */
return MHD_YES;
@}
@}
if (&old_connection_marker == *con_cls)
@{
int number_of_bytes_to_consume = 100;
if (number_of_bytes_to_consume > *upload_data_size)
number_of_bytes_to_consume = *upload_data_size;
consume_some_data(upload_data, number_of_bytes_to_consume);
*upload_data_size -= number_of_bytes_to_consume;
return MHD_YES;
@}
/* process other methods */
return MHD_YES;
@}
@end example
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd post api
@appendixsubsec Programming interface for the @code{POST} processor
@deftypefun {struct MHD_PostProcessor *} MHD_create_post_processor (struct MHD_Connection *connection, unsigned int buffer_size, MHD_PostDataIterator iterator, void *iterator_cls)
Create a PostProcessor. A PostProcessor can be used to (incrementally)
parse the data portion of a @code{POST} request.
@table @var
@item connection
the connection on which the @code{POST} is happening (used to determine
the @code{POST} format);
@item buffer_size
maximum number of bytes to use for internal buffering (used only for the
parsing, specifically the parsing of the keys). A tiny value (256-1024)
should be sufficient; do @strong{NOT} use a value smaller than 256;
@item iterator
iterator to be called with the parsed data; must @strong{NOT} be
@null{};
@item iterator_cls
custom value to be used as first argument to @var{iterator}.
@end table
Return @null{} on error (out of memory, unsupported encoding), otherwise
a PP handle.
@end deftypefun
@deftypefun int MHD_post_process (struct MHD_PostProcessor *pp, const char *post_data, unsigned int post_data_len)
Parse and process @code{POST} data. Call this function when @code{POST}
data is available (usually during an @code{MHD_AccessHandlerCallback})
with the @var{upload_data} and @var{upload_data_size}. Whenever
possible, this will then cause calls to the
@code{MHD_IncrementalKeyValueIterator}.
@table @var
@item pp
the post processor;
@item post_data
@var{post_data_len} bytes of @code{POST} data;
@item post_data_len
length of @var{post_data}.
@end table
Return @code{MHD_YES} on success, @code{MHD_NO} on error
(out--of--memory, iterator aborted, parse error).
@end deftypefun
@deftypefun void MHD_destroy_post_processor (struct MHD_PostProcessor *pp)
Release PostProcessor resources.
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+7482
View File
File diff suppressed because it is too large Load Diff