summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2004-10-02 18:47:02 +0000
committerjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2004-10-02 18:47:02 +0000
commit0294ff3d3282d1b1c5497f00ea25e5e55e6f4338 (patch)
tree978af6f81c7b7715597871b1e89a9ad083907f1a /doc
downloadneon-0294ff3d3282d1b1c5497f00ea25e5e55e6f4338.tar.gz
Import neon 0.24.0 to begin 0.24.x branch.
git-svn-id: http://svn.webdav.org/repos/projects/neon/branches/0.24.x@243 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
Diffstat (limited to 'doc')
-rw-r--r--doc/.cvsignore13
-rw-r--r--doc/TODO156
-rw-r--r--doc/fdl.sgml466
-rw-r--r--doc/feat.xml78
-rw-r--r--doc/html.xsl70
-rw-r--r--doc/manual.css42
-rw-r--r--doc/manual.xml167
-rw-r--r--doc/parsing-xml.txt170
-rw-r--r--doc/ref/alloc.xml88
-rw-r--r--doc/ref/auth.xml114
-rw-r--r--doc/ref/buf.xml53
-rw-r--r--doc/ref/bufapp.xml89
-rw-r--r--doc/ref/bufcr.xml60
-rw-r--r--doc/ref/bufdest.xml81
-rw-r--r--doc/ref/bufutil.xml62
-rw-r--r--doc/ref/clicert.xml153
-rw-r--r--doc/ref/config.xml124
-rw-r--r--doc/ref/err.xml66
-rw-r--r--doc/ref/getst.xml63
-rw-r--r--doc/ref/iaddr.xml124
-rw-r--r--doc/ref/init.xml55
-rw-r--r--doc/ref/neon.xml145
-rw-r--r--doc/ref/opts.xml126
-rw-r--r--doc/ref/req.xml169
-rw-r--r--doc/ref/reqbody.xml69
-rw-r--r--doc/ref/reqhdr.xml63
-rw-r--r--doc/ref/resolve.xml145
-rw-r--r--doc/ref/sess.xml123
-rw-r--r--doc/ref/shave.xml51
-rw-r--r--doc/ref/sslca.xml81
-rw-r--r--doc/ref/sslcert.xml66
-rw-r--r--doc/ref/ssldname.xml66
-rw-r--r--doc/ref/sslvfy.xml140
-rw-r--r--doc/ref/status.xml74
-rw-r--r--doc/ref/tok.xml76
-rw-r--r--doc/ref/vers.xml63
-rw-r--r--doc/refentry.xml56
-rw-r--r--doc/using-neon.txt166
-rw-r--r--doc/using.xml119
-rw-r--r--doc/xml.xml207
40 files changed, 4299 insertions, 0 deletions
diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644
index 0000000..30791a1
--- /dev/null
+++ b/doc/.cvsignore
@@ -0,0 +1,13 @@
+*.?
+*.html
+*.pdf
+*.ps
+*.tex
+*.sgml
+*.junk
+html
+man
+man3
+man1
+version.xml
+date.xml
diff --git a/doc/TODO b/doc/TODO
new file mode 100644
index 0000000..febed30
--- /dev/null
+++ b/doc/TODO
@@ -0,0 +1,156 @@
+/* List of interfaces needing reference documentation. -*- c -*- */
+
+/* ne_session.h */
+
+### DONE: basics
+ne_session *ne_session_create(const char *scheme, const char *hostname, int port);
+void ne_session_destroy(ne_session *sess);
+void ne_close_connection(ne_session *sess);
+void ne_session_proxy(ne_session *sess, const char *hostname, int port);
+
+### DONE: error handling
+void ne_set_error(ne_session *sess, const char *format, ...);
+const char *ne_get_error(ne_session *sess);
+
+### DONE: options
+void ne_set_useragent(ne_session *sess, const char *product);
+void ne_set_expect100(ne_session *sess, int use_expect100);
+void ne_set_persist(ne_session *sess, int persist);
+void ne_set_read_timeout(ne_session *sess, int timeout);
+
+### TODO: progress + status callbcacks
+void ne_set_progress(ne_session *sess, ne_progress progress, void *userdata);
+
+### TODO: status callback
+typedef enum ne_conn_status;
+typedef void (*ne_notify_status)(void *userdata, ne_conn_status status, const char *info);
+void ne_set_status(ne_session *sess, ne_notify_status status, void *userdata);
+
+### DONE: SSL verification
+
+typedef struct ne_ssl_dname;
+char *ne_ssl_readable_dname(const ne_ssl_dname *dn);
+typedef struct ne_ssl_certificate;
+#define NE_SSL_*
+typedef int (*ne_ssl_verify_fn)(void *userdata, int failures,
+ const ne_ssl_certificate *cert);
+void ne_ssl_set_verify(ne_session *sess, ne_ssl_verify_fn fn, void *userdata);
+
+### DONE: SSL server certs
+int ne_ssl_load_ca(ne_session *sess, const char *file);
+int ne_ssl_load_default_ca(ne_session *sess);
+
+### TODO: SSL client certs
+typedef int (*ne_ssl_keypw_fn)(void *userdata, char *pwbuf, size_t len);
+void ne_ssl_keypw_prompt(ne_session *sess, ne_ssl_keypw_fn fn, void *ud);
+int ne_ssl_load_pkcs12(ne_session *sess, const char *fn);
+int ne_ssl_load_pem(ne_session *sess, const char *certfn, const char *keyfn);
+typedef void (*ne_ssl_provide_fn)(void *userdata, ne_session *sess,
+ const ne_ssl_dname *server);
+void ne_ssl_provide_ccert(ne_session *sess, ne_ssl_provide_fn fn, void *userdata);
+
+#ifdef NEON_SSL
+SSL_CTX *ne_ssl_get_context(ne_session *sess);
+X509 *ne_ssl_server_cert(ne_session *req);
+#endif
+
+### TODO: utility functions
+int ne_version_pre_http11(ne_session *sess);
+const char *ne_get_server_hostport(ne_session *sess);
+const char *ne_get_scheme(ne_session *sess);
+void ne_fill_server_uri(ne_session *sess, ne_uri *uri);
+
+/* end of ne_session.h *****************************************/
+
+/* ne_request.h */
+
+### DONE: request basics
+ne_request *ne_request_create(ne_session *sess, const char *method, const char *path);
+int ne_request_dispatch(ne_request *req);
+void ne_request_destroy(ne_request *req);
+
+### DONE: request status
+const ne_status *ne_get_status(ne_request *req);
+
+### TODO: request bodies
+void ne_set_request_body_buffer(ne_request *req, const char *buf, size_t count);
+int ne_set_request_body_fd(ne_request *req, int fd, size_t count);
+
+typedef ssize_t (*ne_provide_body)(void *userdata,
+ char *buffer, size_t buflen);
+void ne_set_request_body_provider(ne_request *req, size_t size,
+ ne_provide_body provider, void *userdata);
+
+### TODO: response bodies
+typedef int (*ne_accept_response)(void *userdata, ne_request *req, ne_status *st);
+int ne_accept_2xx(void *userdata, ne_request *req, ne_status *st);
+int ne_accept_always(void *userdata, ne_request *req, ne_status *st);
+void ne_add_response_body_reader(ne_request *req, ne_accept_response accpt,
+ ne_block_reader reader, void *userdata);
+
+### TODO: response headers
+typedef void (*ne_header_handler)(void *userdata, const char *value);
+void ne_add_response_header_handler(ne_request *req, const char *name,
+ ne_header_handler hdl, void *userdata);
+void ne_add_response_header_catcher(ne_request *req,
+ ne_header_handler hdl, void *userdata);
+
+void ne_duplicate_header(void *userdata, const char *value);
+void ne_handle_numeric_header(void *userdata, const char *value);
+
+### DONE: request headers
+void ne_add_request_header(ne_request *req, const char *name, const char *value);
+void ne_print_request_header(ne_request *req, const char *name, const char *format, ...);
+
+### TODO: misc
+ne_session *ne_get_session(ne_request *req);
+
+### TODO: caller-pulls request interface
+int ne_begin_request(ne_request *req);
+int ne_end_request(ne_request *req);
+ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen);
+
+### TODO: hooks
+typedef void (*ne_free_hooks)(void *cookie);
+typedef void (*ne_create_request_fn)(void *userdata, ne_request *req,
+ const char *method, const char *path);
+void ne_hook_create_request(ne_session *sess, ne_create_request_fn fn, void *userdata);
+
+typedef void (*ne_pre_send_fn)(void *userdata, ne_buffer *header);
+void ne_hook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata);
+
+typedef int (*ne_post_send_fn)(void *userdata, const ne_status *status);
+void ne_hook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata);
+
+typedef void (*ne_destroy_fn)(void *userdata);
+void ne_hook_destroy_request(ne_session *sess, ne_destroy_fn fn, void *userdata);
+
+void ne_hook_destroy_session(ne_session *sess, ne_destroy_fn fn, void *userdata);
+
+typedef void *(*ne_accessor_fn)(void *userdata);
+void ne_hook_session_accessor(ne_session *sess, const char *id, ne_accessor_fn, void *userdata);
+void ne_hook_request_accessor(ne_request *req, const char *id, ne_accessor_fn, void *userdata);
+
+void *ne_null_accessor(void *userdata);
+
+void *ne_session_hook_private(ne_session *sess, const char *id);
+
+void *ne_request_hook_private(ne_request *req, const char *id);
+
+/* ne_207.h */
+/* ne_acl.h */
+/* DONE: ne_alloc.h */
+/* DONE: ne_auth.h */
+/* ne_basic.h */
+/* ne_compress.h */
+/* ne_cookies.h */
+/* ne_dates.h */
+/* ne_locks.h */
+/* ne_props.h */
+/* ne_redirect.h */
+/* ne_socket.h */
+/* MOSTLY DONE: ne_string.h */
+/* ne_uri.h */
+/* ne_utils.h */
+/* ne_xml.h */
+
diff --git a/doc/fdl.sgml b/doc/fdl.sgml
new file mode 100644
index 0000000..37470db
--- /dev/null
+++ b/doc/fdl.sgml
@@ -0,0 +1,466 @@
+<appendix id="gfdl">
+<title>GNU Free Documentation License</title>
+<!-- - GNU Project - Free Software Foundation (FSF) -->
+<!-- LINK REV="made" HREF="mailto:webmasters@gnu.org" -->
+
+
+ <!-- sect1>
+ <title>GNU Free Documentation License</title -->
+
+ <para>Version 1.1, March 2000</para>
+
+ <blockquote>
+ <para>Copyright (C) 2000 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.</para>
+ </blockquote>
+
+ <sect1 label="0">
+ <title>PREAMBLE</title>
+
+ <para>The purpose of this License is to make a manual, textbook,
+ or other written document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by
+ others.</para>
+
+ <para>This License is a kind of "copyleft", which means that
+ derivative works of the document must themselves be free in the
+ same sense. It complements the GNU General Public License, which
+ is a copyleft license designed for free software.</para>
+
+ <para>We have designed this License in order to use it for manuals
+ for free software, because free software needs free documentation:
+ a free program should come with manuals providing the same
+ freedoms that the software does. But this License is not limited
+ to software manuals; it can be used for any textual work,
+ regardless of subject matter or whether it is published as a
+ printed book. We recommend this License principally for works
+ whose purpose is instruction or reference.</para>
+ </sect1>
+
+ <sect1 label="1">
+ <title>APPLICABILITY AND DEFINITIONS</title>
+
+ <para>This License applies to any manual or other work that
+ contains a notice placed by the copyright holder saying it can be
+ distributed under the terms of this License. The "Document",
+ below, refers to any such manual or work. Any member of the
+ public is a licensee, and is addressed as "you".</para>
+
+ <para>A "Modified Version" of the Document means any work
+ containing the Document or a portion of it, either copied
+ verbatim, or with modifications and/or translated into another
+ language.</para>
+
+ <para>A "Secondary Section" is a named appendix or a front-matter
+ section of the Document that deals exclusively with the
+ relationship of the publishers or authors of the Document to the
+ Document's overall subject (or to related matters) and contains
+ nothing that could fall directly within that overall subject.
+ (For example, if the Document is in part a textbook of
+ mathematics, a Secondary Section may not explain any mathematics.)
+ The relationship could be a matter of historical connection with
+ the subject or with related matters, or of legal, commercial,
+ philosophical, ethical or political position regarding
+ them.</para>
+
+ <para>The "Invariant Sections" are certain Secondary Sections
+ whose titles are designated, as being those of Invariant Sections,
+ in the notice that says that the Document is released under this
+ License.</para>
+
+ <para>The "Cover Texts" are certain short passages of text that
+ are listed, as Front-Cover Texts or Back-Cover Texts, in the
+ notice that says that the Document is released under this
+ License.</para>
+
+ <para>A "Transparent" copy of the Document means a
+ machine-readable copy, represented in a format whose specification
+ is available to the general public, whose contents can be viewed
+ and edited directly and straightforwardly with generic text
+ editors or (for images composed of pixels) generic paint programs
+ or (for drawings) some widely available drawing editor, and that
+ is suitable for input to text formatters or for automatic
+ translation to a variety of formats suitable for input to text
+ formatters. A copy made in an otherwise Transparent file format
+ whose markup has been designed to thwart or discourage subsequent
+ modification by readers is not Transparent. A copy that is not
+ "Transparent" is called "Opaque".</para>
+
+ <para>Examples of suitable formats for Transparent copies include
+ plain ASCII without markup, Texinfo input format, LaTeX input
+ format, SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML designed for human modification.
+ Opaque formats include PostScript, PDF, proprietary formats that
+ can be read and edited only by proprietary word processors, SGML
+ or XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML produced by some word
+ processors for output purposes only.</para>
+
+ <para>The "Title Page" means, for a printed book, the title page
+ itself, plus such following pages as are needed to hold, legibly,
+ the material this License requires to appear in the title page.
+ For works in formats which do not have any title page as such,
+ "Title Page" means the text near the most prominent appearance of
+ the work's title, preceding the beginning of the body of the
+ text.</para>
+ </sect1>
+
+ <sect1 label="2">
+ <title>VERBATIM COPYING</title>
+
+ <para>You may copy and distribute the Document in any medium,
+ either commercially or noncommercially, provided that this
+ License, the copyright notices, and the license notice saying this
+ License applies to the Document are reproduced in all copies, and
+ that you add no other conditions whatsoever to those of this
+ License. You may not use technical measures to obstruct or
+ control the reading or further copying of the copies you make or
+ distribute. However, you may accept compensation in exchange for
+ copies. If you distribute a large enough number of copies you
+ must also follow the conditions in section 3.</para>
+
+ <para>You may also lend copies, under the same conditions stated
+ above, and you may publicly display copies.</para>
+ </sect1>
+
+ <sect1 label="3">
+ <title>COPYING IN QUANTITY</title>
+
+ <para>If you publish printed copies of the Document numbering more
+ than 100, and the Document's license notice requires Cover Texts,
+ you must enclose the copies in covers that carry, clearly and
+ legibly, all these Cover Texts: Front-Cover Texts on the front
+ cover, and Back-Cover Texts on the back cover. Both covers must
+ also clearly and legibly identify you as the publisher of these
+ copies. The front cover must present the full title with all
+ words of the title equally prominent and visible. You may add
+ other material on the covers in addition. Copying with changes
+ limited to the covers, as long as they preserve the title of the
+ Document and satisfy these conditions, can be treated as verbatim
+ copying in other respects.</para>
+
+ <para>If the required texts for either cover are too voluminous to
+ fit legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.</para>
+
+ <para>If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a publicly-accessible
+ computer-network location containing a complete Transparent copy
+ of the Document, free of added material, which the general
+ network-using public has access to download anonymously at no
+ charge using public-standard network protocols. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.</para>
+
+ <para>It is requested, but not required, that you contact the
+ authors of the Document well before redistributing any large
+ number of copies, to give them a chance to provide you with an
+ updated version of the Document.</para>
+ </sect1>
+
+ <sect1 label="4">
+ <title>MODIFICATIONS</title>
+
+ <para>You may copy and distribute a Modified Version of the
+ Document under the conditions of sections 2 and 3 above, provided
+ that you release the Modified Version under precisely this
+ License, with the Modified Version filling the role of the
+ Document, thus licensing distribution and modification of the
+ Modified Version to whoever possesses a copy of it. In addition,
+ you must do these things in the Modified Version:</para>
+
+ <orderedlist numeration="upperalpha">
+ <listitem><para>Use in the Title Page
+ (and on the covers, if any) a title distinct from that of the
+ Document, and from those of previous versions (which should, if
+ there were any, be listed in the History section of the
+ Document). You may use the same title as a previous version if
+ the original publisher of that version gives permission.</para>
+ </listitem>
+
+ <listitem><para>List on the Title Page,
+ as authors, one or more persons or entities responsible for
+ authorship of the modifications in the Modified Version,
+ together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has less than
+ five).</para>
+ </listitem>
+
+ <listitem><para>State on the Title page
+ the name of the publisher of the Modified Version, as the
+ publisher.</para>
+ </listitem>
+
+ <listitem><para>Preserve all the
+ copyright notices of the Document.</para>
+ </listitem>
+
+ <listitem><para>Add an appropriate
+ copyright notice for your modifications adjacent to the other
+ copyright notices.</para>
+ </listitem>
+
+ <listitem><para>Include, immediately
+ after the copyright notices, a license notice giving the public
+ permission to use the Modified Version under the terms of this
+ License, in the form shown in the Addendum below.</para>
+ </listitem>
+
+ <listitem><para>Preserve in that license
+ notice the full lists of Invariant Sections and required Cover
+ Texts given in the Document's license notice.</para>
+ </listitem>
+
+ <listitem><para>Include an unaltered
+ copy of this License.</para>
+ </listitem>
+
+ <listitem><para>Preserve the section
+ entitled "History", and its title, and add to it an item stating
+ at least the title, year, new authors, and publisher of the
+ Modified Version as given on the Title Page. If there is no
+ section entitled "History" in the Document, create one stating
+ the title, year, authors, and publisher of the Document as given
+ on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.</para>
+ </listitem>
+
+ <listitem><para>Preserve the network
+ location, if any, given in the Document for public access to a
+ Transparent copy of the Document, and likewise the network
+ locations given in the Document for previous versions it was
+ based on. These may be placed in the "History" section. You
+ may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.</para>
+ </listitem>
+
+ <listitem><para>In any section entitled
+ "Acknowledgements" or "Dedications", preserve the section's
+ title, and preserve in the section all the substance and tone of
+ each of the contributor acknowledgements and/or dedications
+ given therein.</para>
+ </listitem>
+
+ <listitem><para>Preserve all the
+ Invariant Sections of the Document, unaltered in their text and
+ in their titles. Section numbers or the equivalent are not
+ considered part of the section titles.</para>
+ </listitem>
+
+ <listitem><para>Delete any section
+ entitled "Endorsements". Such a section may not be included in
+ the Modified Version.</para>
+ </listitem>
+
+ <listitem><para>Do not retitle any
+ existing section as "Endorsements" or to conflict in title with
+ any Invariant Section.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If the Modified Version includes new front-matter sections
+ or appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.</para>
+
+ <para>You may add a section entitled "Endorsements", provided it
+ contains nothing but endorsements of your Modified Version by
+ various parties--for example, statements of peer review or that
+ the text has been approved by an organization as the authoritative
+ definition of a standard.</para>
+
+ <para>You may add a passage of up to five words as a Front-Cover
+ Text, and a passage of up to 25 words as a Back-Cover Text, to the
+ end of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.</para>
+
+ <para>The author(s) and publisher(s) of the Document do not by
+ this License give permission to use their names for publicity for
+ or to assert or imply endorsement of any Modified Version.</para>
+ </sect1>
+
+ <sect1 label="5">
+ <title>COMBINING DOCUMENTS</title>
+
+ <para>You may combine the Document with other documents released
+ under this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice.</para>
+
+ <para>The combined work need only contain one copy of this
+ License, and multiple identical Invariant Sections may be replaced
+ with a single copy. If there are multiple Invariant Sections with
+ the same name but different contents, make the title of each such
+ section unique by adding at the end of it, in parentheses, the
+ name of the original author or publisher of that section if known,
+ or else a unique number. Make the same adjustment to the section
+ titles in the list of Invariant Sections in the license notice of
+ the combined work.</para>
+
+ <para>In the combination, you must combine any sections entitled
+ "History" in the various original documents, forming one section
+ entitled "History"; likewise combine any sections entitled
+ "Acknowledgements", and any sections entitled "Dedications". You
+ must delete all sections entitled "Endorsements."</para>
+ </sect1>
+
+ <sect1 label="6">
+ <title>COLLECTIONS OF DOCUMENTS</title>
+
+ <para>You may make a collection consisting of the Document and
+ other documents released under this License, and replace the
+ individual copies of this License in the various documents with a
+ single copy that is included in the collection, provided that you
+ follow the rules of this License for verbatim copying of each of
+ the documents in all other respects.</para>
+
+ <para>You may extract a single document from such a collection,
+ and distribute it individually under this License, provided you
+ insert a copy of this License into the extracted document, and
+ follow this License in all other respects regarding verbatim
+ copying of that document.</para>
+ </sect1>
+
+ <sect1 label="7">
+ <title>AGGREGATION WITH INDEPENDENT WORKS</title>
+
+ <para>A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, does not as a whole count as a
+ Modified Version of the Document, provided no compilation
+ copyright is claimed for the compilation. Such a compilation is
+ called an "aggregate", and this License does not apply to the
+ other self-contained works thus compiled with the Document, on
+ account of their being thus compiled, if they are not themselves
+ derivative works of the Document.</para>
+
+ <para>If the Cover Text requirement of section 3 is applicable to
+ these copies of the Document, then if the Document is less than
+ one quarter of the entire aggregate, the Document's Cover Texts
+ may be placed on covers that surround only the Document within the
+ aggregate. Otherwise they must appear on covers around the whole
+ aggregate.</para>
+ </sect1>
+
+ <sect1 label="8">
+ <title>TRANSLATION</title>
+
+ <para>Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires
+ special permission from their copyright holders, but you may
+ include translations of some or all Invariant Sections in addition
+ to the original versions of these Invariant Sections. You may
+ include a translation of this License provided that you also
+ include the original English version of this License. In case of
+ a disagreement between the translation and the original English
+ version of this License, the original English version will
+ prevail.</para>
+ </sect1>
+
+ <sect1 label="9">
+ <title>TERMINATION</title>
+
+ <para>You may not copy, modify, sublicense, or distribute the
+ Document except as expressly provided for under this License. Any
+ other attempt to copy, modify, sublicense or distribute the
+ Document 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.</para>
+ </sect1>
+
+ <sect1 label="10">
+ <title>FUTURE REVISIONS OF THIS LICENSE</title>
+
+ <para>The Free Software Foundation may publish new, revised
+ versions of the GNU Free Documentation 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. See <ulink
+ url="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</ulink>.</para>
+
+ <para>Each version of the License is given a distinguishing
+ version number. If the Document specifies that a particular
+ numbered version of this License "or any later version" applies to
+ it, you have the option of following the terms and conditions
+ either of that specified version or of any later version that has
+ been published (not as a draft) by the Free Software Foundation.
+ If the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.</para>
+ </sect1>
+
+ <sect1 label="">
+ <title>How to use this License for your documents</title>
+
+ <para>To use this License in a document you have written, include
+ a copy of the License in the document and put the following
+ copyright and license notices just after the title page:</para>
+
+<blockquote><para>
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+</para></blockquote>
+
+ <para>If you have no Invariant Sections, write "with no Invariant
+ Sections" instead of saying which ones are invariant. If you have
+ no Front-Cover Texts, write "no Front-Cover Texts" instead of
+ "Front-Cover Texts being LIST"; likewise for Back-Cover
+ Texts.</para>
+
+ <para>If your document contains nontrivial examples of program
+ code, we recommend releasing these examples in parallel under your
+ choice of free software license, such as the GNU General Public
+ License, to permit their use in free software.</para>
+ </sect1>
+
+</appendix>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:nil
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-parent-document: ("referenz.sgml" "appendix")
+sgml-exposed-tags:nil
+sgml-local-ecat-files:nil
+sgml-local-catalogs: CATALOG
+sgml-validate-command: "nsgmls -s referenz.sgml"
+ispell-skip-sgml: t
+End:
+-->
diff --git a/doc/feat.xml b/doc/feat.xml
new file mode 100644
index 0000000..547ab9f
--- /dev/null
+++ b/doc/feat.xml
@@ -0,0 +1,78 @@
+ <sect1 id="features">
+ <title>Feature list</title>
+
+ <para>The major features of the neon library are as follows:</para>
+
+ <itemizedlist>
+
+ <listitem><para>A high-level interface to common HTTP and WebDAV
+methods. This allows you to easily dispatch a GET or a MKCOL request
+against a resource with a single function call.</para></listitem>
+
+ <listitem><para>A low-level interface for HTTP request
+handling; allowing you to implement requests using arbitrary methods
+and request headers, capture arbitrary response headers, and so
+on.</para></listitem>
+
+ <listitem><para>Persistent connection support; neon groups a
+set of requests to a server into a "session"; requests within that
+session can use a persistent (also known as "keep-alive")
+connection.</para></listitem>
+
+ <listitem><para>Modern HTTP authentication support: a complete
+implementation of the new authentication standard, RFC2617,
+supporting the Digest (MD5) and Basic schemes, including integrity
+checking. Credentials are supplied by an application-defined
+callback.</para></listitem>
+
+ <listitem><para>Proxy server support; a session can be set to
+use a proxy server. Authentication is supported for the Proxy as well
+as the origin server.</para></listitem>
+
+ <listitem><para>Complete SSL support; a simple interface for
+enabling SSL, hiding the complexity of using an SSL library directly.
+Client certificate support, callback-based server certificate
+verification, along with functions to load trusted CA
+certificates.</para></listitem>
+
+<!--
+ <listitem><para>Compression support.</para></listitem>
+-->
+
+ <listitem><para>Generic XML parsing interface for handling XML
+response bodies using SAX-like callbacks. Both the expat and libxml
+XML parser libraries are supported.</para></listitem>
+
+ <listitem><para>WebDAV metadata support; set and remove
+properties, query properties (PROPFIND); simple interface for
+retrieving "flat" byte-string properties, more advanced support for
+parsing "complex" XML structured properties.</para></listitem>
+
+<!--
+ <listitem><para>WebDAV locking support</para></listitem>
+-->
+
+ <listitem><para>Build environment support: the neon source
+tree is designed so that it can be embedded in your application's
+build tree; autoconf macros are supplied for integration. To get
+started quickly a <xref linkend="refconfig"/> script is included,
+to easily determine how to compile and link against an installed copy
+of neon</para></listitem>
+
+ <listitem><para>Complete test suite: the neon test suite
+comprises half as many lines of source code as the library itself,
+including many tests for protocol compliance in network behaviour, and
+that the library implementation meets the guarantees made by the
+API.</para> </listitem>
+
+<!--
+
+ <listitem><para>Thorough documentation: neon documentation is
+provided in HTML and man page formats (from a single DocBook XML
+source)</para></listitem>
+
+-->
+
+ </itemizedlist>
+
+ </sect1>
diff --git a/doc/html.xsl b/doc/html.xsl
new file mode 100644
index 0000000..a96867d
--- /dev/null
+++ b/doc/html.xsl
@@ -0,0 +1,70 @@
+<?xml version='1.0'?>
+
+<!-- This file wraps around the DocBook HTML XSL stylesheet to customise
+ - some parameters; add the CSS stylesheet, etc.
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'
+ xmlns="http://www.w3.org/TR/xhtml1/transitional"
+ exclude-result-prefixes="#default">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
+
+<xsl:variable name="html.stylesheet">../manual.css</xsl:variable>
+
+<!-- for sections with id attributes, use the id in the filename.
+ This produces meaningful (and persistent) URLs for the sections. -->
+<xsl:variable name="use.id.as.filename" select="1"/>
+
+<!-- enable the shaded verbatim (programlisting etc) blocks. -->
+<!-- <xsl:variable name="shade.verbatim" select="1"/> -->
+
+<!-- add class="programlisting" attribute on the <pre>s from
+ <programlisting>s so that the CSS can style them nicely. -->
+<xsl:attribute-set name="shade.verbatim.style">
+ <xsl:attribute name="class">programlisting</xsl:attribute>
+</xsl:attribute-set>
+
+<!-- use sane ANSI C function prototypes -->
+<xsl:variable name="funcsynopsis.style" select="'ansi'"/>
+
+<!-- split each sect1 into a separate chunk -->
+<xsl:variable name="chunk.first.sections" select="1"/>
+
+<!-- don't generate table of contents within each chapter chunk. -->
+<xsl:variable name="generate.chapter.toc" select="0"/>
+
+<xsl:variable name="generate.appendix.toc" select="0"/>
+
+<!-- don't include manual page numbers in refentry cross-references, they
+ look weird -->
+<xsl:variable name="refentry.xref.manvolnum" select="0"/>
+
+<!-- do generate variablelist's as tables -->
+<xsl:variable name="variablelist.as.table" select="1"/>
+
+<!-- and css'ize the tables so they can look pretty -->
+<xsl:variable name="table.borders.with.css" select="1"/>
+
+<!-- disable ugly tabular output -->
+<xsl:variable name="funcsynopsis.tabular.threshold" select="99999"/>
+
+<!-- change some presentation choices -->
+<xsl:template match="type">
+ <xsl:call-template name="inline.italicseq"/>
+</xsl:template>
+
+<xsl:template match="parameter">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<!-- enclose the whole funcprototype in <code> -->
+<xsl:template match="funcprototype" mode="ansi-nontabular">
+ <div class="funcprototype"><code>
+ <xsl:apply-templates mode="ansi-nontabular"/>
+ </code></div>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/doc/manual.css b/doc/manual.css
new file mode 100644
index 0000000..621feb5
--- /dev/null
+++ b/doc/manual.css
@@ -0,0 +1,42 @@
+
+p, pre.funcsynopsisinfo { margin-left: 0.4em; margin-right: 0.4em; }
+
+span.term { margin-left: 0.6em; margin-bottom: 0.0em }
+
+div.legalnotice { font-size: 80%; margin-left: 2em; }
+
+a:visited { color: darkgreen; }
+
+div.navheader { border-top: thin solid #bbf2bb; }
+div.navfooter { border-bottom: thin solid #bbf2bb; }
+
+div.funcprototype { margin-top: 0.2em; margin-left: 0.4em; margin-bottom: 0.2em; }
+
+pre.programlisting, pre.screen {
+ background-color: #dddddd;
+ margin-left: 0.6em; margin-right: 1em;
+ padding: 0.3em; width: 50em;
+}
+
+div.funcsynopsis, div.cmdsynopsis {
+ background-color: #dddddd;
+ margin-left: 0.4em; margin-right: 0.4em;
+ padding: 0.1em;
+}
+
+div.warning {
+ border: thin solid #777777;
+}
+
+h1.title { border-bottom: thick solid #bbf2bb; padding-bottom: 0.1em; }
+
+div.toc {
+ border-left: thick solid #bbf2bb; padding-left: 0.5em;
+ }
+
+h2, h3 { padding-left: 0.2em; padding-top: -0.1em; }
+
+h2 { background-color: #bbf2bb; font-size: 110%;
+ padding-bottom: 0.3em; padding-top: 0.2em; spacing-top: 0.1em; }
+
+h3 { border-bottom: thin solid #bbf2bb; }
diff --git a/doc/manual.xml b/doc/manual.xml
new file mode 100644
index 0000000..893f007
--- /dev/null
+++ b/doc/manual.xml
@@ -0,0 +1,167 @@
+<?xml version='1.0'?> <!-- -*- text -*- -->
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+
+<!ENTITY % isoent SYSTEM
+ "http://www.oasis-open.org/docbook/xml/4.2/ent/iso-num.ent">
+<!ENTITY % isopub SYSTEM
+ "http://www.oasis-open.org/docbook/xml/4.2/ent/iso-pub.ent">
+
+%isoent;
+%isopub;
+
+<!ENTITY fdl SYSTEM "fdl.sgml">
+
+<!-- date/version stamp files created as release tarball is rolled -->
+<!ENTITY date SYSTEM "date.xml">
+<!ENTITY version SYSTEM "version.xml">
+
+<!ENTITY neon "neon">
+
+<!-- a useful entity for writing reference examples -->
+<!ENTITY egsess "ne_session *sess = ne_session_create(...);">
+
+<!ENTITY null "<literal>NULL</literal>">
+
+<!ENTITY nul "<literal>NUL</literal>">
+
+<!-- xml.xml entities: -->
+<!ENTITY startelm "<emphasis>start-element</emphasis>">
+<!ENTITY cdata "<emphasis>character-data</emphasis>">
+<!ENTITY endelm "<emphasis>end-element</emphasis>">
+
+<!ENTITY section.xml SYSTEM "xml.xml">
+<!ENTITY section.features SYSTEM "feat.xml">
+<!ENTITY section.using SYSTEM "using.xml">
+
+<!ENTITY refneon SYSTEM "ref/neon.xml">
+<!ENTITY refconfig SYSTEM "ref/config.xml">
+
+<!ENTITY refsess SYSTEM "ref/sess.xml">
+<!ENTITY referr SYSTEM "ref/err.xml">
+<!ENTITY refopts SYSTEM "ref/opts.xml">
+<!ENTITY refsslvfy SYSTEM "ref/sslvfy.xml">
+<!ENTITY refsslcert SYSTEM "ref/sslcert.xml">
+<!ENTITY refssldname SYSTEM "ref/ssldname.xml">
+<!ENTITY refsslca SYSTEM "ref/sslca.xml">
+<!ENTITY refreq SYSTEM "ref/req.xml">
+<!ENTITY refreqhdr SYSTEM "ref/reqhdr.xml">
+<!ENTITY refstatus SYSTEM "ref/status.xml">
+<!ENTITY refgetst SYSTEM "ref/getst.xml">
+<!ENTITY refreqbody SYSTEM "ref/reqbody.xml">
+<!ENTITY refauth SYSTEM "ref/auth.xml">
+<!ENTITY refalloc SYSTEM "ref/alloc.xml">
+<!ENTITY refbuf SYSTEM "ref/buf.xml">
+<!ENTITY refbufcr SYSTEM "ref/bufcr.xml">
+<!ENTITY refbufapp SYSTEM "ref/bufapp.xml">
+<!ENTITY refbufdest SYSTEM "ref/bufdest.xml">
+<!ENTITY refbufutil SYSTEM "ref/bufutil.xml">
+<!ENTITY reftok SYSTEM "ref/tok.xml">
+<!ENTITY refshave SYSTEM "ref/shave.xml">
+<!ENTITY refvers SYSTEM "ref/vers.xml">
+<!ENTITY refinit SYSTEM "ref/init.xml">
+<!ENTITY refresolve SYSTEM "ref/resolve.xml">
+<!ENTITY refiaddr SYSTEM "ref/iaddr.xml">
+<!ENTITY refclicert SYSTEM "ref/clicert.xml">
+
+]>
+
+<book>
+ <bookinfo>
+ <title>neon HTTP/WebDAV client library</title>
+ <author>
+ <firstname>Joe</firstname><surname>Orton</surname>
+ <affiliation>
+ <address><email>neon@webdav.org</email></address>
+ </affiliation>
+ </author>
+ <copyright><year>2001-2003</year><holder>Joe Orton</holder></copyright>
+
+ <legalnotice>
+ <para>Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, with no Front-Cover Texts,
+ and with no Back-Cover Texts.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".</para>
+ </legalnotice>
+
+ </bookinfo>
+
+ <chapter id="intro">
+ <title>Introduction</title>
+
+ <para>This chapter provides an introduction to neon, giving an
+overview of the range of features offered, and some general guidelines
+for using the neon API.</para>
+
+ <para>neon aims to provide a modern, flexible, and simple API
+in the C programming language for implementing HTTP and WebDAV
+support. The WebDAV functionality is entirely separate from the basic
+HTTP functionality; neon can be used simply as an HTTP client library,
+ignoring the WebDAV support if desired.</para>
+
+ &section.features;
+
+ &section.using;
+
+ </chapter>
+
+ <chapter id="api">
+ <title>The neon API for the C language</title>
+
+ &section.xml;
+
+ </chapter>
+
+ <reference id="ref">
+
+ <!-- these are used in the man page header/footers -->
+ <referenceinfo>
+ <title>neon API reference</title>
+ <date>&date;</date>
+ <productname>neon &version;</productname>
+ </referenceinfo>
+
+ <title>neon API reference</title>
+
+ &refneon; <!-- neon -->
+ &refconfig; <!-- neon-config -->
+
+ &refreqhdr; <!-- ne_add_request_header -->
+ &refresolve; <!-- ne_addr_resolve -->
+ &refbuf; <!-- ne_buffer -->
+ &refbufapp; <!-- ne_buffer_append -->
+ &refbufutil; <!-- ne_buffer_clear -->
+ &refbufcr; <!-- ne_buffer_create -->
+ &refbufdest; <!-- ne_buffer_destroy -->
+ &referr; <!-- ne_get_error -->
+ &refgetst; <!-- ne_get_status -->
+ &refiaddr; <!-- ne_iaddr_make -->
+ &refalloc; <!-- ne_malloc -->
+ &refreq; <!-- ne_request_create -->
+ &refsess; <!-- ne_session_create -->
+ &refopts; <!-- ne_set_useragent -->
+ &refreqbody; <!-- ne_set_request_body_buffer -->
+ &refauth; <!-- ne_set_server_auth -->
+ &refshave; <!-- ne_shave -->
+ &refinit; <!-- ne_sock_init -->
+ &refsslcert; <!-- ne_ssl_certificate -->
+ &refssldname; <!-- ne_ssl_dname -->
+ &refsslca; <!-- ne_ssl_load_ca -->
+ &refsslvfy; <!-- ne_ssl_set_verify -->
+ &refclicert; <!-- ne_ssl_client_cert -->
+ &refstatus; <!-- ne_status -->
+ &reftok; <!-- ne_token -->
+ &refvers; <!-- ne_version_match -->
+
+ <!-- REFEND -->
+ <!-- ******************************************************************* -->
+
+ </reference>
+
+&fdl;
+
+</book>
diff --git a/doc/parsing-xml.txt b/doc/parsing-xml.txt
new file mode 100644
index 0000000..dc3e467
--- /dev/null
+++ b/doc/parsing-xml.txt
@@ -0,0 +1,170 @@
+
+Requirements for XML parsing in neon
+------------------------------------
+
+Before describing the interface given in neon for parsing XML, here
+are the requirements which it must satisfy:
+
+ 1. to support using either libxml or expat as the underlying parser
+ 2. to allow "independent" sections to handle parsing one XML
+ document
+ 3. to map element namespaces/names to an integer for easier
+ comparison.
+
+A description of requirement (2) is useful since it is the "hard"
+requirement, and adds most of the complexity of interface: WebDAV
+PROPFIND responses are made up of a large boilerplate XML
+
+ <multistatus><response><propstat><prop>...</prop></propstat> etc.
+
+neon should handle the parsing of these standard elements, and expose
+the meaning of the response using a convenient interface. But, within
+the <prop> elements, there may also be fragments of XML: neon can
+never know how to parse these, since they are property- and hence
+application-specific. The simplest example of this is the
+DAV:resourcetype property.
+
+So there is requirement (2) that two "independent" sections of code
+can handle the parsing of one XML document.
+
+Callback-based XML parsing
+--------------------------
+
+There are two ways of parsing XML documents commonly used:
+
+ 1. Build an in-memory tree of the document
+ 2. Use callbacks
+
+Where practical, using callbacks is more efficient than building a
+tree, so this is what neon uses. The standard interface for
+callback-based XML parsing is called SAX, so understanding the SAX
+interface is useful to understanding the XML parsing interface
+provided by neon.
+
+The SAX interface works by registering callbacks which are called *as
+the XML is parsed*. The most important callbacks are for 'start
+element' and 'end element'. For instance, if the XML document below is
+parsed by a SAX-like interface:
+
+ <hello>
+ <foobar></foobar>
+ </hello>
+
+Say we have registered callbacks "startelm" for 'start element' and
+"endelm" for 'end element'. Simplified somewhat, the callbacks will
+be called in this order, with these arguments:
+
+ 1. startelm("hello")
+ 2. startelm("foobar")
+ 3. endelm("foobar")
+ 4. endelm("hello")
+
+See the expat 'xmlparse.h' header for a more complete definition of a
+SAX-like interface.
+
+The hip_xml interface
+---------------------
+
+The hip_xml interface satisfies requirement (2) by introducing the
+"handler" concept. A handler is made up of these things:
+
+ - a set of XML elements
+ - a callback to validate an element
+ - a callback which is called when an element is opened
+ - a callback which is called when an element is closed
+ - (optionally, a callback which is called for CDATA)
+
+Registering a handler essentially says:
+
+ "If you encounter any of this set of elements, I want these
+ callbacks to be called."
+
+Handlers are kept in a STACK inside hip_xml. The first handler
+registered becomes the BASE of the stack, subsequent handlers are
+PUSHed on top.
+
+During XML parsing, the handler which is used for an XML element is
+recorded. When a new element is started, the search for a handler for
+this element begins at the handler used for the parent element, and
+carries on up the stack. For the root element, the search always
+starts at the BASE of the stack.
+
+A user's guide to hip_xml
+-------------------------
+
+The first thing to do when using hip_xml is to know what set of XML
+elements you are going to be parsing. This can usually be done by
+looking at the DTD provided for the documents you are going to be
+parsing. The DTD is also very useful in writing the 'validate'
+callback function, since it can tell you what parent/child pairs are
+valid, and which aren't.
+
+In this example, we'll parse XML documents which look like:
+
+<T:list-of-things xmlns:T="http://things.org/">
+ <T:a-thing>foo</T:a-thing>
+ <T:a-thing>bar</T:a-thing>
+</T:list-of-things>
+
+So, given the set of elements, declare the element id's and the
+element array:
+
+#define ELM_listofthings (HIP_ELM_UNUSED)
+#define ELM_a_thing (HIP_ELM_UNUSED + 1)
+
+const static struct my_elms[] = {
+ { "http://things.org/", "list-of-things", ELM_listofthings, 0 },
+ { "http://things.org/", "a-thing", ELM_a_thing, HIP_XML_CDATA },
+ { NULL }
+};
+
+This declares we know about two elements: list-of-things, and a-thing,
+and that the 'a-thing' element contains character data.
+
+The definition of the validation callback is very simple:
+
+static int validate(hip_xml_elmid parent, hip_xml_elmid child)
+{
+ /* Only allow 'list-of-things' as the root element. */
+ if (parent == HIP_ELM_root && child == ELM_listofthings ||
+ parent = ELM_listofthings && child == ELM_a_thing) {
+ return HIP_XML_VALID;
+ } else {
+ return HIP_XML_INVALID;
+ }
+}
+
+For this example, we can ignore the start-element callback, and just
+use the end-element callback:
+
+static int endelm(void *userdata, const struct hip_xml_elm *s,
+ const char *cdata)
+{
+ printf("Got a thing: %s\n", cdata);
+ return 0;
+}
+
+This endelm callback just prints the cdata which was contained in the
+"a-thing" element.
+
+Now, on to parsing. A new parser object is created for parsing each
+XML document. Creating a new parser object is as simple as:
+
+ hip_xml_parser *parser;
+
+ parser = hip_xml_create();
+
+Next register the handler, passing NULL as the start-element callback,
+and also as userdata, which we don't use here.
+
+ hip_xml_push_handler(parser, my_elms,
+ validate, NULL, endelm,
+ NULL);
+
+Finally, call hip_xml_parse, passing the chunks of XML document to the
+hip_xml as you get them. The output should be:
+
+ Got a thing: foo
+ Got a thing: bar
+
+for the XML document.
diff --git a/doc/ref/alloc.xml b/doc/ref/alloc.xml
new file mode 100644
index 0000000..cc0ac22
--- /dev/null
+++ b/doc/ref/alloc.xml
@@ -0,0 +1,88 @@
+ <refentry id="refalloc">
+
+ <refmeta>
+ <refentrytitle>ne_malloc</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_malloc">ne_malloc</refname>
+ <refname id="ne_calloc">ne_calloc</refname>
+ <refname id="ne_realloc">ne_realloc</refname>
+ <refname id="ne_strdup">ne_strdup</refname>
+ <refname id="ne_strndup">ne_strndup</refname>
+ <refname id="ne_oom_callback">ne_oom_callback</refname>
+ <refpurpose>memory allocation wrappers</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_alloc.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void *<function>ne_malloc</function></funcdef>
+ <paramdef>size_t <parameter>size</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void *<function>ne_calloc</function></funcdef>
+ <paramdef>size_t <parameter>size</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void *<function>ne_realloc</function></funcdef>
+ <paramdef>void *<parameter>size</parameter></paramdef>
+ <paramdef>size_t <parameter>len</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_strdup</function></funcdef>
+ <paramdef>const char *<parameter>s</parameter></paramdef>
+ <paramdef>size_t <parameter>size</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_strndup</function></funcdef>
+ <paramdef>const char *<parameter>s</parameter></paramdef>
+ <paramdef>size_t <parameter>size</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_oom_callback</function></funcdef>
+ <paramdef>void (*<parameter>callback</parameter>)(void)</paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The functions <function>ne_malloc</function>,
+<function>ne_calloc</function>, <function>ne_realloc</function>,
+<function>ne_strdup</function> and <function>ne_strdnup</function>
+provide wrappers for the equivalent functions in the standard C
+library. The wrappers provide the extra guarantee that if the C
+library equivalent returns &null; when no memory is available, an
+optional callback will be called, and the library will then call
+<function>abort</function>().</para>
+
+ <para><function>ne_oom_callback</function> registers a callback
+which will be invoked if an out of memory error is detected.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>If the operating system uses optimistic memory
+allocation, the C library memory allocation routines will not return
+&null;, so it is not possible to gracefully handle memory allocation
+failures.</para>
+
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/auth.xml b/doc/ref/auth.xml
new file mode 100644
index 0000000..9b20201
--- /dev/null
+++ b/doc/ref/auth.xml
@@ -0,0 +1,114 @@
+ <refentry id="refauth">
+
+ <refmeta>
+ <refentrytitle>ne_set_server_auth</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_set_server_auth">ne_set_server_auth</refname>
+ <refname id="ne_set_proxy_auth">ne_set_proxy_auth</refname>
+ <refname id="ne_forget_auth">ne_forget_auth</refname>
+ <refpurpose>register authentication callbacks</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_auth.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>typedef int (*<function>ne_request_auth</function>)</funcdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ <paramdef>const char *<parameter>realm</parameter></paramdef>
+ <paramdef>int <parameter>attempt</parameter></paramdef>
+ <paramdef>char *<parameter>username</parameter></paramdef>
+ <paramdef>char *<parameter>password</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_server_auth</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>ne_request_auth <parameter>callback</parameter></paramdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_proxy_auth</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>ne_request_auth <parameter>callback</parameter></paramdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_forget_auth</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <type>ne_request_auth</type> function type defines a
+callback which is invoked when a server or proxy server requires user
+authentication for a particular request. The
+<parameter>realm</parameter> string is supplied by the server. <!--
+FIXME --> The <parameter>attempt</parameter> is a counter giving the
+number of times the request has been retried with different
+authentication credentials. The first time the callback is invoked
+for a particular request, <parameter>attempt</parameter> will be zero.</para>
+
+ <para>To retry the request using new authentication
+credentials, the callback should return zero, and the
+<parameter>username</parameter> and <parameter>password</parameter>
+buffers must contain &nul;-terminated strings. The
+<literal>NE_ABUFSIZ</literal> constant gives the size of these
+buffers.</para>
+
+ <tip>
+ <para>If you only wish to allow the user one attempt to enter
+credentials, use the value of the <parameter>attempt</parameter>
+parameter as the return value of the callback.</para>
+ </tip>
+
+ <para>To abort the request, the callback should return a
+non-zero value; in which case the contents of the
+<parameter>username</parameter> and <parameter>password</parameter>
+buffers are ignored.</para>
+
+ <para>The <function>ne_forget_auth</function> function can be
+used to discard the cached authentication credentials.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <programlisting>
+/* Function which prompts for a line of user input: */
+extern char *prompt_for(const char *prompt);
+
+static int
+my_auth(void *userdata, const char *realm, int attempts,
+ char *username, char *password)
+{
+ strncpy(username, prompt_for("Username: "), NE_ABUFSIZ);
+ strncpy(password, prompt_for("Password: "), NE_ABUFSIZ);
+ return attempts;
+}
+
+int main(...)
+{
+ &egsess;
+
+ ne_set_server_auth(sess, my_auth, NULL);
+
+ /* ... */
+}</programlisting>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/buf.xml b/doc/ref/buf.xml
new file mode 100644
index 0000000..68b515c
--- /dev/null
+++ b/doc/ref/buf.xml
@@ -0,0 +1,53 @@
+ <refentry id="refbuf">
+
+ <refmeta>
+ <refentrytitle>ne_buffer</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_buffer">ne_buffer</refname>
+ <refpurpose>string buffer handling</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis><funcsynopsisinfo>#include &lt;ne_string.h&gt;
+
+typedef struct {
+ char *data;
+ size_t used;
+ size_t length;
+} <type>ne_buffer</type>;</funcsynopsisinfo></funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <type>ne_buffer</type> type represents an expandable
+memory buffer for holding &nul;-terminated strings. The
+<structfield>data</structfield> field points to the beginnning of the
+string, the length of which is given by the
+<structfield>used</structfield> field. The current size of memory
+allocated is given by the <structfield>length</structfield> field. It
+is not recommended that the fields of a buffer are manipulated
+directly. The <structfield>data</structfield> pointer may change when
+the buffer is modified.</para>
+
+ <para>A buffer is created using <xref
+linkend="ne_buffer_create"/> or <xref
+linkend="ne_buffer_create_sized"/>, and destroyed using <xref
+linkend="ne_buffer_destroy"/> or <xref linkend="ne_buffer_finish"/>.
+The functions <xref linkend="ne_buffer_append"/>, <xref
+linkend="ne_buffer_zappend"/> and <xref linkend="ne_buffer_concat"/> are
+used to append data to a buffer.</para>
+
+ <para>If the string referenced by the
+<structfield>data</structfield> pointer is modified directly (rather
+than using one of the functions listed above),
+<function>ne_buffer_altered</function> must be called.</para>
+
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/bufapp.xml b/doc/ref/bufapp.xml
new file mode 100644
index 0000000..a75ce81
--- /dev/null
+++ b/doc/ref/bufapp.xml
@@ -0,0 +1,89 @@
+ <refentry id="refbufapp">
+
+ <refmeta>
+ <refentrytitle>ne_buffer_append</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_buffer_append">ne_buffer_append</refname>
+ <refname id="ne_buffer_zappend">ne_buffer_zappend</refname>
+ <refname id="ne_buffer_concat">ne_buffer_concat</refname>
+ <refpurpose>append data to a string buffer</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_string.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void <function>ne_buffer_append</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ <paramdef>const char *<parameter>string</parameter></paramdef>
+ <paramdef>size_t <parameter>len</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_buffer_zappend</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ <paramdef>const char *<parameter>string</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_buffer_concat</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ <paramdef>const char *<parameter>str</parameter></paramdef>
+ <paramdef>...</paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_buffer_append</function> and
+<function>ne_buffer_zappend</function> functions append a string to
+the end of a buffer; extending the buffer as necessary. The
+<parameter>len</parameter> passed to
+<function>ne_buffer_append</function> specifies the length of the
+string to append; there must be no &nul; terminator in the first
+<parameter>len</parameter> bytes of the string.
+<function>ne_buffer_zappend</function> must be passed a
+&nul;-terminated string.</para>
+
+ <para>The <function>ne_buffer_concat</function> function takes
+a variable-length argument list following <parameter>str</parameter>;
+each argument must be a <type>char *</type> pointer to a
+&nul;-terminated string. A &null; pointer must be given as the last
+argument to mark the end of the list. The strings (including
+<parameter>str</parameter>) are appended to the buffer in the order
+given. None of the strings passed to
+<function>ne_buffer_concat</function> are modified.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>The following code will output "<literal>Hello, world.
+And goodbye.</literal>".</para>
+
+ <programlisting>ne_buffer *buf = ne_buffer_create();
+ne_buffer_zappend(buf, "Hello");
+ne_buffer_concat(buf, ", world. ", "And ", "goodbye.", NULL);
+puts(buf->data);
+ne_buffer_destroy(buf);</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_buffer"/>, <xref linkend="ne_buffer_create"/>,
+<xref linkend="ne_buffer_destroy"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/bufcr.xml b/doc/ref/bufcr.xml
new file mode 100644
index 0000000..0c572a6
--- /dev/null
+++ b/doc/ref/bufcr.xml
@@ -0,0 +1,60 @@
+ <refentry id="refbufcr">
+
+ <refmeta>
+ <refentrytitle>ne_buffer_create</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_buffer_create">ne_buffer_create</refname>
+ <refname id="ne_buffer_create_sized">ne_buffer_ncreate</refname>
+ <refpurpose>general purpose of group of functions</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_alloc.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>ne_buffer *<function>ne_buffer_create</function></funcdef>
+ <void/>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>ne_buffer *<function>ne_buffer_ncreate</function></funcdef>
+ <paramdef>size_t <parameter>size</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ne_buffer_create</function> creates a new
+buffer object, with an implementation-defined initial size.
+<function>ne_buffer_ncreate</function> creates an
+<type>ne_buffer</type> where the minimum initial size is given in the
+<parameter>size</parameter> parameter. The buffer created will
+contain the empty string (<literal>""</literal>).</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para>Both functions return a pointer to a new buffer object,
+and never &null;.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_buffer"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/bufdest.xml b/doc/ref/bufdest.xml
new file mode 100644
index 0000000..5dc4dfc
--- /dev/null
+++ b/doc/ref/bufdest.xml
@@ -0,0 +1,81 @@
+ <refentry id="refbufdest">
+
+ <refmeta>
+ <refentrytitle>ne_buffer_destroy</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_buffer_destroy">ne_buffer_destroy</refname>
+ <refname id="ne_buffer_finish">ne_buffer_finish</refname>
+ <refpurpose>destroy a buffer object</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_string.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void <function>ne_buffer_destroy</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_buffer_finish</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ne_buffer_destroy</function> frees all memory
+associated with the buffer. <function>ne_buffer_finish</function>
+frees the buffer structure, but not the actual string stored in the
+buffer, which is returned and must be <function>free</function>()d by
+the caller.</para>
+
+ <para>Any use of the buffer object after calling either of these
+functions gives undefined behaviour.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para><function>ne_buffer_finish</function> returns the
+<function>malloc</function>-allocated string stored in the buffer.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>An example use of <function>ne_buffer_finish</function>;
+the <function>duplicate</function> function returns a string made up of
+<parameter>n</parameter> copies of <parameter>str</parameter>:</para>
+
+ <programlisting>static char *duplicate(int n, const char *str)
+{
+ ne_buffer *buf = ne_buffer_create();
+ while (n--) {
+ ne_buffer_zappend(buf, str);
+ }
+ return ne_buffer_finish(buf);
+}</programlisting>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_buffer"/>, <xref linkend="ne_buffer_create"/>,
+<xref linkend="ne_buffer_zappend"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/bufutil.xml b/doc/ref/bufutil.xml
new file mode 100644
index 0000000..3f3f3c5
--- /dev/null
+++ b/doc/ref/bufutil.xml
@@ -0,0 +1,62 @@
+ <refentry id="refbufutil">
+
+ <refmeta>
+ <refentrytitle>ne_buffer_clear</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_buffer_clear">ne_buffer_clear</refname>
+ <refname id="ne_buffer_grow">ne_buffer_grow</refname>
+ <refname id="ne_buffer_altered">ne_buffer_altered</refname>
+ <refpurpose>general purpose of group of functions</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_string.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void <function>ne_buffer_clear</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_buffer_altered</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_buffer_grow</function></funcdef>
+ <paramdef>ne_buffer *<parameter>buf</parameter></paramdef>
+ <paramdef>size_t <parameter>size</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_buffer_clear</function> function sets
+the string stored in <parameter>buf</parameter> to be the empty string
+(<literal>""</literal>).</para>
+
+ <para>The <function>ne_buffer_altered</function> function must
+be used after the string stored in the buffer
+<parameter>buf</parameter> is modified by directly rather than using
+<xref linkend="ne_buffer_append"/>, <xref linkend="ne_buffer_zappend"/>
+or <xref linkend="ne_buffer_concat"/>.</para>
+
+ <para>The <function>ne_buffer_grow</function> function
+ensures that at least <parameter>size</parameter> bytes are allocated
+for the string; this can be used if a large amount of data is going to
+be appended to the buffer and may result in more efficient memory
+allocation.</para>
+
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/clicert.xml b/doc/ref/clicert.xml
new file mode 100644
index 0000000..47a2ce0
--- /dev/null
+++ b/doc/ref/clicert.xml
@@ -0,0 +1,153 @@
+<refentry id="refclicert">
+
+ <refmeta>
+ <refentrytitle>ne_ssl_client_cert</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_ssl_clicert_read">ne_ssl_clicert_read</refname>
+ <refname id="ne_ssl_clicert_name">ne_ssl_clicert_name</refname>
+ <refname id="ne_ssl_clicert_encrypted">ne_ssl_clicert_encrypted</refname>
+ <refname id="ne_ssl_clicert_decrypt">ne_ssl_clicert_decrypt</refname>
+ <refname id="ne_ssl_clicert_owner">ne_ssl_clicert_owner</refname>
+ <refname id="ne_ssl_clicert_free">ne_ssl_clicert_free</refname>
+ <refpurpose>SSL client certificate handling</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_ssl.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>ne_ssl_client_cert *<function>ne_ssl_clicert_read</function></funcdef>
+ <paramdef>const char *<parameter>filename</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>const char *<function>ne_ssl_clicert_name</function></funcdef>
+ <paramdef>const ne_ssl_client_cert *<parameter>ccert</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>ne_ssl_clicert_encrypted</function></funcdef>
+ <paramdef>const ne_ssl_client_cert *<parameter>ccert</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>ne_ssl_clicert_decrypt</function></funcdef>
+ <paramdef>ne_ssl_client_cert *<parameter>ccert</parameter></paramdef>
+ <paramdef>const char *<parameter>password</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>const ne_ssl_certificate *<function>ne_ssl_clicert_owner</function></funcdef>
+ <paramdef>const ne_ssl_client_cert *<parameter>ccert</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_ssl_clicert_free</function></funcdef>
+ <paramdef>ne_ssl_client_cert *<parameter>ccert</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_ssl_clicert_read</function> function reads
+ a <firstterm>client certificate</firstterm> from a
+ PKCS#12-formatted file, and returns an
+ <type>ne_ssl_client_certificate</type> object. If the client
+ certificate is encrypted, it must be decrypted before it is used.
+ An <type>ne_ssl_client_certificate</type> object holds a client
+ certificate and the associated private key, not just a
+ certificate; the term "<glossterm>client certificate</glossterm>"
+ will used to refer to this pair.</para>
+
+ <para>A client certificate can be in one of two states:
+ <emphasis>encrypted</emphasis> or <emphasis>decrypted</emphasis>.
+ The <function>ne_ssl_clicert_encrypted</function> function will
+ return non-zero if the client certificate is in the
+ <emphasis>encrypted</emphasis> state. A client certificate object
+ returned by <function>ne_ssl_clicert_read</function> may be
+ initially in either state, depending on whether the file was
+ encrypted or not.</para>
+
+ <para><function>ne_ssl_clicert_decrypt</function> can be used to
+ decrypt a client certificate using the appropriate password. This
+ function must only be called if the object is in the
+ <emphasis>encrypted</emphasis> state; if decryption fails, the
+ certificate state does not change, so decryption can be attempted
+ more than once using different passwords.</para>
+
+ <para>A client certificate can be given a "friendly name" when it
+ is created; <function>ne_ssl_clicert_owner</function> will return
+ this name (or &null; if no friendly name was specified).
+ <function>ne_ssl_clicert_owner</function> can be used when the
+ client certificate is in either the encrypted or decrypted state,
+ and will return the same string for the lifetime of the
+ object.</para>
+
+ <para>The function <function>ne_ssl_clicert_owner</function>
+ returns the certificate part of the client certificate; it must
+ only be called if the client certificate is in the
+ <emphasis>decrypted</emphasis> state.</para>
+
+ <para>When the client certificate is no longer needed, the
+ <function>ne_ssl_clicert_free</function> function should be used
+ to destroy the object.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para><function>ne_ssl_clicert_read</function> returns a client
+ certificate object, or &null; if the file could not be read.
+ <function>ne_ssl_clicert_encrypted</function> returns zero if the
+ object is in the decrypted state, or non-zero if it is in the
+ encrypted state. <function>ne_ssl_clicert_name</function> returns
+ a &nul;-terminated friendly name string, or &null;.
+ <function>ne_ssl_clicert_owner</function> returns a certificate
+ object.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>The following code reads a client certificate and decrypts
+ it if necessary, then loads it into an HTTP session.</para>
+
+ <programlisting>ne_ssl_client_certificate *ccert;
+
+ccert = ne_ssl_clicert_read("/path/to/client.p12");
+
+if (ccert == NULL) {
+ /* handle error... */
+} else if (ne_ssl_clicert_encrypted(ccert)) {
+ char *password = prompt_for_password();
+
+ if (ne_ssl_clicert_decrypt(ccert, password)) {
+ /* could not decrypt! handle error... */
+ }
+}
+
+ne_ssl_set_clicert(sess, ccert);
+</programlisting>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_ssl_certificate"/></para>
+ </refsect1>
+
+</refentry>
+
diff --git a/doc/ref/config.xml b/doc/ref/config.xml
new file mode 100644
index 0000000..4823cca
--- /dev/null
+++ b/doc/ref/config.xml
@@ -0,0 +1,124 @@
+ <refentry id="refconfig">
+
+ <refentryinfo><title>neon</title></refentryinfo>
+
+ <refmeta>
+ <refentrytitle>neon-config</refentrytitle>
+ <manvolnum>1</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="neon-config">neon-config</refname>
+
+ <refpurpose>script providing information about installed copy
+ of neon library</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <cmdsynopsis>
+ <command>neon-config</command>
+ <arg choice="opt"><option>--prefix</option></arg>
+ <group>
+ <arg><option>--cflags</option></arg>
+ <arg><option>--libs</option></arg>
+ <arg><option>--la-file</option></arg>
+ <arg><option>--support</option> <replaceable>feature</replaceable></arg>
+ <arg><option>--help</option></arg>
+ <arg><option>--version</option></arg>
+ </group>
+ </cmdsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <command>neon-config</command> script provides
+information about an installed copy of the neon library. The
+<option>--cflags</option> and <option>--libs</option> options instruct
+how to compile and link an application against the library; the
+<option>--version</option> and <option>--support</option> options can
+help determine whether the library meets the applications
+requirements.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--cflags</option></term>
+ <listitem><simpara>Print the flags which should be passed to
+the C compiler when compiling object files, when the object files use
+neon header files.</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--libs</option></term>
+ <listitem><simpara>Print the flags which should be passed to
+the linker when linking an application which uses the neon
+library</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--la-file</option></term>
+ <listitem><simpara>Print the location of the libtool library
+script, <filename>libneon.la</filename>, which can be used to link against
+&neon; by applications using libtool.</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--version</option></term>
+ <listitem><simpara>Print the version of the library</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--prefix</option> <replaceable>dir</replaceable></term>
+ <listitem><simpara>If <replaceable>dir</replaceable> is given; relocate output of
+<option>--cflags</option> and <option>--libs</option> as if neon was
+installed in given prefix directory. Otherwise, print the
+installation prefix of the library.</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--support</option> <replaceable>feature</replaceable></term>
+ <listitem><simpara>The script exits with success if
+<replaceable>feature</replaceable> is supported by the
+library.</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--help</option></term>
+ <listitem><simpara>Print help message; includes list of known
+ features and whether they are supported or not.</simpara></listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </refsect1>
+
+ <refsect1 id="example">
+ <title>Example</title>
+
+ <para>Below is a Makefile fragment which could be used to
+build an application against an installed neon library, when the
+<command>neon-config</command> script can be found in
+<envar>$PATH</envar>.</para>
+
+ <programlisting>CFLAGS = `neon-config --cflags`
+LIBS = `neon-config --libs`
+OBJECTS = myapp.o
+TARGET = myapp
+
+$(TARGET): $(OBJECTS)
+ $(CC) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
+
+myapp.o: myapp.c
+ $(CC) $(CFLAGS) -c myapp.c -o myapp.o</programlisting>
+
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/err.xml b/doc/ref/err.xml
new file mode 100644
index 0000000..50551b5
--- /dev/null
+++ b/doc/ref/err.xml
@@ -0,0 +1,66 @@
+ <refentry id="referr">
+
+ <refmeta>
+ <refentrytitle>ne_get_error</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_get_error">ne_get_error</refname>
+ <refname id="ne_set_error">ne_set_error</refname>
+ <refpurpose>error handling for HTTP sessions</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_session.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>const char *<function>ne_get_error</function></funcdef>
+ <paramdef>ne_sesssion *<parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_error</function></funcdef>
+ <paramdef>ne_sesssion *<parameter>session</parameter></paramdef>
+ <paramdef>const char *<parameter>format</parameter></paramdef>
+ <paramdef>...</paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The session error string is used to store any
+human-readable error information associated with any errors which
+occur whilst using the HTTP session.</para>
+
+ <para>The <function>ne_get_error</function> function returns the current
+session error string. This string persists only until it is changed by a
+subsequent operation on the session.</para>
+
+ <para>The <function>ne_set_error</function> function can be
+used to set a new session error string, using a
+<function>printf</function>-style format string interface.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+ <para>Retrieve the current error string:</para>
+ <programlisting>&egsess;
+...
+printf("Error was: %s\n", ne_get_error(sess));</programlisting>
+
+ <para>Set a new error string:</para>
+ <programlisting>&egsess;
+...
+ne_set_error(sess, "Response missing header %s", "somestring");</programlisting>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/getst.xml b/doc/ref/getst.xml
new file mode 100644
index 0000000..5a419c4
--- /dev/null
+++ b/doc/ref/getst.xml
@@ -0,0 +1,63 @@
+ <refentry id="refgetst">
+
+ <refmeta>
+ <refentrytitle>ne_get_status</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_get_status">ne_get_status</refname>
+ <refpurpose>retrieve HTTP response status for request</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_request.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>const ne_status *<function>ne_get_status</function></funcdef>
+ <paramdef>const ne_request *<parameter>request</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_get_status</function> function returns
+a pointer to the HTTP status object giving the result of a request.
+The object returned only becomes valid once the request has been
+<emphasis>successfully</emphasis> dispatched (the return value of
+<function>ne_request_dispatch</function> or
+<function>ne_begin_request</function> was zero). The object remains
+valid until the associated request object is destroyed.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_status"/>, <xref
+ linkend="ne_request_create"/></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>Display the response status code of applying the
+<literal>HEAD</literal> method to some resource.</para>
+
+ <programlisting>ne_request *req = ne_request_create(sess, "HEAD", "/foo/bar");
+if (ne_request_dispatch(req))
+ /* handle errors... */
+else
+ printf("Response status code was %d\n", ne_get_status(req)->code);
+ne_request_destroy(req);</programlisting>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/iaddr.xml b/doc/ref/iaddr.xml
new file mode 100644
index 0000000..cf64a13
--- /dev/null
+++ b/doc/ref/iaddr.xml
@@ -0,0 +1,124 @@
+<refentry id="refiaddr">
+
+ <refmeta>
+ <refentrytitle>ne_iaddr_make</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_iaddr_make">ne_iaddr_make</refname>
+ <refname id="ne_iaddr_cmp">ne_iaddr_cmp</refname>
+ <refname id="ne_iaddr_print">ne_iaddr_print</refname>
+ <refname id="ne_iaddr_free">ne_iaddr_free</refname>
+ <refpurpose>functions to manipulate and compare network addresses</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_socket.h&gt;
+
+typedef enum {
+ ne_iaddr_ipv4 = 0,
+ ne_iaddr_ipv6
+} <type>ne_iaddr_type</type>;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>ne_inet_addr *<function>ne_iaddr_make</function></funcdef>
+ <paramdef>ne_iaddr_type <parameter>type</parameter></paramdef>
+ <paramdef>const unsigned char *<parameter>raw</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>ne_iaddr_cmp</function></funcdef>
+ <paramdef>const ne_inet_addr *<parameter>i1</parameter></paramdef>
+ <paramdef>const ne_inet_addr *<parameter>i2</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_iaddr_print</function></funcdef>
+ <paramdef>const ne_inet_addr *<parameter>ia</parameter></paramdef>
+ <paramdef>char *<parameter>buffer</parameter></paramdef>
+ <paramdef>size_t <parameter>bufsiz</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_iaddr_free</function></funcdef>
+ <paramdef>const ne_inet_addr *<parameter>addr</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ne_iaddr_make</function> creates an
+ <type>ne_inet_addr</type> object from a raw binary network
+ address; for instance the four bytes <literal>0x7f 0x00 0x00
+ 0x01</literal> represent the IPv4 address
+ <literal>127.0.0.1</literal>. The object returned is suitable for
+ passing to <function>ne_sock_connect</function>. A binary IPv4
+ address contains four bytes; a binary IPv6 address contains
+ sixteen bytes; addresses passed must be in network byte
+ order.</para>
+
+ <para><function>ne_iaddr_cmp</function> can be used to compare two
+ network addresses; returning zero only if they are identical. The
+ addresses need not be of the same address type; if the addresses
+ are not of the same type, the return value is guaranteed to be
+ non-zero.</para>
+
+ <para><function>ne_iaddr_print</function> can be used to print the
+ human-readable string representation of a network address into a
+ buffer, for instance the string
+ <literal>"127.0.0.1"</literal>.</para>
+
+ <para><function>ne_iaddr_free</function> releases the memory
+ associated with a network address object.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para><function>ne_iaddr_make</function> returns &null; if the
+ address type passed is not supported (for instance on a platform
+ which does not support IPv6).</para>
+
+
+ <para><function>ne_iaddr_print</function> returns the
+ <parameter>buffer</parameter> pointer, and never &null;.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>The following example connects a socket to port 80 at the
+ address <literal>127.0.0.1</literal>.</para>
+
+ <programlisting>unsigned char addr[] = "\0x7f\0x00\0x00\0x01";
+ne_inet_addr *ia;
+
+ia = ne_iaddr_make(ne_iaddr_ipv4, addr);
+if (ia != NULL) {
+ ne_socket *sock = ne_sock_connect(ia, 80);
+ ne_iaddr_free(ia);
+ /* ... */
+} else {
+ /* ... */
+}</programlisting>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_addr_resolve"/></para>
+ </refsect1>
+
+</refentry>
+
diff --git a/doc/ref/init.xml b/doc/ref/init.xml
new file mode 100644
index 0000000..32dcda5
--- /dev/null
+++ b/doc/ref/init.xml
@@ -0,0 +1,55 @@
+<refentry id="refsockinit">
+
+ <refmeta>
+ <refentrytitle>ne_sock_init</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_sock_init">ne_sock_init</refname>
+ <refpurpose>perform library initialization</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_socket.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>ne_sock_init</function></funcdef>
+ <void/>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>In some platforms and configurations, &neon; may be using
+ some socket or SSL libraries which require global initialization
+ before use. To perform this initialization, the
+ <function>ne_sock_init</function> function must be called once
+ before any other library functions are used.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para><function>ne_sock_init</function> returns zero on success,
+ or non-zero on error. If an error occurs, no further use of the
+ &neon; library should be attempted.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="refneon"/></para>
+ </refsect1>
+
+</refentry>
+
diff --git a/doc/ref/neon.xml b/doc/ref/neon.xml
new file mode 100644
index 0000000..9857c63
--- /dev/null
+++ b/doc/ref/neon.xml
@@ -0,0 +1,145 @@
+<refentry id="refneon">
+
+ <refmeta>
+ <refentrytitle>neon</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>neon</refname>
+ <refpurpose>HTTP and WebDAV client library</refpurpose>
+ </refnamediv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>neon is an HTTP and WebDAV client library. The major
+ abstractions exposed are the HTTP <emphasis>session</emphasis>,
+ created by <xref linkend="ne_session_create"/>; and the HTTP
+ <emphasis>request</emphasis>, created by <xref
+ linkend="ne_request_create"/>. HTTP authentication is handled
+ transparently for server and proxy servers, see <xref
+ linkend="ne_set_server_auth"/>; complete SSL/TLS support is also
+ included, see <xref linkend="ne_ssl_set_verify"/>.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Conventions</title>
+
+ <para>Some conventions are used throughout the neon API, to
+ provide a consistent and simple interface; these are documented
+ below.</para>
+
+ <refsect2>
+ <title>Thread-safeness and global initialization</title>
+
+ <para>&neon; itself is implemented to be thread-safe (avoiding
+ any use of global state), but in some configurations makes use of
+ other libraries which require global initialization. The
+ <xref linkend="ne_sock_init"/> function should be called before
+ any other use of the &neon; library interface.</para>
+ </refsect2>
+
+ <refsect2>
+ <title>Namespaces</title>
+
+ <para>To avoid possible collisions between names used for symbols
+ and preprocessor macros by an application and the libraries it
+ uses, it is good practice for each library to reserve a particular
+ <emphasis>namespace prefix</emphasis>. An application which
+ ensures it uses no names with these prefixes is then guaranteed to
+ avoid such collisions.</para>
+
+ <para>The &neon; library reserves the use of the namespace
+ prefixes <literal>ne_</literal> and <literal>NE_</literal>. The
+ libraries used by &neon; may also reserve certain namespaces;
+ collisions between these libraries and a &neon;-based application
+ will not be detected at compile time, since the underlying library
+ interfaces are not exposed through the &neon; header files. Such
+ collisions can only be detected at link time, when the linker
+ attempts to resolve symbols. The following list documents some of
+ the namespaces claimed by libraries used by &neon;; this list may
+ be incomplete.</para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>SSL, ssl, TLS, tls, ERR_, BIO_, d2i_, i2d_, ASN1_</term>
+ <listitem><simpara>Some of the many prefixes used by the OpenSSL
+ library; little attempt has been made to keep exported symbols
+ within any particular prefixes for this
+ library.</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>XML_, Xml[A-Z]</term> <listitem><simpara>Namespaces
+ used by the expat library.</simpara></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>xml[A-Z], html[A-Z], docb[A-Z]</term>
+ <listitem><simpara>Namespaces used by the libxml2 library; a
+ relatively small number of symbols are used without these
+ prefixes.</simpara></listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Argument validation</title>
+
+ <para>&neon; does not attempt to validate that arguments passed to
+ functions conform to the API (for instance, checking that pointer
+ arguments are not &null;). Any use of the &neon; API which is not
+ documented to produce a certain behaviour results in
+ <emphasis>undefined behaviour</emphasis>, by definition.</para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>URI paths, WebDAV metadata</title>
+
+ <para>The path strings passed to any function must be
+ <emphasis>URI-encoded</emphasis> by the application; &neon; never
+ performs any URI encoding or decoding internally. WebDAV property
+ names and values must be valid UTF-8 encoded Unicode
+ strings.</para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Memory handling</title>
+
+ <para>neon does not attempt to cope gracefully with an
+ out-of-memory situation; instead, by default, the
+ <function>abort</function> function is called to immediately
+ terminate the process. An application may register a custom
+ function which will be called before <function>abort</function> in
+ such a situation; see <xref linkend="ne_oom_callback"/>.</para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Callbacks and userdata</title>
+
+ <para>Whenever a callback is registered, a
+ <literal>userdata</literal> pointer is also used to allow the
+ application to associate a context with the callback. The
+ userdata is of type <type>void *</type>, allowing any pointer to
+ be used.</para>
+
+ </refsect2>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="refsess"/>, <xref linkend="ne_oom_callback"/></para>
+ </refsect1>
+
+</refentry>
+
diff --git a/doc/ref/opts.xml b/doc/ref/opts.xml
new file mode 100644
index 0000000..fe8f368
--- /dev/null
+++ b/doc/ref/opts.xml
@@ -0,0 +1,126 @@
+ <refentry id="refopts">
+
+ <refmeta>
+ <refentrytitle>ne_set_useragent</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_set_useragent">ne_set_useragent</refname>
+ <refname id="ne_set_persist">ne_set_persist</refname>
+ <refname id="ne_set_read_timeout">ne_set_read_timeout</refname>
+ <refname id="ne_set_expect100">ne_set_expect100</refname>
+ <refpurpose>common settings for HTTP sessions</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_session.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_useragent</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>const char *<parameter>product</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_persist</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>int <parameter>flag</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_read_timeout</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>int <parameter>timeout</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_expect100</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>int <parameter>flag</parameter></paramdef>
+ </funcprototype>
+
+<!--
+ <funcprototype>
+ <funcdef>const char *<function>ne_get_scheme</function></funcdef>
+ <paramdef>ne_sesssion *<parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>const char *<function>ne_get_server_hostport</function></funcdef>
+ <paramdef>ne_sesssion *<parameter>session</parameter></paramdef>
+ </funcprototype>
+-->
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <!-- TODO: intro para? -->
+
+ <para>The <literal>User-Agent</literal> request header is used
+to identify the software which generated the request for statistical
+or debugging purposes. neon does not send a
+<literal>User-Agent</literal> header unless a call is made to the
+<function>ne_set_useragent</function>.
+<function>ne_set_useragent</function> must be passed a product string
+conforming to RFC2616's product token grammar; of the form
+<literal>"Product/Version"</literal>.</para>
+
+ <para>By default neon will use a persistent connection
+whenever possible. For specific applications, or for debugging
+purposes, it is sometimes useful to disable persistent connections.
+The <function>ne_set_persist</function> function will disable
+persistent connections if passed a <parameter>flag</parameter>
+parameter of <literal>0</literal>, and will enable them
+otherwise.</para>
+
+ <para>When neon reads from a socket, by default the read
+operation will time out after 60 seconds, and the request will fail
+giving an <errorcode>NE_TIMEOUT</errorcode> error. To configure this
+timeout interval, call <function>ne_set_read_timeout</function> giving
+the desired number of seconds as the <parameter>timeout</parameter>
+parameter.</para>
+
+ <para>An extension introduced in the HTTP/1.1 specification
+was the use of the <literal>Expect: 100-continue</literal> header.
+This header allows an HTTP client to be informed of the expected
+response status before the request message body is sent: a useful
+optimisation for situations where a large message body is to be sent.
+The <function>ne_set_expect100</function> function can be used to
+enable this feature by passing the <parameter>flag</parameter>
+parameter as any non-zero integer.</para>
+
+<warning><para>Unfortunately, if this header is sent to a server which
+is not fully compliant with the HTTP/1.1 specification, a deadlock
+occurs resulting in a temporarily "hung" connection. neon will
+recover gracefully from this situation, but only after a 15 second
+timeout. It is highly recommended that this option is not enabled
+unless it is known that the server in use correctly implements
+<literal>Expect: 100-continue</literal> support.</para></warning>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+ <para>Set a user-agent string:</para>
+ <programlisting>&egsess;
+ne_set_useragent(sess, "MyApplication/2.1");</programlisting>
+
+ <para>Disable use of persistent connections:</para>
+ <programlisting>ne_session *sess = ne_session_create(...);
+ne_set_persist(sess, 0);</programlisting>
+
+ <para>Set a 30 second read timeout:</para>
+ <programlisting>&egsess;
+ne_set_read_timeout(sess, 30);</programlisting>
+
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/req.xml b/doc/ref/req.xml
new file mode 100644
index 0000000..7c36d5c
--- /dev/null
+++ b/doc/ref/req.xml
@@ -0,0 +1,169 @@
+ <refentry id="refreq">
+
+ <refmeta>
+ <refentrytitle>ne_request_create</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_request_create">ne_request_create</refname>
+ <refname id="ne_request_dispatch">ne_request_dispatch</refname>
+ <refname id="ne_request_destroy">ne_request_destroy</refname>
+ <refpurpose>low-level HTTP request handling</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_request.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>ne_request *<function>ne_request_create</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>const char *<parameter>method</parameter></paramdef>
+ <paramdef>const char *<parameter>path</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>ne_request_dispatch</function></funcdef>
+ <paramdef>ne_request *<parameter>req</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_request_destroy</function></funcdef>
+ <paramdef>ne_request *<parameter>req</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>An HTTP request, represented by the
+<type>ne_request</type> type, specifies that some operation is to be
+performed on some resource. The
+<function>ne_request_create</function> function creates a request
+object, specifying the operation in the <parameter>method</parameter>
+parameter. The location of the resource is determined by the server in
+use for the session given by the <parameter>sess</parameter>
+parameter, combined with the <parameter>path</parameter> parameter.</para>
+
+<para>The <parameter>path</parameter> string used must conform to the
+<literal>abs_path</literal> definition given in RFC2396, with an
+optional "?query" part, and must be URI-escaped by the caller (for
+instance, using <function>ne_path_escape</function>. If the string
+comes from an untrusted source, failure to perform URI-escaping
+results in a security vulnerability.</para>
+
+ <para>To dispatch a request, and process the response, the
+<function>ne_request_dispatch</function> function can be used. An
+alternative is to use the (more complex, but more flexible)
+combination of the <function>ne_begin_request</function>,
+<function>ne_end_request</function>, and
+<function>ne_read_response_block</function> functions; see
+<function>ne_begin_request</function>.</para>
+
+ <para>To add extra headers in the request, the functions <xref
+linkend="ne_add_request_header"/> and <xref
+linkend="ne_print_request_header"/> can be used. To include a message
+body with the request, one of the functions
+<function>ne_set_request_body_buffer</function>, <xref
+linkend="ne_set_request_body_fd"/>, or
+<function>ne_set_request_body_provider</function> can be used.</para>
+
+ <para>The return value of
+<function>ne_request_dispatch</function> indicates merely whether the
+request was sent and the response read successfully. To discover the
+result of the operation, <xref linkend="ne_get_status"/>, along with
+any processing of the response headers and message body.</para>
+
+ <para>A request can only be dispatched once: calling
+<function>ne_request_dispatch</function> more than once on a single
+<type>ne_request</type> object produces undefined behaviour. Once all
+processing associated with the request object is complete, use the
+<function>ne_request_destroy</function> function to destroy the
+resources associated with it. Any subsequent use of the request
+object produces undefined behaviour.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para>The <function>ne_request_create</function> function
+returns a pointer to a request object (and never &null;).</para>
+
+ <para>The <function>ne_request_dispatch</function> function
+returns zero if the request was dispatched successfully, and a
+non-zero error code otherwise.</para>
+
+ </refsect1>
+
+<!-- TODO: abs_path description in a NOTES section -->
+
+ <refsect1>
+ <title>Errors</title>
+
+ <variablelist>
+ <varlistentry><term><errorcode>NE_ERROR</errorcode></term>
+ <listitem>
+ <simpara>Request failed (see session error string)</simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><errorcode>NE_LOOKUP</errorcode></term>
+ <listitem>
+ <simpara>The DNS lookup for the server (or proxy server) failed.</simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><errorcode>NE_AUTH</errorcode></term>
+ <listitem>
+ <simpara>Authentication failed on the server.</simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><errorcode>NE_PROXYAUTH</errorcode></term>
+ <listitem>
+ <simpara>Authentication failed on the proxy server.</simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><errorcode>NE_CONNECT</errorcode></term>
+ <listitem>
+ <simpara>A connection to the server could not be established.</simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><errorcode>NE_TIMEOUT</errorcode></term>
+ <listitem>
+ <simpara>A timeout occurred while waiting for the server to respond.</simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>An example of applying a <literal>MKCOL</literal>
+ operation to the resource at the location
+ <literal>http://www.example.com/foo/bar/</literal>:</para>
+
+ <programlisting>ne_session *sess = ne_session_create("http", "www.example.com", 80);
+ne_request *req = ne_request_create(sess, "MKCOL", "/foo/bar/");
+if (ne_request_dispatch(req)) {
+ printf("Request failed: %s\n", ne_get_error(sess));
+}
+ne_request_destroy(req);</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_get_error"/>, <xref
+linkend="ne_set_error"/>, <xref linkend="ne_get_status"/>, <xref
+linkend="ne_add_request_header"/>, <xref
+linkend="ne_set_request_body_buffer"/>.</para>
+
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/reqbody.xml b/doc/ref/reqbody.xml
new file mode 100644
index 0000000..e2c8eb3
--- /dev/null
+++ b/doc/ref/reqbody.xml
@@ -0,0 +1,69 @@
+ <refentry id="refreqbody">
+
+ <refmeta>
+ <refentrytitle>ne_set_request_body_buffer</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_set_request_body_buffer">ne_set_request_body_buffer</refname>
+ <refname id="ne_set_request_body_fd">ne_set_request_body_fd</refname>
+ <refpurpose>include a message body with a request</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_request.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_request_body_buffer</function></funcdef>
+ <paramdef>ne_request *<parameter>req</parameter></paramdef>
+ <paramdef>const char *<parameter>buf</parameter></paramdef>
+ <paramdef>size_t <parameter>count</parameter></paramdef>
+ </funcprototype>
+
+ <!-- this is a better interface for set_request_body_fd:
+ <funcprototype>
+ <funcdef>int <function>ne_set_request_body_fd</function></funcdef>
+ <paramdef>ne_request *<parameter>req</parameter></paramdef>
+ <paramdef>int <parameter>fd</parameter></paramdef>
+ <paramdef>off_t <parameter>begin</parameter></paramdef>
+ <paramdef>size_t <parameter>count</parameter></paramdef>
+ </funcprototype>
+ -->
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_set_request_body_buffer</function>
+function specifies that a message body should be included with the
+body, which is stored in the <parameter>count</parameter> bytes buffer
+<parameter>buf</parameter>.</para>
+
+<!--
+ <para>The <function>ne_set_request_body_fd</function> function
+can be used to include a message body with a request which is read
+from a file descriptor. The body is read from the file descriptor
+<parameter>fd</parameter>, which must be a associated with a seekable
+file (not a pipe, socket, or FIFO). <parameter>count</parameter>
+bytes are read, beginning at offset <parameter>begin</parameter>
+(passing <parameter>begin</parameter> as zero means the body is read
+from the beginning of the file).</para>
+
+-->
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_request_create"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/reqhdr.xml b/doc/ref/reqhdr.xml
new file mode 100644
index 0000000..4d811b1
--- /dev/null
+++ b/doc/ref/reqhdr.xml
@@ -0,0 +1,63 @@
+ <refentry id="refreqhdr">
+
+ <refmeta>
+ <refentrytitle>ne_add_request_header</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_add_request_header">ne_add_request_header</refname>
+ <refname id="ne_print_request_header">ne_print_request_header</refname>
+ <refpurpose>add headers to a request</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_request.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void <function>ne_add_request_header</function></funcdef>
+ <paramdef>ne_request *<parameter>request</parameter></paramdef>
+ <paramdef>const char *<parameter>name</parameter></paramdef>
+ <paramdef>const char *<parameter>value</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_print_request_header</function></funcdef>
+ <paramdef>ne_request *<parameter>request</parameter></paramdef>
+ <paramdef>const char *<parameter>name</parameter></paramdef>
+ <paramdef>const char *<parameter>format</parameter></paramdef>
+ <paramdef>...</paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The functions <function>ne_add_request_header</function>
+and <function>ne_print_request_header</function> can be used to add
+headers to a request, before it is sent.</para>
+
+ <para><function>ne_add_request_header</function> simply adds a
+header of given <parameter>name</parameter>, with given
+<parameter>value</parameter>.</para>
+
+ <para><function>ne_print_request_header</function> adds a
+header of given <parameter>name</parameter>, taking the value from the
+<function>printf</function>-like <parameter>format</parameter> string
+parameter and subsequent variable-length argument list.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_request_create"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/resolve.xml b/doc/ref/resolve.xml
new file mode 100644
index 0000000..067cf61
--- /dev/null
+++ b/doc/ref/resolve.xml
@@ -0,0 +1,145 @@
+<refentry id="refresolve">
+
+ <refmeta>
+ <refentrytitle>ne_addr_resolve</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_addr_resolve">ne_addr_resolve</refname>
+ <refname id="ne_addr_result">ne_addr_result</refname>
+ <refname id="ne_addr_first">ne_addr_first</refname>
+ <refname id="ne_addr_next">ne_addr_next</refname>
+ <refname id="ne_addr_error">ne_addr_error</refname>
+ <refname id="ne_addr_destroy">ne_addr_destroy</refname>
+ <refpurpose>functions to resolve hostnames to addresses</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_socket.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>ne_sock_addr *<function>ne_addr_resolve</function></funcdef>
+ <paramdef>const char *<parameter>hostname</parameter></paramdef>
+ <paramdef>int <parameter>flags</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>ne_addr_result</function></funcdef>
+ <paramdef>const ne_sock_addr *<parameter>addr</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>const ne_inet_addr *<function>ne_addr_first</function></funcdef>
+ <paramdef>ne_sock_addr *<parameter>addr</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>const ne_inet_addr *<function>ne_addr_next</function></funcdef>
+ <paramdef>ne_sock_addr *<parameter>addr</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_addr_error</function></funcdef>
+ <paramdef>const ne_sock_addr *<parameter>addr</parameter></paramdef>
+ <paramdef>char *<parameter>buffer</parameter></paramdef>
+ <paramdef>size_t <parameter>bufsiz</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_addr_destroy</function></funcdef>
+ <paramdef>ne_sock_addr *<parameter>addr</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_addr_resolve</function> function resolves
+ the given <parameter>hostname</parameter>, returning an
+ <type>ne_sock_addr</type> object representing the address (or
+ addresses) associated with the hostname. The
+ <parameter>flags</parameter> parameter is currently unused, and
+ must be passed as 0.</para>
+
+ <para>The <parameter>hostname</parameter> passed to
+ <function>ne_addr_resolve</function> can be a DNS hostname
+ (e.g. <literal>"www.example.com"</literal>) or an IPv4 dotted quad
+ (e.g. <literal>"192.0.34.72"</literal>); or, on systems which
+ support IPv6, an IPv6 hex address, which may be enclosed in
+ brackets, e.g. <literal>"[::1]"</literal>.</para>
+
+ <para>To determine whether the hostname was successfully resolved,
+ the <function>ne_addr_result</function> function is used, which
+ returns non-zero if an error occurred. If an error did occur, the
+ <function>ne_addr_error</function> function can be used, which
+ will copy the error string into a given
+ <parameter>buffer</parameter> (of size
+ <parameter>bufsiz</parameter>).</para>
+
+ <para>The functions <function>ne_addr_first</function> and
+ <function>ne_addr_next</function> are used to retrieve the
+ Internet addresses associated with an address object which has
+ been successfully resolved. <function>ne_addr_first</function>
+ returns the first address; <function>ne_addr_next</function>
+ returns the next address after the most recent call to
+ <function>ne_addr_next</function> or
+ <function>ne_addr_first</function>, or &null; if there are no more
+ addresses. The <type>ne_inet_addr</type> pointer returned by
+ these functions can be passed to
+ <function>ne_sock_connect</function> to connect a socket.</para>
+
+ <para>After the address object has been used, it should be
+ destroyed using <function>ne_addr_destroy</function>.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para><function>ne_addr_resolve</function> returns a pointer to an
+ address object, and never &null;.
+ <function>ne_addr_error</function> returns the
+ <parameter>buffer</parameter> parameter .</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>The code below prints out the set of addresses associated
+ with the hostname <literal>www.google.com</literal>.</para>
+
+ <programlisting>ne_sock_addr *addr;
+char buf[256];
+
+addr = ne_addr_resolve("www.google.com", 0);
+if (ne_addr_result(addr)) {
+ printf("Could not resolve www.google.com: %s\n",
+ ne_addr_error(addr, buf, sizeof buf));
+} else {
+ const ne_inet_addr *ia;
+ printf("www.google.com:");
+ for (ia = ne_addr_first(addr); ia != NULL; ia = ne_addr_next(addr)) {
+ printf(" %s", ne_iaddr_print(ia, buf, sizeof buf));
+ }
+ putchar('\n');
+}
+ne_addr_destroy(addr);
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_iaddr_print"/></para>
+ </refsect1>
+
+</refentry>
+
diff --git a/doc/ref/sess.xml b/doc/ref/sess.xml
new file mode 100644
index 0000000..8fcd9cb
--- /dev/null
+++ b/doc/ref/sess.xml
@@ -0,0 +1,123 @@
+ <refentry id="refsess">
+
+ <refmeta>
+ <refentrytitle>ne_session_create</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_session_create">ne_session_create</refname>
+ <refname id="ne_close_connection">ne_close_connection</refname>
+ <refname id="ne_session_proxy">ne_session_proxy</refname>
+ <refname id="ne_session_destroy">ne_session_destroy</refname>
+ <refpurpose>set up HTTP sessions</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;ne_session.h&gt;</funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>ne_session *<function>ne_session_create</function></funcdef>
+ <paramdef>const char *<parameter>scheme</parameter></paramdef>
+ <paramdef>const char *<parameter>hostname</parameter></paramdef>
+ <paramdef>unsigned int <parameter>port</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_session_proxy</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>const char *<parameter>hostname</parameter></paramdef>
+ <paramdef>unsigned int <parameter>port</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_close_connection</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_session_destroy</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>An <type>ne_session</type> object represents an HTTP
+session - a logical grouping of a sequence of HTTP requests made to a
+certain server. Any requests made using the session can use a
+persistent connection, share cached authentication credentials and any
+other common attributes.</para>
+
+ <para>A new HTTP session is created using
+<function>ne_session_create</function>, giving the
+<parameter>hostname</parameter> and <parameter>port</parameter> of the
+server to use, along with the <parameter>scheme</parameter> used to
+contact the server (usually <literal>"http"</literal>). Before the
+first use of <function>ne_session_create</function> in a process,
+<xref linkend="ne_sock_init"/> must have been called to perform any
+global initialization needed by any libraries used by &neon;.</para>
+
+ <para>To enable SSL/TLS for the session, pass the string
+<literal>"https"</literal> as the <parameter>scheme</parameter>
+parameter, and either register a certificate verification function
+(see <xref linkend="ne_ssl_set_verify"/>) or load the appropriate CA
+certificate (see <xref linkend="ne_ssl_load_ca"/>, <xref
+linkend="ne_ssl_load_default_ca"/>).</para>
+
+ <para>If an HTTP proxy server should be used for the session,
+<function>ne_session_proxy</function> must be called giving the
+hostname and port on which to contact the proxy.</para>
+
+ <para>If it is known that the session will not be used for a
+significant period of time, <function>ne_close_connection</function>
+can be called to close the connection, if one remains open. Use of
+this function is entirely optional, but it must not be called if there
+is a request active using the session.</para>
+
+ <para>Once a session has been completed,
+<function>ne_session_destroy</function> must be called to destroy the
+resources associated with the session. Any subsequent use of the
+session pointer produces undefined behaviour.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>The hostname passed to
+<function>ne_session_create</function> is resolved when the first
+request using the session is dispached; a DNS resolution failure can
+only be detected at that time (using the <literal>NE_LOOKUP</literal>
+error code); see <xref linkend="ne_request_dispatch"/> for
+details.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return Values</title>
+ <para><function>ne_session_create</function> will return
+ a pointer to a new session object (and never &null;).</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+ <para>Create and destroy a session:</para>
+ <programlisting>ne_session *sess;
+sess = ne_session_create("http", "host.example.com", 80);
+/* ... use sess ... */
+ne_session_destroy(sess);
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para><xref linkend="ne_ssl_set_verify"/>, <xref linkend="ne_ssl_load_ca"/>, <xref linkend="ne_sock_init"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/shave.xml b/doc/ref/shave.xml
new file mode 100644
index 0000000..a5b745a
--- /dev/null
+++ b/doc/ref/shave.xml
@@ -0,0 +1,51 @@
+ <refentry id="refshave">
+
+ <refmeta>
+ <refentrytitle>ne_shave</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ne_shave</refname>
+ <refpurpose>trim whitespace from a string</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_string.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_shave</function></funcdef>
+ <paramdef>char *<parameter>str</parameter></paramdef>
+ <paramdef>const char *<parameter>whitespace</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>ne_shave</function> returns a portion of
+<parameter>str</parameter> with any leading or trailing characters in
+the <parameter>whitespace</parameter> array removed.
+<parameter>str</parameter> may be modified.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>The following code segment will output
+ <literal>"fish"</literal>:</para>
+
+ <programlisting>char s[] = ".!.fish!.!";
+puts(ne_shave(s, ".!"));</programlisting>
+
+ </refsect1>
+
+ </refentry>
+
diff --git a/doc/ref/sslca.xml b/doc/ref/sslca.xml
new file mode 100644
index 0000000..c68739d
--- /dev/null
+++ b/doc/ref/sslca.xml
@@ -0,0 +1,81 @@
+ <refentry id="refsslca">
+
+ <refmeta>
+ <refentrytitle>ne_ssl_load_ca</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_ssl_load_ca">ne_ssl_load_ca</refname>
+ <refname id="ne_ssl_load_default_ca">ne_ssl_load_default_ca</refname>
+ <refpurpose>load SSL Certificate Authorities</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_session.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>ne_ssl_load_ca</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>const char *<parameter>filename</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>ne_ssl_load_default_ca</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To indicate that a given CA certificate is trusted by the user,
+the certificate can be loaded using the <function>ne_ssl_load_ca</function>
+function. The <parameter>filename</parameter> parameter given must specify
+the location of a PEM-encoded CA certificate.</para>
+
+ <para>The SSL library in use by neon may include a default set
+of CA certificates; calling the
+<function>ne_ssl_load_default_ca</function> function will indicate
+that these CAs are trusted by the user.</para>
+
+ <para>If no CA certificates are loaded, or the server presents
+a certificate which is invalid in some way, then the certificate must
+be manually verified (see <xref linkend="ne_ssl_set_verify"/>), otherwise the
+connection will fail.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para>Both <function>ne_ssl_load_ca</function> and
+<function>ne_ssl_load_default_ca</function> functions return
+<literal>0</literal> on success, or non-zero on failure.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>Load the CA certificate stored in <filename>/path/to/cacert.pem</filename>:</para>
+ <programlisting>&egsess;
+
+if (ne_ssl_load_ca(sess, "/path/to/cacert.pem")) {
+ printf("Could not load CA cert: %s\n", ne_get_error(sess));
+}</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_get_error"/>, <xref
+ linkend="ne_ssl_set_verify"/></para> </refsect1>
+
+ </refentry>
diff --git a/doc/ref/sslcert.xml b/doc/ref/sslcert.xml
new file mode 100644
index 0000000..46dbffd
--- /dev/null
+++ b/doc/ref/sslcert.xml
@@ -0,0 +1,66 @@
+ <refentry id="refsslcert">
+
+ <refmeta>
+ <refentrytitle>ne_ssl_certificate</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_ssl_certificate">ne_ssl_certificate</refname>
+ <refname id="ne_ssl_dname">ne_ssl_dname</refname>
+ <refpurpose>structures representing SSL certificates</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis><funcsynopsisinfo>#include &lt;ne_session.h&gt;
+
+/* A simplified X.509 distinguished name. */
+typedef struct {
+ const char *country, *state, *locality, *organization;
+ const char *organizationalUnit;
+ const char *commonName;
+} <type>ne_ssl_dname</type>;
+
+/* A simplified SSL certificate. */
+typedef struct {
+ const <type>ne_ssl_dname</type> *subject, *issuer;
+ const char *from, *until;
+} <type>ne_ssl_certificate</type>;
+
+</funcsynopsisinfo></funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <type>ne_ssl_dname</type> structure is used to
+represent a simplified X.509 distinguished name, as used in SSL
+certificates; a distinguished name is used to uniquely identify an
+entity. Along with the fields giving the geographical and
+organizational location of the entity, the
+<structfield>commonName</structfield> field will be assigned the DNS
+hostname of the entity. The
+<function>ne_ssl_readable_dname</function> function can be used to
+create a single-line string out of an <type>ne_ssl_dname</type>
+structure.</para>
+
+ <para>The <type>ne_ssl_certificate</type> structure is used to
+represent a simplified SSL certificate; containing the distinguished
+names of the <firstterm>issuer</firstterm> and
+<firstterm>subject</firstterm> of the certificate. The issuer is the
+entity which has digitally signed the certificate to guarantee its
+authenticity; the subject is the owner of the certificate. A
+certificate is only valid for a certain period of time: the
+<structfield>from</structfield> and <structfield>until</structfield>
+contain strings giving the validity period.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para><xref linkend="ne_ssl_dname"/>, <xref linkend="ne_ssl_set_verify"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/ssldname.xml b/doc/ref/ssldname.xml
new file mode 100644
index 0000000..accc2cb
--- /dev/null
+++ b/doc/ref/ssldname.xml
@@ -0,0 +1,66 @@
+
+ <refentry id="refssldname">
+
+ <refmeta>
+ <refentrytitle>ne_ssl_dname</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_ssl_readable_dname">ne_ssl_readable_dname</refname>
+ <refname id="ne_ssl_dname_cmp">ne_ssl_dname_cmp</refname>
+ <refpurpose>SSL distinguished name handling</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_ssl.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>const char *<function>ne_ssl_readable_dname</function></funcdef>
+ <paramdef>const ne_ssl_dname *<parameter>dname</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>ne_ssl_dname_cmp</function></funcdef>
+ <paramdef>const ne_ssl_dname *<parameter>dn1</parameter></paramdef>
+ <paramdef>const ne_ssl_dname *<parameter>dn2</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_ssl_readable_dname</function> function
+creates a single-line, human-readable string out of an
+<type>ne_ssl_dname</type> object. The returned string is
+<function>malloc</function>()-allocated, and must be
+<function>free</function>()d by the caller.</para>
+
+ <para>The <function>ne_ssl_dname_cmp</function> function
+ compares two distinguished names, and returns zero if they are
+ equal, or non-zero otherwise.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para><function>ne_ssl_readable_dname</function> returns a
+ <function>malloc</function>-allocated string, and never
+ NULL.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_ssl_certificate"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/sslvfy.xml b/doc/ref/sslvfy.xml
new file mode 100644
index 0000000..98f0054
--- /dev/null
+++ b/doc/ref/sslvfy.xml
@@ -0,0 +1,140 @@
+ <refentry id="refsslvfy">
+
+ <refmeta>
+ <refentrytitle>ne_ssl_set_verify</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_ssl_set_verify">ne_ssl_set_verify</refname>
+ <refpurpose>register an SSL certificate verification callback</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_session.h&gt;</funcsynopsisinfo>
+
+ <!-- hard to put data type declarations here -->
+
+ <funcprototype>
+ <funcdef>typedef int (*<function>ne_ssl_verify_fn</function>)</funcdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ <paramdef>int <parameter>failures</parameter></paramdef>
+ <paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>void <function>ne_ssl_set_verify</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>ne_ssl_verify_fn <parameter>verify_fn</parameter></paramdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>To enable manual SSL certificate verification, a
+callback can be registered using
+<function>ne_ssl_set_verify</function>. If such a callback is not
+registered, when a connection is established to an SSL server which
+does not present a certificate signed by a trusted CA (see <xref
+linkend="ne_ssl_load_ca"/>), or if the certificate presented is invalid in
+some way, the connection will fail.</para>
+
+ <para>When the callback is invoked, the
+<parameter>failures</parameter> parameter gives a bitmask indicating
+in what way the automatic certificate verification failed. The value
+is equal to the bit-wise OR of one or more of the following
+constants (and is guaranteed to be non-zero):</para>
+
+ <variablelist>
+ <varlistentry><term><filename>NE_SSL_NOTYETVALID</filename></term>
+ <listitem>
+ <para>The certificate is not yet valid.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><filename>NE_SSL_EXPIRED</filename></term>
+ <listitem>
+ <para>The certificate has expired.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><filename>NE_SSL_CNMISMATCH</filename></term>
+ <listitem>
+ <para>The hostname used for the session does not match
+the hostname to which the certificate was issued: this could mean that
+the connection has been intercepted.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry><term><filename>NE_SSL_UNKNOWNCA</filename></term>
+ <listitem>
+ <para>The Certificate Authority which signed the certificate
+is not trusted.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>The <parameter>cert</parameter> parameter passed to the
+callback describes the certificate which was presented by the server,
+see <xref linkend="ne_ssl_certificate"/> for more details. The certificate
+object given is only valid until the callback returns.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para>The verification callback must return zero to indicate
+that the certificate should be trusted; and non-zero otherwise (in
+which case, the connection will fail).</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>Manual certificate verification:</para>
+ <programlisting>
+static int
+my_verify(void *userdata, int failures, const ne_ssl_certificate *cert)
+{
+ /* leak the return values of ne_ssl_readable_dname for simplicity! */
+ printf("Issuer: %s\n", ne_ssl_readable_dname(cert->issuer);
+ printf("Subject: %s\n", ne_ssl_readable_dname(cert->subject);
+ if (failures &amp; NE_SSL_CNMISMATCH) {
+ printf("Server certificate was issued to `%s'; "
+ "connection may have been intercepted!\n",
+ cert->subject->commonName);
+ }
+ if (failures &amp; NE_SSL_EXPIRED) {
+ printf("Server certificate expired on %s!", cert->until);
+ }
+ /* ... check for other failures ... */
+ if (prompt_user())
+ return 1; /* fail verification */
+ else
+ return 0; /* trust certificate */
+}
+
+int
+main(...)
+{
+ ne_session *sess = ne_session_create("https", "some.host.name", 443);
+ ne_ssl_set_verify(sess, my_verify, NULL);
+ ...
+}</programlisting>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para><xref linkend="ne_ssl_certificate"/>, <xref linkend="ne_ssl_load_ca"/>,
+ <xref linkend="ne_ssl_dname"/>, <xref linkend="ne_ssl_readable_dname"/></para>
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/status.xml b/doc/ref/status.xml
new file mode 100644
index 0000000..56616ea
--- /dev/null
+++ b/doc/ref/status.xml
@@ -0,0 +1,74 @@
+ <refentry id="refstatus">
+
+ <refmeta>
+ <refentrytitle>ne_status</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_status">ne_status</refname>
+ <refpurpose>HTTP status structure</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis><funcsynopsisinfo>#include &lt;ne_utils.h&gt;
+
+typedef struct {
+ int major_version, minor_version;
+ int code, klass;
+ const char *reason_phrase;
+} <type>ne_status</type>;</funcsynopsisinfo></funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>An <type>ne_status</type> type represents an HTTP
+response status; used in response messages giving a result of request.
+The <structfield>major_version</structfield> and
+<structfield>minor_version</structfield> fields give the HTTP version
+supported by the server issuing the response. The
+<structfield>code</structfield> field gives the status code of the
+result (lying between 100 and 999 inclusive), and the
+<structfield>klass</structfield> field gives the class, which is equal
+to the most significant digit of the status.</para>
+
+ <para>There are five classes of HTTP status code defined by
+ RFC2616:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>1xx</literal></term>
+ <listitem><para>Informational response.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>2xx</literal></term>
+ <listitem><para>Success: the operation was successful</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>3xx</literal></term>
+ <listitem><para>Redirection</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>4xx</literal></term> <listitem><para>Client
+ error: the request made was incorrect in some
+ manner.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>5xx</literal></term>
+ <listitem><para>Server error</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ </refsect1>
+
+ <refsect1> <title>See also</title> <para><xref
+linkend="ne_get_status"/>.</para> </refsect1>
+
+ </refentry>
diff --git a/doc/ref/tok.xml b/doc/ref/tok.xml
new file mode 100644
index 0000000..2e6211f
--- /dev/null
+++ b/doc/ref/tok.xml
@@ -0,0 +1,76 @@
+ <refentry id="reftok">
+
+ <refmeta>
+ <refentrytitle>ne_token</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ne_token</refname>
+ <refname>ne_qtoken</refname>
+ <refpurpose>string tokenizers</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_string.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_token</function></funcdef>
+ <paramdef>char **<parameter>str</parameter></paramdef>
+ <paramdef>char <parameter>sep</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>char *<function>ne_qtoken</function></funcdef>
+ <paramdef>char **<parameter>str</parameter></paramdef>
+ <paramdef>char <parameter>sep</parameter></paramdef>
+ <paramdef>const char *<parameter>quotes</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <!-- FIXME: italics on tokenize -->
+
+ <para><function>ne_token</function> and
+<function>ne_qtoken</function> tokenize the string at the location
+stored in the pointer <parameter>str</parameter>. Each time the
+function is called, it returns the next token, and modifies the
+<parameter>str</parameter> pointer to point to the remainer of the
+string, or &null; if there are no more tokens in the string. A token
+is delimited by the separator character <parameter>sep</parameter>; if
+<function>ne_qtoken</function> is used any quoted segments of the
+string are skipped when searching for a separator. A quoted segment
+is enclosed in a pair of one of the characters given in the
+<parameter>quotes</parameter> string.</para>
+
+ <para>The string being tokenized is modified each time
+the tokenizing function is called; replacing the next separator
+character with a &nul; terminator.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>The following function prints out each token in a
+comma-separated string <parameter>list</parameter>, which is
+modified in-place:</para>
+
+ <programlisting>static void splitter(char *list)
+{
+ do {
+ printf("Token: %s\n", ne_token(&amp;list, ','));
+ while (list);
+}</programlisting>
+
+ </refsect1>
+
+ </refentry>
diff --git a/doc/ref/vers.xml b/doc/ref/vers.xml
new file mode 100644
index 0000000..2e7a50d
--- /dev/null
+++ b/doc/ref/vers.xml
@@ -0,0 +1,63 @@
+<refentry id="refvers">
+
+ <refmeta>
+ <refentrytitle>ne_version_match</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ne_version_match</refname>
+ <refname>ne_version_string</refname>
+ <refpurpose>library versioning</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_utils.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>ne_version_match</function></funcdef>
+ <paramdef>int <parameter>major</parameter></paramdef>
+ <paramdef>int <parameter>minor</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>const char *<function>ne_version_string</function></funcdef>
+ <void/>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <function>ne_version_match</function> function returns
+ non-zero if the library version is not of major version
+ <parameter>major</parameter>, or the minor version is less than
+ <parameter>minor</parameter>. For &neon; versions 0.x, every
+ minor version is assumed to be incompatible with every other minor
+ version.</para> <!-- TODO: remove that for 1.0 -->
+
+ <para>The <function>ne_version_string</function> function returns
+ a string giving the library version.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>To require &neon; 1.x, version 1.2 or later:</para>
+
+ <programlisting>if (ne_version_match(1, 2)) {
+ printf("Library version out of date: 1.2 required, found %s.",
+ ne_version_string());
+ exit(1);
+}</programlisting>
+
+ </refsect1>
+
+</refentry>
diff --git a/doc/refentry.xml b/doc/refentry.xml
new file mode 100644
index 0000000..bf724e0
--- /dev/null
+++ b/doc/refentry.xml
@@ -0,0 +1,56 @@
+<refentry id="refXXXX">
+
+ <refmeta>
+ <refentrytitle>ne_foo</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname id="ne_foo">ne_foo</refname>
+ <refname id="ne_bar">ne_bar</refname>
+ <refpurpose>functions which do foo and bar</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+
+ <funcsynopsis>
+
+ <funcsynopsisinfo>#include &lt;ne_header.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>void <function>ne_set_useragent</function></funcdef>
+ <paramdef>ne_session *<parameter>session</parameter></paramdef>
+ <paramdef>const char *<parameter>product</parameter></paramdef>
+ </funcprototype>
+
+ </funcsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>XXX</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Return value</title>
+
+ <para>XXX</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>XXX</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para>XXX</para>
+ </refsect1>
+
+</refentry>
+
diff --git a/doc/using-neon.txt b/doc/using-neon.txt
new file mode 100644
index 0000000..45ddfc3
--- /dev/null
+++ b/doc/using-neon.txt
@@ -0,0 +1,166 @@
+
+Guide to neon
+=============
+
+Using libneon from applications
+-------------------------------
+
+The neon source package is designed to be easily incorporated into
+applications:
+
+- autoconf macros are distributed in the 'macros' subdirectory of the
+ neon distribution. Use NEON_LIBRARY from your configure.in to check
+ for the presence of the neon library installed on the system. The
+ macro adds an '--with-neon=...' argument to configure, which allows
+ the user to specify a location for the library (the standard /usr
+ and /usr/local directories are checked automatically without having
+ to be specified).
+
+- The 'src' directory of the neon package can be imported directly
+ into your application, if you do not wish to add an external
+ dependency. If you wish to bundle, use the NEON_BUNDLED macro
+ to configure neon in your application: here, the neon sources are
+ bundled in a directory called 'libneon':
+
+ NEON_BUNDLED(libneon, ...)
+
+ If your application supports builds where srcdir != builddir, you
+ should use the NEON_VPATH_BUNDLED macro like this:
+
+ NEON_VPATH_BUNDLED(${srcdir}/libneon, libneon, ...)
+
+ (thanks to Peter Moulder for getting this working properly).
+
+ If you use this macro, a '--with-included-neon' option will
+ be added to the generated configure script. This allows the user
+ to force the bundled neon to be used in the application, rather than
+ any neon library found on the system. If you allow neon to be
+ configured this way, you must also configure an XML parser. Use
+ the NEON_XML_PARSER macro to do this.
+
+- The final argument to the _BUNDLED macros is a set of actions which
+ are executed if the bundled build *is* chosen (rather than an
+ external neon which might have been found on the user's system).
+ In here, use either the NEON_LIBTOOL_BUILD or NEON_NORMAL_BUILD
+ macro to set up the neon Makefile appropriately: including adding
+ the neon source directory to the recursive make.
+
+- A full fragment might be:
+
+ NEON_BUNDLED(libneon, [
+ NEON_NORMAL_BUILD
+ NEON_XML_PARSER
+ SUBDIRS="libneon $SUBDIRS"
+ ])
+
+ This means the bundled neon source directory (called 'libneon') is
+ used if no neon is found on the system, and the standard XML parser
+ search is used.
+
+The neon API
+============
+
+neon offers two levels of API for use in applications:
+
+- Low-level HTTP request/response handling
+- High-level method invocation
+
+The low-level interface allows for easily designing new method
+handlers, taking care of things like persistent connections,
+authentication, and proxy servers. The high-level interface allows
+you to easily integrate existing HTTP (and WebDAV) methods into your
+application. This document details both interfaces.
+
+N.B.: Documentation is always WRONG. The definitive API reference is in
+src/*.c, with src/*.h is hopefully fairly similar.
+
+PLEASE NOTE: the neon API is NOT STABLE, and is not considered to be
+stable or backwards-compatible until version 1.0 is reached. If
+you are not happy with this constraint, then please either:
+
+1. pick a version of neon and never upgrade
+2. don't use neon (yet).
+3. contribute sufficient development resources to neon that all
+ bugs are fixed yesterday, features added tomorrow, and 1.0 is
+ reached on by the end of the week.
+
+An Important Note
+-----------------
+
+Most neon functions which allocate memory with malloc() will call
+abort() if malloc() returns NULL. This is a design decision, the
+rationale being:
+
+- it makes the interfaces cleaner.
+
+- if malloc() DOES return NULL there is not much you can do about it.
+
+- Apparently, malloc() won't return NULL on systems which over-commit
+ memory (e.g. Linux), so it doesn't make any real difference anyway.
+
+The author is open to persuasion on this: mail neon@webdav.org.
+
+Namespaces
+----------
+
+neon reserves these namespaces:
+ ne_*
+ uri_*
+ sock_*
+
+Eventually all symbols globally defined by the library should fall
+within a reserved namespace. The author is considering moving
+all symbols into the ne_* namespace.
+
+Note that the XML parser used will also reserve a namespace:
+expat takes XML_*, libxml takes xml*
+
+The http_session type
+---------------------
+
+The http_session type is used whether you are writing to the low-level
+or the high-level interface. An http_session object is created to
+store data which persists beyond a single HTTP request:
+
+ - Protocol options, e.g. (proxy) server details
+ - Authentication information
+ - Persistent connection
+
+A session is created with the 'ne_session_create' call. Before
+creating a request for the session, the server details must be set, as
+follows:
+
+ ne_session *sess;
+ /* Initialize the socket library */
+ sock_init();
+ /* Create the session */
+ sess = ne_session_create();
+ /* Optionally, set a proxy server */
+ ne_session_proxy(sess, "proxy.myisp.com", 8080);
+ /* Set the server */
+ ne_session_server(sess, "my.server.com", 80);
+
+The proxy server should be set BEFORE the origin server; otherwise a
+DNS lookup will be performed on the origin server by the
+ne_session_server call, which may well fail if the client is
+firewalled. ne_session_{proxy,server} will return NE_LOOKUP if
+the DNS lookup fails; otherwise NE_OK.
+
+The 'ne_set_persist' call can be used to turn off persistent
+connection handling: it is on by default.
+
+The 'ne_set_useragent' call can be used to set the User-Agent header
+to be sent with requests. A product token of the form
+"myhttpclient/0.1.2" should be passed, and will have "neon/x.y.z"
+appended in the actual header sent.
+
+When a session has been finished with, it should be destroyed using
+ne_session_destroy. Any subsequent operations on the session object
+will have undefined results (i.e. will segfault).
+
+Low-level HTTP Request/Response Handling
+----------------------------------------
+
+...
+
+
diff --git a/doc/using.xml b/doc/using.xml
new file mode 100644
index 0000000..efb53d1
--- /dev/null
+++ b/doc/using.xml
@@ -0,0 +1,119 @@
+ <sect1 id="using">
+ <title>How to use neon from your application</title>
+
+ <para>This section describes how to add &neon; support to an
+ application. If you just want to quickly try out &neon;, use
+ the <xref linkend="refconfig"/> script.</para>
+
+ <para>The &neon; source code is designed to be easily embedded
+ into an application source tree. &neon; has no dependencies on
+ libraries other than an SSL toolkit and XML parser, though the
+ source tree can be configured to have no support for SSL or XML
+ if desired. To configure the &neon; source code some <ulink
+ url="http://www.gnu.org/software/autoconf/">GNU autoconf</ulink>
+ macros are supplied, which can be used in a number of ways, as
+ follows:</para>
+
+ <itemizedlist>
+ <listitem>
+
+ <para>autoconf macros are distributed in the 'macros'
+ subdirectory of the neon distribution. Use the NEON_LIBRARY
+ macro from your configure.in to check for the presence of
+ the neon library installed on the system. The macro adds an
+ '--with-neon=...' argument to configure, which allows the
+ user to specify a location for the library (the standard
+ /usr and /usr/local directories are checked automatically
+ without having to be specified).</para></listitem>
+
+ <listitem><para>The 'src' directory of the neon package can be
+ imported directly into your application, if you do not wish
+ to add an external dependency. If you wish to bundle, use
+ the NEON_BUNDLED macro to configure neon in your application:
+ here, the neon sources are bundled in a directory called
+ 'libneon':</para>
+
+ <programlisting>NEON_BUNDLED(libneon, ...)</programlisting>
+
+ <para>If your application supports builds where srcdir != builddir,
+ you should use the NEON_VPATH_BUNDLED macro like this:</para>
+
+ <programlisting>NEON_VPATH_BUNDLED(${srcdir}/libneon, libneon, ...)</programlisting>
+
+ <para>If you use this macro, a '--with-included-neon' option
+ will be added to the generated configure script. This
+ allows the user to force the bundled neon to be used in the
+ application, rather than any neon library found on the
+ system. If you allow neon to be configured this way, you
+ must also configure an XML parser. Use the NEON_XML_PARSER
+ macro to do this.</para></listitem>
+
+ <listitem><para>The final argument to the _BUNDLED macros is a
+ set of actions which are executed if the bundled build *is*
+ chosen (rather than an external neon which might have been
+ found on the user's system). In here, use either the
+ NEON_LIBTOOL_BUILD or NEON_NORMAL_BUILD macro to set up the
+ neon Makefile appropriately: including adding the neon source
+ directory to the recursive make.</para></listitem>
+
+ </itemizedlist>
+
+ <para>A full fragment might be:</para>
+
+<programlisting>NEON_BUNDLED(libneon, [
+ NEON_NORMAL_BUILD
+ NEON_XML_PARSER
+ SUBDIRS="libneon $SUBDIRS"
+])</programlisting>
+
+ <para>This means the bundled neon source directory (called 'libneon')
+ is used if no neon is found on the system, and the standard XML
+ parser search is used.</para>
+
+ </sect1>
+
+ <sect1 id="compliance">
+ <title>Protocol compliance</title>
+
+ <para>&neon; is intended to be compliant with the IETF
+ protocol standards it implements, with a few exceptions where
+ real-world use has necessitated minor deviations. These
+ exceptions are documented in this section.</para>
+
+ <sect2><title>RFC 2518, HTTP Extensions for Distributed Authoring&mdash;WebDAV</title>
+
+ <para>&neon; is deliberately not compliant with section
+ 23.4.2, and treats property names as a (namespace-URI, name)
+ pair. This is <ulink
+ url="http://lists.w3.org/Archives/Public/w3c-dist-auth/1999OctDec/0343.html">generally
+ considered</ulink> to be correct behaviour by the WebDAV
+ working group, and is likely to formally adopted in a future
+ revision of the specification.</para></sect2>
+
+ <sect2><title>RFC 2616, Hypertext Transfer Protocol&mdash;HTTP/1.1</title>
+
+ <para>There is some confusion in this specification about the
+ use of the <quote>identity</quote>
+ <firstterm>transfer-coding</firstterm>. &neon; treats the
+ presence of <emphasis>any</emphasis>
+ <literal>Transfer-Encoding</literal> response header as an
+ indication that the response message uses the
+ <quote>chunked</quote> transfer-coding. This was the
+ suggested resolution <ulink
+ url="http://lists.w3.org/Archives/Public/ietf-http-wg-old/2001SepDec/0018.html">proposed
+ by Larry Masinter</ulink>.</para></sect2>
+
+ <sect2>
+ <title>RFC 2617, HTTP Authentication: Basic and Digest Access Authentication</title>
+
+ <para>&neon; is not strictly compliant with the quoting rules
+ given in the grammar for the <literal>Authorization</literal>
+ header. The grammar requires that the <literal>qop</literal>
+ and <literal>algorithm</literal> parameters are not quoted,
+ however one widely deployed server implementation
+ (Microsoft&reg; IIS 5) rejects the request if these parameters
+ are not quoted. &neon; sends these parameters with
+ quotes&mdash;this is not known to cause any problems with
+ other server implementations.</para></sect2>
+
+ </sect1>
diff --git a/doc/xml.xml b/doc/xml.xml
new file mode 100644
index 0000000..c001073
--- /dev/null
+++ b/doc/xml.xml
@@ -0,0 +1,207 @@
+<!-- neon XML interface -*- text -*- -->
+
+<sect1 id="xml">
+
+ <title>Parsing XML</title>
+
+ <para>The &neon; XML interface is exposed by the
+ <filename>ne_xml.h</filename> header file. This interface gives a
+ wrapper around the standard <ulink
+ url="http://www.saxproject.org/">SAX</ulink> API used by XML
+ parsers, with an additional abstraction, <firstterm>stacked SAX
+ handlers</firstterm>, and also giving consistent <ulink
+ url="http://www.w3.org/TR/REC-xml-names">XML Namespace
+ support</ulink>.</para>
+
+<sect2 id="xml-sax">
+ <title>Introduction to SAX</title>
+
+ <para>A SAX-based parser works by emitting a sequence of
+ <firstterm>events</firstterm> to reflect the tokens being parsed
+ from the XML document. For example, parsing the following document
+ fragment:
+
+<programlisting><![CDATA[
+<hello>world</hello>
+]]></programlisting>
+
+ results in the following events:
+
+ <orderedlist>
+ <listitem>
+ <simpara>&startelm; "hello"</simpara>
+ </listitem>
+ <listitem>
+ <simpara>&cdata; "world"</simpara>
+ </listitem>
+ <listitem>
+ <simpara>&endelm; "hello"</simpara>
+ </listitem>
+ </orderedlist>
+
+ This example demonstrates the three event types used used in the
+ subset of SAX exposed by the &neon; XML interface: &startelm;,
+ &cdata; and &endelm;. In a C API, an <quote>event</quote> is
+ implemented as a function callback; three callback types are used in
+ &neon;, one for each type of event.</para>
+
+</sect2>
+
+<sect2 id="xml-stacked">
+ <title>Stacked SAX handlers</title>
+
+ <para>WebDAV property values are represented as fragments of XML,
+ transmitted as parts of larger XML documents over HTTP (notably in
+ the body of the response to a <literal>PROPFIND</literal> request).
+ When &neon; parses such documents, the SAX events generated for
+ these property value fragments may need to be handled by the
+ application, since &neon; has no knowledge of the structure of
+ properties used by the application.</para>
+
+ <para>To solve this problem<footnote><para>This
+ <quote>problem</quote> only needs solving because the SAX interface
+ is so inflexible when implemented as C function callbacks; a better
+ approach would be to use an XML parser interface which is not based
+ on callbacks.</para></footnote> the &neon; XML interface introduces
+ the concept of a <firstterm>SAX handler</firstterm>. A SAX handler
+ comprises a &startelm;, &cdata; and &endelm; callback; the
+ &startelm; callback being defined such that each handler may
+ <emphasis>accept</emphasis> or <emphasis>decline</emphasis> the
+ &startelm; event. Handlers are composed into a <firstterm>handler
+ stack</firstterm> before parsing a document. When a new &startelm;
+ event is generated by the XML parser, &neon; invokes each &startelm;
+ callback in the handler stack in turn until one accepts the event.
+ The handler which accepts the event will then be subsequently be
+ passed &cdata; events if the element contains character data,
+ followed by an &endelm; event when the element is closed. If no
+ handler in the stack accepts a &startelm; event, the branch of the
+ tree is ignored.</para>
+
+ <para>To illustrate, given a handler A, which accepts the
+ <literal>cat</literal> and <literal>age</literal> elements, and a
+ handler B, which accepts the <literal>name</literal> element, the
+ following document:
+
+<example id="xml-example">
+<title>An example XML document</title>
+<programlisting><![CDATA[
+<cat>
+ <age>3</age>
+ <name>Bob</name>
+</cat>
+]]></programlisting></example>
+
+ would be parsed as follows:
+
+ <orderedlist>
+ <listitem>
+ <simpara>A &startelm; "cat" &rarr; <emphasis>accept</emphasis></simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &startelm; "age" &rarr; <emphasis>accept</emphasis></simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &cdata; "3"</simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &endelm; "age"</simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &startelm; "name" &rarr; <emphasis>decline</emphasis></simpara>
+ </listitem>
+ <listitem>
+ <simpara>B &startelm; "name" &rarr; <emphasis>accept</emphasis></simpara>
+ </listitem>
+ <listitem>
+ <simpara>B &cdata; "Bob"</simpara>
+ </listitem>
+ <listitem>
+ <simpara>B &endelm; "name"</simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &endelm; "cat"</simpara>
+ </listitem>
+ </orderedlist></para>
+
+ <para>The search for a handler which will accept a &startelm; event
+ begins at the handler of the parent element and continues toward the
+ top of the stack. For the root element, it begins at the base of
+ the stack. In the above example, handler A is at the base, and
+ handler B at the top; if the <literal>name</literal> element had any
+ children, only B's &startelm; would be invoked to accept
+ them.</para>
+
+</sect2>
+
+<sect2 id="xml-state">
+ <title>Maintaining state</title>
+
+ <para>To facilitate communication between independent handlers, a
+ <firstterm>state integer</firstterm> is associated with each element
+ being parsed. This integer is returned by &startelm; callback and
+ is passed to the subsequent &cdata; and &endelm; callbacks
+ associated with the element. The state integer of the parent
+ element is also passed to each &startelm; callback, the value zero
+ used for the root element (which by definition has no
+ parent).</para>
+
+ <para>To further extend <xref linkend="xml-example"/>: if handler A
+ defines that the state of the root element <sgmltag>cat</sgmltag>
+ will be <literal>42</literal>, the event trace would be as
+ follows:
+
+ <orderedlist>
+ <listitem>
+ <simpara>A &startelm; (parent = 0, "cat") &rarr;
+ <emphasis>accept</emphasis>, state = 42
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &startelm; (parent = 42, "age") &rarr;
+ <emphasis>accept</emphasis>, state = 50
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &cdata; (state = 50, "3")</simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &endelm; (state = 50, "age")</simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &startelm; (parent = 42, "name") &rarr;
+ <emphasis>decline</emphasis></simpara>
+ </listitem>
+ <listitem>
+ <simpara>B &startelm; (parent = 42, "name") &rarr;
+ <emphasis>accept</emphasis>, state = 99</simpara>
+ </listitem>
+ <listitem>
+ <simpara>B &cdata; (state = 99, "Bob")</simpara>
+ </listitem>
+ <listitem>
+ <simpara>B &endelm; (state = 99, "name")</simpara>
+ </listitem>
+ <listitem>
+ <simpara>A &endelm; (state = 42, "cat")</simpara>
+ </listitem>
+ </orderedlist></para>
+
+ <para>To avoid collisions between state integers used by different
+ handlers, the interface definition of any handler includes the range
+ of integers it will use.</para>
+
+</sect2>
+
+<sect2 id="xml-ns">
+ <title>XML namespaces</title>
+
+ <para>To support XML namespaces, every element name is represented
+ as a <emphasis>(namespace, name)</emphasis> pair. The &startelm;
+ and &endelm; callbacks are passed namespace and name strings
+ accordingly. If an element in the XML document has no declared
+ namespace, the namespace given will be the empty string,
+ <literal>""</literal>.</para>
+
+</sect2>
+
+</sect1>