diff --git a/docs/man/nng_http_handler_alloc.3http.adoc b/docs/man/nng_http_handler_alloc.3http.adoc deleted file mode 100644 index 3eb9674a5..000000000 --- a/docs/man/nng_http_handler_alloc.3http.adoc +++ /dev/null @@ -1,185 +0,0 @@ -= nng_http_handler_alloc(3http) -// -// Copyright 2025 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; - -typedef void (*nng_http_hander_func)(nng_http_conn *conn, void *arg, nng_aio *aio); - -int nng_http_handler_alloc(nng_http_handler **hp, const char *path, - nng_http_handler_func cb); - -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 receives the connection on _conn_, and the data that it set -previously with `nng_http_handler_set_data` as the second argument. The -final argument is the _aio_, which must be "finished" to complete the operation. - -The function takes a pointer to an xref:nng_aio.5.adoc[`nng_aio`] structure. - -The handler should obtain `nng_http_res *` response from the -connection (`nng_http_conn_res`) and update it to reflect the final status. - -The handler may call `nng_http_conn_write_res` to send the response, or -it may simply let the framework do so on its behalf. The server will perform -this step if the callback has not already done so. - -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_start.3.adoc[`nng_aio_start()`] function. - -=== 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. - -=== 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_start.3.adoc[nng_aio_start(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_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)] diff --git a/docs/man/nng_http_handler_collect_body.3http.adoc b/docs/man/nng_http_handler_collect_body.3http.adoc deleted file mode 100644 index 5012680d4..000000000 --- a/docs/man/nng_http_handler_collect_body.3http.adoc +++ /dev/null @@ -1,69 +0,0 @@ -= nng_http_handler_collect_body(3http) -// -// Copyright 2018 Staysail Systems, Inc. -// Copyright 2018 Capitar IT Group BV -// -// 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_collect_body - set HTTP handler to collect request body - -== SYNOPSIS - -[source, c] ----- -#include -#include - -void nng_http_handler_collect_body(nng_http_handler *handler, bool want, size_t maxsz); ----- - -== DESCRIPTION - -The `nng_http_handler_collect_body()` function causes the _handler_ to -collect any request body that was submitted with the request, and attach -it to the `nng_http_req` before the handler is called. - -Subsequently the data can be retrieved by the handler from the request with the -xref:nng_http_req_get_data.3http.adoc[`nng_http_req_get_data()`] function. - -The collection is enabled if _want_ is true. -Furthermore, the data that the client may sent is limited by the -value of _maxsz_. -If the client attempts to send more data than _maxsz_, then the -request will be terminated with a 400 `Bad Request` status. - -TIP: Limiting the size of incoming request data can provide protection -against denial of service attacks, as a buffer of the client-supplied -size must be allocated to receive the data. - -In order to provide an unlimited size, use `(size_t)-1` for _maxsz_. -The value `0` for _maxsz_ can be used to prevent any data from being passed -by the client. - -The built-in handlers for files, directories, and static data limit the -_maxsz_ to zero by default. -Otherwise the default setting is to enable this capability with a default -value of _maxsz_ of 1 megabyte. - -NOTE: The handler looks for data indicated by the `Content-Length:` HTTP -header. -If this header is absent, the request is assumed not to contain any data. - -NOTE: This specifically does not support the `Chunked` transfer-encoding. -This is considered a bug, and is a deficiency for full HTTP/1.1 compliance. -However, few clients send data in this format, so in practice this should -create few limitations. - -== SEE ALSO - -[.text-left] -xref:nng_http_handler_alloc.3http.adoc[nng_http_handler_alloc(3http)], -xref:nng_http_server_add_handler.3http.adoc[nng_http_server_add_handler(3http)], -xref:nng_http_req_get_data.3http.adoc[nng_http_req_get_data(3http)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_http_handler_set_data.3http.adoc b/docs/man/nng_http_handler_set_data.3http.adoc deleted file mode 100644 index 91d2b1227..000000000 --- a/docs/man/nng_http_handler_set_data.3http.adoc +++ /dev/null @@ -1,42 +0,0 @@ -= nng_http_handler_set_data(3http) -// -// Copyright 2024 Staysail Systems, Inc. -// Copyright 2018 Capitar IT Group BV -// -// 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_set_data - set extra data for HTTP handler - -== SYNOPSIS - -[source, c] ----- -#include -#include - -void nng_http_handler_set_data(nng_http_handler *handler, void *data, - void (*dtor)(void *)); ----- - -== DESCRIPTION - -The `nng_http_handler_set_data()` function is used to set an additional -_data_ for the _handler_. - -Additionally, when the handler is deallocated, if _dtor_ is not `NULL`, -then it will be called with _data_ as its argument. -The intended use of -this function is deallocate any resources associated with _data_. - -== SEE ALSO - -[.text-left] -xref:nng_http_handler_alloc.3http.adoc[nng_http_handler_alloc(3http)], -xref:nng_http_server_add_handler.3http.adoc[nng_http_server_add_handler(3http)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_http_handler_set_host.3http.adoc b/docs/man/nng_http_handler_set_host.3http.adoc deleted file mode 100644 index e3d5e80af..000000000 --- a/docs/man/nng_http_handler_set_host.3http.adoc +++ /dev/null @@ -1,52 +0,0 @@ -= nng_http_handler_set_host(3http) -// -// Copyright 2024 Staysail Systems, Inc. -// Copyright 2018 Capitar IT Group BV -// -// 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_set_host - set host for HTTP handler - -== SYNOPSIS - -[source, c] ----- -#include -#include - -void nng_http_handler_set_host(nng_http_handler *handler, const char *host); ----- - -== DESCRIPTION - -The `nng_http_handler_set_host()` function is used to limit the scope of the -_handler_ so that it will only be called when the specified _host_ matches -the value of the `Host:` HTTP header. - -TIP: This can be used to create servers with multiple handlers for virtual -hosting. - -The value of the _host_ can include a colon and port, and should match -exactly the value of the `Host` header sent by the client. -(Canonicalization of the host name is performed though.) - -TIP: As the server framework does not support listening on multiple -ports, the port number can be elided. -The matching test only considers -the hostname or IP address, and ignores any trailing port number. - -NOTE: This should not be used with an IP address normally, as `Host:` header -is used with virtual hosts in HTTP/1.1, and not supported for HTTP/1.0. - -== SEE ALSO - -[.text-left] -xref:nng_http_handler_alloc.3http.adoc[nng_http_handler_alloc(3http)], -xref:nng_http_server_add_handler.3http.adoc[nng_http_server_add_handler(3http)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_http_handler_set_method.3http.adoc b/docs/man/nng_http_handler_set_method.3http.adoc deleted file mode 100644 index e216ab54a..000000000 --- a/docs/man/nng_http_handler_set_method.3http.adoc +++ /dev/null @@ -1,50 +0,0 @@ -= nng_http_handler_set_method(3http) -// -// Copyright 2018 Staysail Systems, Inc. -// Copyright 2018 Capitar IT Group BV -// -// 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_set_method - set HTTP handler method - -== SYNOPSIS - -[source, c] ----- -#include -#include - -void nng_http_handler_set_method(nng_http_handler *handler, const char *method); ----- - -== DESCRIPTION - -The `nng_http_handler_set_method()` function sets the _method_ that the -_handler_ will be called for, such as "GET" or "POST". -(By default the "GET" method is handled.) -If _method_ is `NULL`, then the request method -is not examined, and the handler will be executed regardless of the -method. - -NOTE: The server will automatically call "GET" handlers if the client -sends a "HEAD" request, and will suppress HTTP body data in the responses -sent for such requests. - -NOTE: If _method_ is longer than 32-bytes, it may be truncated silently. - -The handler may always examine the actual method used using the -xref:nng_http_req_get_method.3http.adoc[`nng_http_req_get_method()`] function. - -== SEE ALSO - -[.text-left] -xref:nng_http_handler_alloc.3http.adoc[nng_http_handler_alloc(3http)], -xref:nng_http_server_add_handler.3http.adoc[nng_http_server_add_handler(3http)], -xref:nng_http_req_get_method.3http.adoc[nng_http_req_get_method(3http)], -xref:nng.7.adoc[nng(7)] diff --git a/docs/man/nng_http_handler_set_tree.3http.adoc b/docs/man/nng_http_handler_set_tree.3http.adoc deleted file mode 100644 index 77b1cc598..000000000 --- a/docs/man/nng_http_handler_set_tree.3http.adoc +++ /dev/null @@ -1,45 +0,0 @@ -= nng_http_handler_set_tree(3http) - -// Copyright 2025 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_set_tree - set HTTP handler to match trees - -== SYNOPSIS - -[source,c] ----- -#include -#include - -void nng_http_handler_set_tree(nng_http_handler *handler); ----- - -== DESCRIPTION - -The `nng_http_handler_set_tree()` function causes the _handler_ to be matched if the request URI sent -by the client is a logical child of the path for _handler_, and no more specific -_handler_ has been registered. - -This is useful in cases when the handler would like to examine the entire path -and possibly behave differently; for example a REST API that uses the rest of -the path to pass additional parameters. - -TIP: This function is useful when constructing API handlers where a single -service address (path) supports dynamically generated children. -It can also provide a logical fallback instead of relying on a 404 error code. - -== SEE ALSO - -[.text-left] -xref:nng_http_handler_alloc.3http.adoc[nng_http_handler_alloc(3http)], -xref:nng_http_server_add_handler.3http.adoc[nng_http_server_add_handler(3http)], -xref:nng_http_get_method.3http.adoc[nng_http_get_method(3http)] diff --git a/docs/ref/api/http.md b/docs/ref/api/http.md index dfa9d07df..8cb1945e4 100644 --- a/docs/ref/api/http.md +++ b/docs/ref/api/http.md @@ -431,7 +431,7 @@ nng_aio *aio; nng_url *url; nng_http_client *client; nng_http *conn; -int rv; +nng_err rv; // Error checks elided for clarity. nng_url_parse(&url, "http://www.google.com"); @@ -458,8 +458,6 @@ if ((rv = nng_aio_result(aio)) != 0) { ### Preparing a Transaction -### Request Body - ### Sending the Request ```c @@ -481,7 +479,7 @@ may be obtained via [`nng_aio_result`]. > Consider using the [`nng_http_transact`] function, > which provides a simpler interface for performing a complete HTTP client transaction. -## Obtaining the Response +### Obtaining the Response ```c void nng_http_read_response(nng_http *conn, nng_aio *aio); @@ -545,7 +543,243 @@ may be obtained via [`nng_aio_result()`]. ### Handlers -### Sending the Response +```c +typedef struct nng_http_handler nng_http_handler; +``` + +An {{i:`nng_http_handler`}} encapsulates a function used used to handle +incoming requests on an HTTP server, routed based on method and URI, +and the parameters used with that function. + +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, but doing so will require setting the handler to match a parent path in the tree using +[`nng_http_handler_set_tree`]. + +> [!TIP] +> The NNG HTTP framework is optimized for URLs shorter than 200 characters. + +Additionally each handler has a method it is registered to handle +(the default is "GET" andc can be changed with [`nng_http_handler_set_method`]), and +optionally a "Host" header it can be matched against (see [`nng_http_handler_set_host`]). + +In some cases, a handler may reference a logical tree rather (directory) +rather than just a single element. +(See [`nng_http_handler_set_tree`]). + +### Implementing a Handler + +```c +typedef void (*nng_http_hander_func)(nng_http_conn *conn, void *arg, nng_aio *aio); + +nng_err nng_http_handler_alloc(nng_http_handler **hp, const char *path, nng_http_handler_func cb); +``` + +The {{i:`nng_http_handler_alloc`}} function allocates a generic 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_. + +The handler function is specified by _cb_. +This function uses the asynchronous I/O framework. + +The function receives the connection on _conn_, and an optional data pointer that was set +previously with [`nng_http_handler_set_data`] as the second argument. The +final argument is the [`nng_aio`] _aio_, which must be "finished" to complete the operation. + +The handler may call [`nng_http_write_response`] to send the response, or +it may simply let the framework do so on its behalf. The server will perform +this step if the callback has not already done so. + +Response headers may be set using [`nng_http_set_header`], and request headers +may be accessed by using [`nng_http_get_header`]. + +Likewise the request body may be accessed, using [`nng_http_get_body`], and +the response body may be set using either [`nng_http_set_body`] or [`nng_http_copy_body`]. + +> [!NOTE] +> The request body is only collected for the handler if the +> [`nng_http_handler_collect_body`] function has been called for the handler. + +The HTTP status should be set for the transaction using [`nng_http_set_status`]. + +Finally, the handler should finish the operation by calling the [`nng_aio_finish`] function +after having set the status to [`NNG_OK`]. +If any other status is set on the _aio_, 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 [`nng_aio_start`]. + +### Serving Directories and Files + +```c +nng_err nng_http_handler_alloc_directory(nng_http_handler **hp, const char *path, const char *dirname); +nng_err nng_http_handler_alloc_file(nng_http_handler **hp, const char *path, const char *filename); +``` + +The {{i:`nng_http_handler_alloc_directory`}} and {{i:`nng_http_handler_alloc_file`}} +create handlers pre-configured to act as static content servers for either a full +directory at _dirname_, or the single file at _filename_. These support the "GET" and "HEAD" +methods, and the directory variant will dynamically generate `index.html` content based on +the directory contents. These will also set the "Content-Type" if the file extension +matches one of the built-in values already known. If the no suitable MIME type can be +determined, the content type is set to "application/octet-stream". + +### Static Handler + +```c +nng_err nng_http_handler_alloc_static(nng_http_handler **hp, const char *path, + const void *data, size_t size, const char *content_type); +``` + +The {{i:`nng_http_handler_alloc_static`}} function creates a handler that +serves the content located in _data_ (consisting of _size_ bytes) at the URI _path_. +The _content_type_ determines the "Content-Type" header. If `NULL` is specified +then a value of `application/octet-stream` is assumed. + +### Redirect Handler + +```c +nng_err nng_http_handler_alloc_redirect(nng_http_handler **hp, const char *path, + nng_http_status status, const char *location); +``` + +The {{i:`nng_http_handler_alloc_redirect`}} function creates a handler with +a function that simply directions from the URI at _path_ to the given _location_. + +The HTTP reply it creates will be with [status code][`nng_http_status`] _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 [`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 [`NNG_HTTP_STATUS_STATUS_MOVED_PERMANENTLY`] (301) +> and temporary redirections should use [`NNG_HTTP_STATUS_TEMPORARY_REDIRECT`] (307). +> In REST APIs, using a redirection to supply the new location of an object +> created with `POST` should use [`NNG_HTTP_STATUS_SEE_OTHER`] (303). + +### Collecting Request Body + +```c +void nng_http_handler_collect_body(nng_http_handler *handler, bool want, size_t maxsz); +``` + +The {{i:`nng_http_handler_collect_body`}} function requests that HTTP server +framework collect any reuqest body for the request and attach it to the +connection before calling the callback for the _handler_. + +Subsequently the data can be retrieved by the handler from the request with the +[`nng_http_get_body`] function. + +The collection is enabled if _want_ is true. +Furthermore, the data that the client may sent is limited by the +value of _maxsz_. +If the client attempts to send more data than _maxsz_, then the +request will be terminated with [`NNG_HTTP_STATUS_CONTENT_TOO_LARGE`] (413). + +> [!TIP] +> Limiting the size of incoming request data can provide protection +> against denial of service attacks, as a buffer of the client-supplied +> size must be allocated to receive the data. + +> In order to provide an unlimited size, use `(size_t)-1` for _maxsz_. +> The value `0` for _maxsz_ can be used to prevent any data from being passed +> by the client. + +> The built-in handlers for files, directories, and static data limit the +> _maxsz_ to zero by default. +> Otherwise the default setting is to enable this capability with a default +> value of _maxsz_ of 1 megabyte. + +> [!NOTE] +> NNG specifically does not support the `Chunked` transfer-encoding. +> This is considered a bug, and is a deficiency for full HTTP/1.1 compliance. +> However, few clients send data in this format, so in practice this should +> create few limitations. + +### Setting Callback Argument + +```c +void nng_http_handler_set_data(nng_http_handler *handler, void *data, + void (*dtor)(void *)); +``` + +The {{i:`nng_http_handler_set_data`}} function is used to set the +_data_ argument that will be passed to the callback. + +Additionally, when the handler is deallocated, if _dtor_ is not `NULL`, +then it will be called with _data_ as its argument. +The intended use of this function is deallocate any resources associated with _data_. + +### Setting the Method + +```c +void nng_http_handler_set_method(nng_http_handler *handler, const char *method); +``` + +The {{i:`nng_http_handler_set_method`}} function sets the _method_ that the +_handler_ will be called for, such as "GET" or "POST". +(By default the "GET" method is handled.) + +If _method_ is `NULL` the handler will be executed for all methods. +The handler may determine the actual method used with the [`nng_http_get_method`] function. + +The server will automatically call "GET" handlers if the client +sends a "HEAD" request, and will suppress HTTP body data in the responses +sent for such requests. + +> [!NOTE] +> If _method_ is longer than 32-bytes, it may be truncated silently. + +### Filtering by Host + +```c +void nng_http_handler_set_host(nng_http_handler *handler, const char *host); +``` + +The {{i:`nng_http_handler_set_host`}} function is used to limit the scope of the +_handler_ so that it will only be called when the specified _host_ matches +the value of the `Host:` HTTP header. + +This can be used to create servers with different content for different virtual hosts. + +The value of the _host_ can include a colon and port, and should match +exactly the value of the `Host` header sent by the client. +(Canonicalization of the host name is performed.) + +> [!NOTE] +> The port number may be ignored; at present the HTTP server framework +> does not support a single server listening on different ports concurrently. + +### Handling an Entire Tree + +```c +void nng_http_handler_set_tree(nng_http_handler *handler); +``` + +The {{i:`nng_http_handler_set_tree`}} function causes the _handler_ to be matched if the request URI sent +by the client is a logical child of the path for _handler_, and no more specific +_handler_ has been registered. + +This is useful in cases when the handler would like to examine the entire path +and possibly behave differently; for example a REST API that uses the rest of +the path to pass additional parameters. + +> [!TIP] +> This function is useful when constructing API handlers where a single +> service address (path) supports dynamically generated children. +> It can also provide a logical fallback instead of relying on a 404 error code. + +### Sending the Response Explicitly ```c void nng_http_write_response(nng_http *conn, nng_aio *aio); diff --git a/include/nng/http.h b/include/nng/http.h index a2198cce0..1ff541ac7 100644 --- a/include/nng/http.h +++ b/include/nng/http.h @@ -236,6 +236,8 @@ NNG_DECL nng_err nng_http_handler_alloc( // nng_http_handler_free frees the handler. This actually just drops a // reference count on the handler, as it may be in use by an existing // server. The server will also call this when it is destroyed. +// This is not formally documented as there is no practical reason that +// user code should need to free a handler explicitly. NNG_DECL void nng_http_handler_free(nng_http_handler *); // nng_http_handler_alloc_file creates a "file" based handler, that