This commit is contained in:
biosvos
2026-08-07 17:38:18 +09:00
commit 873193a243
9613 changed files with 2755992 additions and 0 deletions
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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_cert</type> object. If the client
certificate is encrypted, it must be decrypted before it is used.
An <type>ne_ssl_client_cert</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_name</function> will return
this name (or &null; if no friendly name was specified).
<function>ne_ssl_clicert_name</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_cert *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_cert_read"/></para>
</refsect1>
</refentry>
@@ -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>
@@ -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>
@@ -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>
@@ -0,0 +1,133 @@
<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_typeof">ne_iaddr_typeof</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>ia1</parameter></paramdef>
<paramdef>const ne_inet_addr *<parameter>ia2</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>ne_iaddr_type <function>ne_iaddr_typeof</function></funcdef>
<paramdef>const ne_inet_addr *<parameter>ia</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>void <function>ne_iaddr_free</function></funcdef>
<paramdef>const ne_inet_addr *<parameter>ia</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_typeof</function> returns the type of the
given network address.</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>
@@ -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>
@@ -0,0 +1,182 @@
<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 relies on the operating system providing
a thread-safe resolver interface. Modern operating systems offer
the thread-safe <function>getaddrinfo</function> interface, which
&neon; supports; some others implement
<function>gethostbyname</function> using thread-local
storage.</para>
<para>To allow thread-safe use of the OpenSSL library, the
application must register some locking callbacks in accordance
with the <ulink
url="http://www.openssl.org/docs/crypto/threads.html">OpenSSL
documentation</ulink>.</para>
<para>Some platforms and libraries used by &neon; require global
initialization before use; notably:
<itemizedlist>
<listitem><simpara>OpenSSL requires global initialization to
load shared lookup tables.</simpara></listitem>
<listitem><simpara>The SOCKS library requires initialization
before use.</simpara></listitem>
<listitem><simpara>The Win32 socket library requires
initialization before use.</simpara></listitem>
</itemizedlist>
The <xref linkend="ne_sock_init"/> function should be called
before any other use of &neon; to perform any necessary
initialization needed for the particular platform.</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 the parameters
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 is
said to produce <emphasis>undefined behaviour</emphasis>; it is
likely that &neon; will segfault under these conditions.</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>User interaction</title>
<para>As a pure library interface, &neon; will never produce
output on <constant>stdout</constant> or
<constant>stderr</constant>; all user interaction is the
responsibilty of the application.</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>
@@ -0,0 +1,110 @@
<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_get_scheme">ne_get_scheme</refname>
<refname id="ne_get_server_hostport">ne_get_server_hostport</refname>
<refpurpose>common properties 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>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>
<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>The scheme used to initially create the session will be
returned by <function>ne_get_scheme</function>.</para>
<para>The hostport pair with which the session is associated
will be returned by the
<function>ne_get_server_hostport</function>; for example
<literal>www.example.com:8080</literal>. Note that the
<literal>:port</literal> will be omitted if the default port
for the scheme is used.</para>
</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>
@@ -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>
@@ -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>
@@ -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>
@@ -0,0 +1,60 @@
<refentry id="refreqopts">
<refmeta>
<refentrytitle>ne_set_request_expect100</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname id="ne_set_request_expect100">ne_set_request_expect100</refname>
<refpurpose>function to enable Expect: 100-continue support</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;ne_request.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>void <function>ne_set_request_expect100</function></funcdef>
<paramdef>ne_request *<parameter>request</parameter></paramdef>
<paramdef>int <parameter>flag</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<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_request_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>See also</title>
<para><xref linkend="ne_request_create"/>.</para>
</refsect1>
</refentry>
@@ -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>
@@ -0,0 +1,98 @@
<refentry id="refresphdr">
<refmeta>
<refentrytitle>ne_get_response_header</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname id="ne_get_response_header">ne_get_response_header</refname>
<refname id="ne_response_header_iterate">ne_response_header_iterate</refname>
<refpurpose>functions to access response headers</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;ne_request.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>const char *<function>ne_get_response_header</function></funcdef>
<paramdef>ne_request *<parameter>request</parameter></paramdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>void *<function>ne_response_header_iterate</function></funcdef>
<paramdef>ne_request *<parameter>request</parameter></paramdef>
<paramdef>void *<parameter>cursor</parameter></paramdef>
<paramdef>const char **<parameter>name</parameter></paramdef>
<paramdef>const char **<parameter>value</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>To retrieve the value of a response header field, the
<function>ne_get_response_header</function> function can be used,
and is given the name of the header to return.</para>
<para>To iterate over all the response headers returned, the
<function>ne_response_header_iterate</function> function can be
used. This function takes a <parameter>cursor</parameter>
parameter which should be &null; to retrieve the first header. The
function stores the name and value of the next header header in
the <parameter>name</parameter> and <parameter>value</parameter>
parameters, and returns a new cursor pointer which can be passed
to <function>ne_response_header_iterate</function> to retrieve the
next header.</para>
</refsect1>
<refsect1>
<title>Return value</title>
<para><function>ne_get_response_header</function> returns a
string, or &null; if no header with that name was given. If used
during request processing, the return value pointer is valid only
until the next call to <function>ne_begin_request</function>, or
else, until the request object is destroyed.</para>
<para>Likewise, the cursor, names, and values returned by
<function>ne_response_header_iterate</function> are only valid
until the next call to <function>ne_begin_request</function> or
until the request object is destroyed.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>The following code will output the value of the
<literal>Last-Modified</literal> header for a resource:</para>
<programlisting>ne_request *req = ne_request_create(sess, "GET", "/foo.txt");
if (ne_request_dispatch(req) == NE_OK) {
const char *mtime = ne_get_response_header(req, "Last-Modified");
if (mtime) {
printf("/foo.txt has last-modified value %s\n", mtime);
}
}
ne_request_destroy(req);</programlisting>
</refsect1>
<refsect1>
<title>See also</title>
<para><xref linkend="ne_request_create"/>, <xref
linkend="ne_request_destroy"/>.</para>
</refsect1>
</refentry>
@@ -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 trust the appropriate
certificate (see <xref linkend="ne_ssl_trust_cert"/>, <xref
linkend="ne_ssl_trust_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 dispatched; 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_trust_cert"/>, <xref linkend="ne_sock_init"/></para>
</refsect1>
</refentry>
@@ -0,0 +1,52 @@
<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. Note that the return
value may not be equal to <parameter>str</parameter>.</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>
@@ -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>
@@ -0,0 +1,111 @@
<refentry id="refcert">
<refmeta>
<refentrytitle>ne_ssl_cert_identity</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname id="ne_ssl_cert_identity">ne_ssl_cert_identity</refname>
<refname id="ne_ssl_cert_signedby">ne_ssl_cert_signedby</refname>
<refname id="ne_ssl_cert_issuer">ne_ssl_cert_issuer</refname>
<refname id="ne_ssl_cert_subject">ne_ssl_cert_subject</refname>
<refpurpose>functions to access certificate properties</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;ne_ssl.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>const char *<function>ne_ssl_cert_identity</function></funcdef>
<paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>const ne_ssl_certificate *<function>ne_ssl_cert_signedby</function></funcdef>
<paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>const ne_ssl_dname *<function>ne_ssl_cert_subject</function></funcdef>
<paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>const ne_ssl_dname *<function>ne_ssl_cert_issuer</function></funcdef>
<paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>The function <function>ne_ssl_cert_identity</function>
retrieves the <quote>identity</quote> of a certificate; for an
SSL server certificate, this will be the hostname for which the
certificate was issued. In PKI parlance, the identity is the
<emphasis>common name</emphasis> attribute of the distinguished name of
the certificate subject.</para>
<para>The functions <function>ne_ssl_cert_subject</function> and
<function>ne_ssl_cert_issuer</function> can be used to access the
objects representing the distinguished name of the subject and of
the issuer of a certificate, respectively.</para>
<para>If a certificate object is part of a certificate chain, then
<function>ne_ssl_cert_signedby</function> can be used to find the
certificate which signed a particular certificate. For a
self-signed certificate or a certificate for which the full chain
is not available, this function will return &null;.</para>
</refsect1>
<refsect1>
<title>Return value</title>
<para><function>ne_ssl_cert_issuer</function> and
<function>ne_ssl_cert_subject</function> are guaranteed to never
return &null;. <function>ne_ssl_cert_identity</function> may
return &null; if the certificate has no specific
<quote>identity</quote>. <function>ne_ssl_cert_signedby</function>
may return &null; as covered above.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>The following function could be used to display information
about a given certificate:</para>
<programlisting>void dump_cert(const ne_ssl_certificate *cert) {
const char *id = ne_ssl_cert_identity(cert);
char *dn;
if (id)
printf("Certificate was issued for '%s'.\n", id);
dn = ne_ssl_readable_dname(ne_ssl_cert_subject(cert));
printf("Subject: %s\n", dn);
free(dn);
dn = ne_ssl_readable_dname(ne_ssl_cert_issuer(cert));
printf("Issuer: %s\n", dn);
free(dn);
}</programlisting>
</refsect1>
<refsect1>
<title>See also</title>
<para><xref linkend="ne_ssl_cert_cmp"/>, <xref linkend="ne_ssl_readable_dname"/></para>
</refsect1>
</refentry>
@@ -0,0 +1,49 @@
<refentry id="refsslcert2">
<refmeta>
<refentrytitle>ne_ssl_cert_cmp</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname id="ne_ssl_cert_cmp">ne_ssl_cert_cmp</refname>
<refname id="ne_ssl_cert_free">ne_ssl_cert_free</refname>
<refpurpose>functions to operate on certificate objects</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;ne_header.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>ne_ssl_cert_cmp</function></funcdef>
<paramdef>const ne_ssl_certificate *<parameter>c1</parameter></paramdef>
<paramdef>const ne_ssl_certificate *<parameter>c2</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>void <function>ne_ssl_cert_free</function></funcdef>
<paramdef>ne_ssl_certificate *<parameter>cert</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>The <function>ne_ssl_cert_cmp</function> function can be
used to compare two certificate objects; it returns zero if they
refer to the same certificate, and non-zero otherwise.</para>
<para>The <function>ne_ssl_cert_free</function> function can be
used to destroy a certificate object when it is no longer
needed.</para>
</refsect1>
</refentry>
@@ -0,0 +1,95 @@
<refentry id="refsslcertio">
<refmeta>
<refentrytitle>ne_ssl_cert_read</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname id="ne_ssl_cert_read">ne_ssl_cert_read</refname>
<refname id="ne_ssl_cert_write">ne_ssl_cert_write</refname>
<refname id="ne_ssl_cert_import">ne_ssl_cert_import</refname>
<refname id="ne_ssl_cert_export">ne_ssl_cert_export</refname>
<refpurpose>functions to read or write certificates to and from files or strings</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;ne_ssl.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>ne_ssl_certificate *<function>ne_ssl_cert_read</function></funcdef>
<paramdef>const char *<parameter>filename</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>ne_ssl_cert_write</function></funcdef>
<paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
<paramdef>const char *<parameter>filename</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>ne_ssl_certificate *<function>ne_ssl_cert_import</function></funcdef>
<paramdef>const char *<parameter>data</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>char *<function>ne_ssl_cert_export</function></funcdef>
<paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>The <function>ne_ssl_cert_write</function> function writes a
certificate to a file using the PEM encoding. The
<function>ne_ssl_cert_export</function> function returns a
base64-encoded &nul;-terminated string representing the
certificate. This string is malloc-allocated and should be
destroyed using <function>free</function> by the caller.</para>
<para>The <function>ne_ssl_cert_read</function> function reads a
certificate from a PEM-encoded file, and returns a certificate
object. The <function>ne_ssl_cert_import</function> function
returns a certificate object from a base64-encoded string,
<parameter>data</parameter>, as returned by
<function>ne_ssl_cert_export</function>. The certificate object
returned by these functions should be destroyed using <xref
linkend="ne_ssl_cert_free"/> after use.</para>
</refsect1>
<refsect1>
<title>Return value</title>
<para><function>ne_ssl_cert_read</function> returns &null; if a
certificate could not be read from the file.
<function>ne_ssl_cert_write</function> returns non-zero if the
certificate could not be written to the file.
<function>ne_ssl_cert_export</function> always returns a
&nul;-terminated string, and never &null;.
<function>ne_ssl_cert_import</function> returns &null; if the
string was not a valid base64-encoded certificate.</para>
</refsect1>
<refsect1>
<title>Encoding Formats</title>
<para>The string produced by
<function>ne_ssl_cert_export</function> is the base64 encoding of
the DER representation of the certificate. The file written by
<function>ne_ssl_cert_write</function> uses the PEM format: this
is the base64 encoding of the DER representation with newlines
every 64 characters, and start and end marker lines.</para>
</refsect1>
</refentry>
@@ -0,0 +1,73 @@
<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>Examples</title>
<para>See <xref linkend="ne_ssl_cert_subject"/> for an example
use of <function>ne_ssl_readable_dname</function>.</para>
</refsect1>
<refsect1>
<title>See also</title>
<para><xref linkend="ne_ssl_cert_subject"/></para>
</refsect1>
</refentry>
@@ -0,0 +1,72 @@
<refentry id="refsslca">
<refmeta>
<refentrytitle>ne_ssl_trust_cert</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname id="ne_ssl_trust_cert">ne_ssl_trust_cert</refname>
<refname id="ne_ssl_trust_default_ca">ne_ssl_trust_default_ca</refname>
<refpurpose>functions to indicate that certificates are trusted</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;ne_session.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>void <function>ne_ssl_trust_cert</function></funcdef>
<paramdef>ne_session *<parameter>session</parameter></paramdef>
<paramdef>const ne_ssl_certificate *<parameter>cert</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>void <function>ne_ssl_trust_default_ca</function></funcdef>
<paramdef>ne_session *<parameter>session</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>To indicate that a given certificate is trusted by the
user, the certificate object can be passed to
<function>ne_ssl_trust_cert</function>. The certificate object is
duplicated internally and can subequently be destroyed.</para>
<para>The SSL library in use by &neon; may include a default
set of CA certificates; calling the
<function>ne_ssl_trust_default_ca</function> function will indicate
that these CAs are trusted by the user.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>Load the CA certificate stored in <filename>/path/to/cacert.pem</filename>:</para>
<programlisting>&egsess;
ne_ssl_certificate *cert = ne_ssl_cert_read("/path/to/cacert.pem");
if (cert) {
ne_ssl_trust_cert(sess, cert);
ne_ssl_cert_free(cert);
} else {
printf("Could not load CA cert: %s\n", ne_get_error(sess));
}</programlisting>
</refsect1>
<refsect1>
<title>See also</title>
<para><xref linkend="ne_ssl_cert_read"/>, <xref
linkend="ne_ssl_cert_import"/>, <xref
linkend="ne_ssl_cert_free"/></para> </refsect1>
</refentry>
@@ -0,0 +1,163 @@
<refentry id="refsslvfy"> <!-- -*- xml-mode -*- -->
<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_trust_cert"/>), 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><constant>NE_SSL_NOTYETVALID</constant></term>
<listitem>
<simpara>The certificate is not yet valid.</simpara>
</listitem>
</varlistentry>
<varlistentry><term><constant>NE_SSL_EXPIRED</constant></term>
<listitem>
<simpara>The certificate has expired.</simpara>
</listitem>
</varlistentry>
<varlistentry><term><constant>NE_SSL_IDMISMATCH</constant></term>
<listitem>
<simpara>The hostname used for the session does not match
the hostname to which the certificate was issued.</simpara>
</listitem>
</varlistentry>
<varlistentry><term><constant>NE_SSL_UNTRUSTED</constant></term>
<listitem>
<simpara>The Certificate Authority which signed the certificate
is not trusted.</simpara>
</listitem>
</varlistentry>
</variablelist>
<para>Note that if either of the
<constant>NE_SSL_IDMISMATCH</constant> or
<constant>NE_SSL_UNTRUSTED</constant> failures is given, the
connection may have been intercepted by a third party, and
must not be presumed to be <quote>secure</quote>.</para>
<para>The <parameter>cert</parameter> parameter passed to the
callback represents the certificate which was presented by the server.
If the server presented a chain of certificates, the chain can be
accessed using <xref linkend="ne_ssl_cert_signedby"/>. The
<parameter>cert</parameter> object given is not valid after 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>The following code implements an example verification
callback, using the <function>dump_cert</function> function
from <xref linkend="ne_ssl_cert_subject"/> to display
certification information. Notice that the hostname of the
server used for the session is passed as the
<parameter>userdata</parameter> parameter to the
callback.</para>
<programlisting>
static int
my_verify(void *userdata, int failures, const ne_ssl_certificate *cert)
{
const char *hostname = userdata;
dump_cert(cert);
puts("Certificate verification failed - the connection may have been "
"intercepted by a third party!");
if (failures &amp; NE_SSL_IDMISMATCH) {
const char *id = ne_ssl_cert_identity(cert);
if (id)
printf("Server certificate was issued to '%s' not '%s'.\n",
id, hostname);
else
printf("The certificate was not issued for '%s'\n", hostname);
}
if (failures &amp; NE_SSL_UNTRUSTED)
puts("The certificate is not signed by a trusted Certificate Authority.");
/* ... check for validity failures ... */
if (prompt_user())
return 1; /* fail verification */
else
return 0; /* trust the certificate anyway */
}
int
main(...)
{
ne_session *sess = ne_session_create("https", "some.host.name", 443);
ne_ssl_set_verify(sess, my_verify, "some.host.name");
...
}</programlisting>
</refsect1>
<refsect1>
<title>See also</title>
<para><xref linkend="ne_ssl_trust_cert"/>, <xref
linkend="ne_ssl_readable_dname"/>, <xref linkend="ne_ssl_cert_subject"/></para>
</refsect1>
</refentry>
@@ -0,0 +1,78 @@
<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<footnote><para>the field is named <quote>klass</quote> not
<quote>class</quote> so that the header can be used from a C++
program, in which <quote>class</quote> is a reserved
word)</para></footnote>, 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><simpara>Informational response.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><literal>2xx</literal></term>
<listitem><simpara>Success: the operation was successful</simpara></listitem>
</varlistentry>
<varlistentry>
<term><literal>3xx</literal></term>
<listitem><simpara>Redirection</simpara></listitem>
</varlistentry>
<varlistentry>
<term><literal>4xx</literal></term> <listitem><simpara>Client
error: the request made was incorrect in some
manner.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><literal>5xx</literal></term>
<listitem><simpara>Server error</simpara></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1> <title>See also</title> <para><xref
linkend="ne_get_status"/>.</para> </refsect1>
</refentry>
@@ -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>
@@ -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>
@@ -0,0 +1,56 @@
<refentry id="refxml">
<refmeta>
<refentrytitle>ne_xml_create</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname id="ne_xml_create">ne_xml_create</refname>
<refname id="ne_xml_destroy">ne_xml_destroy</refname>
<refpurpose>create and destroy an XML parser</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;ne_xml.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>ne_xml_parser *<function>ne_xml_create</function></funcdef>
<void/>
</funcprototype>
<funcprototype>
<funcdef>void <function>ne_xml_destroy</function></funcdef>
<paramdef>ne_xml_parser *<parameter>parser</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>The <function>ne_xml_create</function> function creates an
XML parser object, which can be used for parsing XML documents
using stacked SAX handlers.</para>
</refsect1>
<refsect1>
<title>Return value</title>
<para><function>ne_xml_create</function> returns a pointer to an
XML parser object, and never &null;</para> </refsect1>
<refsect1>
<title>See also</title>
<para>XXX</para>
</refsect1>
</refentry>