mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
docs from Marco Maggi
This commit is contained in:
+5
-1
@@ -1,3 +1,7 @@
|
||||
|
||||
man_MANS = libmicrohttpd.3
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
||||
#DISTCLEANFILES = microhttpd.cps
|
||||
#info_TEXINFOS = microhttpd.texi
|
||||
#microhttpd_TEXINFOS = gpl.texi
|
||||
|
||||
|
||||
+397
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user