    <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>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 otherwise.</para>

      </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>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"/>, <xref linkend="ne_set_request_flag"/>.</para>

      </refsect1>

    </refentry>
