From 3db54322b4b6024b34878a277789ef082872189b Mon Sep 17 00:00:00 2001 From: gdamore Date: Thu, 16 Jan 2025 02:43:50 +0000 Subject: deploy: c4ca4834e39e48676ea50df1fc6239c7dc2a56ff --- ref/api/http.html | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 218 insertions(+), 5 deletions(-) (limited to 'ref/api/http.html') diff --git a/ref/api/http.html b/ref/api/http.html index 03ab3ef6..4b2713a6 100644 --- a/ref/api/http.html +++ b/ref/api/http.html @@ -586,7 +586,7 @@ retried from the aio using < 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"); @@ -611,7 +611,6 @@ if ((rv = nng_aio_result(aio)) != 0) { }

Preparing a Transaction

-

Request Body

Sending the Request

void nng_http_write_request(nng_http *conn, nng_aio *aio);
 
@@ -632,7 +631,7 @@ may be obtained via nng_aio_re

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

void nng_http_read_response(nng_http *conn, nng_aio *aio);
 

The nng_http_read_response function starts an asynchronous read from the @@ -695,12 +694,226 @@ may be obtained via [nng_aio_result()].

Response Body

Server API

Handlers

-

Sending the Response

+
typedef struct nng_http_handler nng_http_handler;
+
+

An 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

+
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 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

+
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 nng_http_handler_alloc_directory and 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

+
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 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

+
nng_err nng_http_handler_alloc_redirect(nng_http_handler **hp, const char *path,
+        nng_http_status status, const char *location);
+
+

The 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

+
void nng_http_handler_collect_body(nng_http_handler *handler, bool want, size_t maxsz);
+
+

The 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

+
void nng_http_handler_set_data(nng_http_handler *handler, void *data,
+    void (*dtor)(void *));
+
+

The 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

+
void nng_http_handler_set_method(nng_http_handler *handler, const char *method);
+
+

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 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

+
void nng_http_handler_set_host(nng_http_handler *handler, const char *host);
+
+

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.

+

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

+
void nng_http_handler_set_tree(nng_http_handler *handler);
+
+

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.

+
+

Sending the Response Explicitly

void nng_http_write_response(nng_http *conn, nng_aio *aio);
 

Normally the server will send any attached response, but there are circumstances where a response must be sent manually, such as when hijacking a connection.

-

In such a case, nng_http_write_response can be called, which will send the response and any attached data, asynchronously +

In such a case, nng_http_write_response can be called, which will send the response and any attached data, asynchronously using the nng_aio aio.

By default, for HTTP/1.1 connections, the connection is kept open, and will be reused to receive new requests. For HTTP/1.0, or if the client has requested -- cgit v1.2.3-70-g09d2