= nng_http_handler_alloc(3http) // // Copyright 2018 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // Copyright 2020 Dirac Research // // 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 #include 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)]