= nng_http_handler_alloc(3http)
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2020 Dirac Research <robert.bielik@dirac.com>
//
// This document is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
// file was obtained (LICENSE.txt).  A copy of the license may also be
// found online at https://opensource.org/licenses/MIT.
//

== NAME

nng_http_handler_alloc - allocate HTTP server handler

== SYNOPSIS

[source, c]
----
#include <nng/nng.h>
#include <nng/supplemental/http/http.h>

typedef struct nng_http_handler nng_http_handler;

int nng_http_handler_alloc(nng_http_handler **hp, const char *path,
    void (*func)(nng_aio *);

int nng_http_handler_alloc_directory(nng_http_handler **hp, const char *path,
    const char *dirname);

int nng_http_handler_alloc_file(nng_http_handler **hp, const char *path,
    const char *filename);

int nng_http_handler_alloc_redirect(nng_http_handler **hp, const char *path,
    uint16_t status, const char *location);

int nng_http_handler_alloc_static(nng_http_handler **hp, const char *path,
    const void *data, size_t size, const char *content_type);
----

== DESCRIPTION

The `nng_http_handler_alloc()` family of functions allocate a handler
which will be used to process requests coming into an HTTP server.
On success, a pointer to the handler is stored at the located pointed to
by _hp_.

Every handler has a Request-URI to which it refers, which is determined
by the _path_ argument.
Only the path component of the Request URI is
considered when determining whether the handler should be called.

This implementation limits the _path_ length to 1024 bytes, including the
zero termination byte.  This does not prevent requests with much longer
URIs from being supported, doing so will require setting the handler
to matching a parent path in the tree using
xref:nng_http_handler_set_tree.3http.adoc[`nng_http_handler_set_tree`()].

Additionally each handler has a method it is registered to handle
(the default is `GET`, see
xref:nng_http_handler_set_method.3http.adoc[`nng_http_handler_set_method()`]), and
optionally a 'Host' header it can be matched against (see
xref:nng_http_handler_set_host.3http.adoc[`nng_http_handler_set_host()`]).

In some cases, a handler may reference a logical tree rather (directory)
rather than just a single element.
(See xref:nng_http_handler_set_tree.3http.adoc[`nng_http_handler_set_tree()`]).

=== Custom Handler

The generic (first) form of this creates a handler that uses a user-supplied
function to process HTTP requests.
This function uses the asynchronous I/O framework.
The function takes a pointer to an xref:nng_aio.5.adoc[`nng_aio`] structure.

The _aio_ will be passed with the following input values (retrieved with
xref:nng_aio_get_input.3.adoc[`nng_aio_get_input()`]):

   0: `nng_http_req *` __request__:: The client's HTTP request.
   1: `nng_http_handler *` __handler__:: Pointer to the handler object.
   2: `nng_http_conn *` __conn__:: The underlying HTTP connection.

The handler should create an `nng_http_res *` response (such as via
xref:nng_http_res_alloc.3http.adoc[`nng_http_res_alloc()`] or
xref:nng_http_res_alloc_error.3http.adoc[`nng_http_res_alloc_error()`]) and store that
in as the first output (index 0) with
xref:nng_aio_set_output.3.adoc[`nng_aio_set_output()`].

Alternatively, the handler may send the HTTP response (and any associated
body data) itself using the connection.
In that case the output at index 0 of the _aio_ should be NULL.

Finally, using the xref:nng_aio_finish.3.adoc[`nng_aio_finish()`] function, the
_aio_ should be completed successfully.
If any non-zero status is returned back to the caller instead,
then a generic 500 response will be created and
sent, if possible, and the connection will be closed.

The _aio_ may be scheduled for deferred completion using the
xref:nng_aio_defer.3.adoc[`nng_aio_defer()`] function.

NOTE: The callback function should *NOT* call
xref:nng_aio_begin.3.adoc[`nng_aio_begin()`],
as that will already have been done by the server framework.

=== Directory Handler

The second member of this family, `nng_http_handler_alloc_directory()`, creates
a handler configured to serve a directory tree.
The _uri_ is taken as the root, and files are served from the directory
tree rooted at _path_.

When the client Request-URI resolves to a directory in the file system,
the handler looks first for a file named `index.html` or `index.htm`.
If one is found, then that file is returned back to the client.
If no such index file exists, then an `NNG_HTTP_STATUS_NOT_FOUND` (404) error is
sent back to the client.

The `Content-Type` will be set automatically based upon the extension
of the requested file name. If a content type cannot be determined from
the extension, then `application/octet-stream` is used.

The directory handler is created as a tree handler initially in exclusive mode (see
xref:nng_http_handler_set_tree.3http.adoc[nng_http_handler_set_tree_exclusive]).
This can be changed by calling
xref:nng_http_handler_set_tree.3http.adoc[nng_http_handler_set_tree(3http)]
after creating the directory handler.

=== File Handler

The third member of this family, `nng_http_handler_alloc_file()`, creates
a handler to serve up a single file; it does not traverse directories
or search for `index.html` or `index.htm` files.

The `Content-Type` will be set automatically based upon the extension
of the requested file name.
If a content type cannot be determined from
the extension, then `application/octet-stream` is used.

=== Redirect Handler

The fourth member is used to arrange for a server redirect from one
URL to another.
The reply will be with status code __status__, which should be a 3XX
code such as 301, and a `Location:` header will contain the URL
referenced by __location__, with any residual suffix from the request
URI appended.

TIP: Use xref:nng_http_handler_set_tree.3http.adoc[`nng_http_handler_set_tree()`]
to redirect an entire tree.
For example, it is possible to redirect an entire HTTP site to another
HTTPS site by specifying `/` as the path and then using the base
of the new site, such as `https://newsite.example.com` as the
new location.

TIP: Be sure to use the appropriate value for __status__.
Permanent redirection should use 301 and temporary redirections should use 307.
In REST APIs, using a redirection to supply the new location of an object
created with `POST` should use 303.

=== Static Handler

The fifth member of this family, `nng_http_handler_alloc_static()`, creates
a handler to serve up fixed content located in program data.
The client is
sent the _data_, with `Content-Length` of _size_ bytes, and `Content-Type` of
__content_type__.

== RETURN VALUES

These functions return 0 on success, and non-zero otherwise.

== ERRORS

[horizontal]
`NNG_EINVAL`:: An invalid _path_ was specified.
`NNG_ENOMEM`:: Insufficient free memory exists to allocate a message.
`NNG_ENOTSUP`:: No support for HTTP in the library.

== SEE ALSO

[.text-left]
xref:nng_aio_defer.3.adoc[nng_aio_defer(3)],
xref:nng_aio_finish.3.adoc[nng_aio_finish(3)],
xref:nng_aio_get_input.3.adoc[nng_aio_get_input(3)],
xref:nng_aio_set_output.3.adoc[nng_aio_set_output(3)],
xref:nng_http_handler_collect_body.3http.adoc[nng_http_handler_collect_body(3http)],
xref:nng_http_handler_free.3http.adoc[nng_http_handler_free(3http)],
xref:nng_http_handler_set_host.3http.adoc[nng_http_handler_set_host(3http)],
xref:nng_http_handler_set_method.3http.adoc[nng_http_handler_set_method(3http)],
xref:nng_http_handler_set_tree.3http.adoc[nng_http_handler_set_tree(3http)],
xref:nng_http_handler_set_tree.3http.adoc[nng_http_handler_set_tree_exclusive(3http)],
xref:nng_http_res_alloc.3http.adoc[nng_http_res_alloc(3http)],
xref:nng_http_res_alloc_error.3http.adoc[nng_http_res_alloc_error(3http)],
xref:nng_http_server_add_handler.3http.adoc[nng_http_server_add_handler(3http)],
xref:nng_strerror.3.adoc[nng_strerror(3)],
xref:nng_aio.5.adoc[nng_aio(5)],
xref:nng.7.adoc[nng(7)]
