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
|
= 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.
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)]
|