1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
<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 <ne_request.h></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>target</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>The <type>ne_request</type> object represents an HTTP
request and the associated response. The
<function>ne_request_create</function> function creates a new
request object for the given <parameter>session</parameter>.
The target resource for the request is identified by the
<parameter>target</parameter>, parameter, and the method to be
performed on that resource via the
<parameter>method</parameter> parameter.</para>
<para>The <parameter>target</parameter> string used must conform to
the <literal>request-target</literal> definition given in <ulink
url="https://www.rfc-editor.org/rfc/rfc9112">RFC 9112</ulink>. Usually
this will take the <literal>abolute-path</literal> form, which
optionally includes a query string.</para>
<para>To <emphasis>dispatch</emphasis> 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>. <emphasis>Dispatching</emphasis> a request may require
multiple iterations of a request being sent and response received, for example
if authentication is used (see <xref linkend="ne_set_server_auth"/>), or if a persistent
connection times out; this is handled internally by <function>ne_request_dispatch</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>, <function>ne_set_request_body_fd</function>, 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>
<para>Request methods are assumed to be <ulink
url="https://www.rfc-editor.org/rfc/rfc9110.html#name-idempotent-methods">idempotent</ulink>
by default. For a request using a non-idempotent method such
as <literal>POST</literal>, the
<literal>NE_REQFLAG_IDEMPOTENT</literal> flag must be
disabled using <xref linkend="ne_set_request_flag"/>.</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 code otherwise, as described in the
following section.</para>
</refsect1>
<refsect1 id="error-codes" xreflabel="NE_* error code">
<title>Error codes</title>
<para>Error codes have a non-zero value, and correspond to an
<literal>NE_*</literal> macro definition, as listed below.
Future versions of &neon; may introduce additional error code
definitions. Functions which return an error code and have an
associated session object set the session error string (see
<xref linkend="ne_get_error"/>) unless documented
otherwise.</para>
<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>
<varlistentry><term><errorcode>NE_REDIRECT</errorcode></term>
<listitem>
<simpara>A valid redirect was retuerned. <emphasis>Note:</emphasis> Only returned if redirect handling is registered for the session using <xref linkend="ne_redirect_register"/>.</simpara>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Notes</title>
<para>The <parameter>path</parameter>,
<parameter>method</parameter> and
<parameter>target</parameter> parameters of
<function>ne_request_create</function> are used directly in
request data without validation, so must not be taken from
untrusted sources. For example, allowing insertion of
unescaped CR, LF or other control characters in these
parameters may result in unexpected or insecure behaviour.</para>
<para>&neon; does not impose any length restrictions on
request input data.</para>
</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"/>, <xref linkend="ne_set_request_flag"/>, <xref linkend="ne_redirect_register"/>.</para>
</refsect1>
</refentry>
|