aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2025-01-17 05:49:14 -0800
committerGarrett D'Amore <garrett@damore.org>2025-01-17 05:50:04 -0800
commit6d74a90b72c80edbd58d8b2b29105e749bdfc28e (patch)
treeea2a2fcabc3ef81ac0859ecef1ab9c7f4ab88f2b
parent98b0d432dfeaa811cdfe20adb60ea899d61947b9 (diff)
downloadnng-6d74a90b72c80edbd58d8b2b29105e749bdfc28e.tar.gz
nng-6d74a90b72c80edbd58d8b2b29105e749bdfc28e.tar.bz2
nng-6d74a90b72c80edbd58d8b2b29105e749bdfc28e.zip
http: handler API clean ups
-rw-r--r--docs/man/nng_http_handler_free.3http.adoc47
-rw-r--r--docs/ref/api/http.md157
-rw-r--r--docs/ref/xref.md5
-rw-r--r--include/nng/http.h13
-rw-r--r--src/supplemental/http/http_api.h72
-rw-r--r--src/supplemental/http/http_public.c22
-rw-r--r--src/supplemental/http/http_server.c127
-rw-r--r--src/supplemental/http/http_server_test.c48
-rw-r--r--src/supplemental/websocket/websocket.c18
9 files changed, 234 insertions, 275 deletions
diff --git a/docs/man/nng_http_handler_free.3http.adoc b/docs/man/nng_http_handler_free.3http.adoc
deleted file mode 100644
index 0e1a5b1c..00000000
--- a/docs/man/nng_http_handler_free.3http.adoc
+++ /dev/null
@@ -1,47 +0,0 @@
-= nng_http_handler_free(3http)
-//
-// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
-// Copyright 2018 Capitar IT Group BV <info@capitar.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_free - free HTTP server handler
-
-== SYNOPSIS
-
-[source, c]
-----
-#include <nng/nng.h>
-#include <nng/http.h>
-
-void nng_http_handler_free(nng_http_handler *h);
-----
-
-== DESCRIPTION
-
-The `nng_http_handler_free()` function frees an allocated HTTP server handler.
-
-IMPORTANT: It is an error to free a handler that is registered with a server.
-Any handlers that are registered with servers are automatically freed
-when the server itself is deallocated.
-
-== RETURN VALUES
-
-None.
-
-== ERRORS
-
-None.
-
-== 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/ref/api/http.md b/docs/ref/api/http.md
index 8cb1945e..bec22f1b 100644
--- a/docs/ref/api/http.md
+++ b/docs/ref/api/http.md
@@ -121,68 +121,68 @@ then a built in reason based on the _status_ will be used instead.
Status codes are defined by the IETF. Here are defininitions that NNG provides for convenience:
-| Name | Code | Reason Text | Notes |
-| ------------------------------------------------------------------------------------------------ | ---- | ------------------------------- | ----------------------------------------------------- |
-| `NNG_HTTP_STATUS_CONTINUE`<a name="#NNG_HTTP_STATUS_CONTINUE"></a> | 100 | Continue | Partial transfer, client may send body. |
-| `NNG_HTTP_STATUS_SWITCHING`<a name="#NNG_HTTP_STATUS_SWITCHING"></a> | 101 | Switching Protocols | Used when upgrading or hijacking a connection. |
-| `NNG_HTTP_STATUS_PROCESSING`<a name="#NNG_HTTP_STATUS_PROCESSING"></a> | 102 | Processing |
-| `NNG_HTTP_STATUS_OK`<a name="#NNG_HTTP_STATUS_OK"></a> | 200 | OK | Successful result. |
-| `NNG_HTTP_STATUS_CREATED`<a name="#NNG_HTTP_STATUS_CREATED"></a> | 201 | Created | Resource created successfully. |
-| `NNG_HTTP_STATUS_ACCEPTED`<a name="#NNG_HTTP_STATUS_ACCEPTED"></a> | 202 | Created | Request accepted for future processing. |
-| `NNG_HTTP_STATUS_NOT_AUTHORITATIVE`<a name="#NNG_HTTP_STATUS_NOT_AUTHORITATIVE"></a> | 203 | Not Authoritative | Request successful, but modified by proxy. |
-| `NNG_HTTP_STATUS_NO_CONTENT`<a name="#NNG_HTTP_STATUS_NO_CONTENT"></a> | 204 | No Content | Request successful, no content returned. |
-| `NNG_HTTP_STATUS_RESET_CONTENT`<a name="#NNG_HTTP_STATUS_NO_CONTENT"></a> | 205 | Reset Content | Request successful, client should reload content. |
-| `NNG_HTTP_STATUS_PARTIAL_CONTENT`<a name="#NNG_HTTP_STATUS_NO_CONTENT"></a> | 206 | Partial Content | Response to a range request. |
-| `NNG_HTTP_STATUS_MULTI_STATUS`<a name="#NNG_HTTP_STATUS_MULTI_STATUS"></a> | 207 | Multi-Status | Used with WebDAV. |
-| `NNG_HTTP_STATUS_ALREADY_REPORTED`<a name="#NNG_HTTP_STATUS_ALREADY_REPORTED"></a> | 208 | Already Reported | Used with WebDAV. |
-| `NNG_HTTP_STATUS_IM_USED`<a name="#NNG_HTTP_STATUS_IM_USED"></a> | 226 | IM Used | Used with delta encodings, rarely supported. |
-| `NNG_HTTP_STATUS_MULTIPLE_CHOICES`<a name="#NNG_HTTP_STATUS_MULTIPLE_CHOICES"></a> | 300 | Multiple Choices | Multiple responses possible, client should choose. |
-| `NNG_HTTP_STATUS_MOVED_PERMANENTLY`<a name="#NNG_HTTP_STATUS_MOVED_PERMANENTLY"></a> | 301 | Moved Permanently | Permanent redirection, may be saved by client. |
-| `NNG_HTTP_STATUS_FOUND`<a name="#NNG_HTTP_STATUS_FOUND"></a> | 302 | Found | Temporary redirection, client may switch to GET. |
-| `NNG_HTTP_STATUS_SEE_OTHER`<a name="#NNG_HTTP_STATUS_SEE_OTHER"></a> | 303 | See Other | Redirect, perhaps after a success POST or PUT. |
-| `NNG_HTTP_STATUS_NOT_MODIFIED`<a name="#NNG_HTTP_STATUS_NOT_MODIFIED"></a> | 304 | Not Modified | Resource not modified, client may use cached version. |
-| `NNG_HTTP_STATUS_USE_PROXY`<a name="#NNG_HTTP_STATUS_USE_PROXY"></a> | 305 | Use Proxy |
-| `NNG_HTTP_STATUS_TEMPORARY_REDIRECT`<a name="#NNG_HTTP_STATUS_TEMPORARY_REDIRECT"></a> | 307 | Temporary Redirect | Temporary redirect, preserves method. |
-| `NNG_HTTP_STATUS_PERMANENT_REDIRECT`<a name="#NNG_HTTP_STATUS_PERMANENT_REDIRECT"></a> | 308 | Permanent Redirect | Permanent redirect. |
-| `NNG_HTTP_STATUS_BAD_REQUEST`<a name="#NNG_HTTP_STATUS_BAD_REQUEST"></a> | 400 | Bad Request | Generic problem with the request. |
-| `NNG_HTTP_STATUS_UNAUTHORIZED`<a name="#NNG_HTTP_STATUS_UNAUTHORIZED"></a> | 401 | Unauthorized | Indicates a problem with authentication. |
-| `NNG_HTTP_STATUS_PAYMENT_REQUIRED`<a name="#NNG_HTTP_STATUS_PAYMENT_REQUIRED"></a> | 402 | Payment Required |
-| `NNG_HTTP_STATUS_FORBIDDEN`<a name="#NNG_HTTP_STATUS_FORBIDDEN"></a> | 403 | Forbidden | No permission to access resource. |
-| `NNG_HTTP_STATUS_NOT_FOUND`<a name="#NNG_HTTP_STATUS_NOT_FOUND"></a> | 404 | Not Found | Resource does not exist. |
-| `NNG_HTTP_STATUS_METHOD_NOT_ALLOWED`<a name="#NNG_HTTP_STATUS_METHOD_NOT_ALLOWED"></a> | 405 | Method Not Allowed | Resource does not support the method. |
-| `NNG_HTTP_STATUS_METHOD_NOT_ACCEPTABLE`<a name="#NNG_HTTP_STATUS_METHOD_NOT_ACCEPTABLE"></a> | 406 | Not Acceptable | Could not satisfy accept requirements. |
-| `NNG_HTTP_STATUS_PROXY_AUTH_REQUIRED`<a name="#NNG_HTTP_STATUS_PROXY_AUTH_REQUIRED"></a> | 407 | Proxy Authentication Required | Proxy requires authentication. |
-| `NNG_HTTP_STATUS_REQUEST_TIMEOUT`<a name="#NNG_HTTP_STATUS_REQUEST_TIMEOUT"></a> | 408 | Request Timeout | Timed out waiting for request. |
-| `NNG_HTTP_STATUS_CONFLICT`<a name="#NNG_HTTP_STATUS_CONFLICT"></a> | 409 | Conflict | Conflicting request. |
-| `NNG_HTTP_STATUS_GONE`<a name="#NNG_HTTP_STATUS_GONE"></a> | 410 | Gone | Resource no longer exists. |
-| `NNG_HTTP_STATUS_LENGTH_REQUIRED`<a name="#NNG_HTTP_STATUS_LENGTH_REQUIRED"></a> | 411 | Length Required | Missing Content-Length. |
-| `NNG_HTTP_STATUS_PRECONDITION_FAILED`<a name="#NNG_HTTP_STATUS_PRECONDITION_FAILED"></a> | 412 | Precondition Failed | |
-| `NNG_HTTP_STATUS_CONTENT_TOO_LARGE`<a name="#NNG_HTTP_STATUS_PAYLOAD_TOO_LARGE"></a> | 413 | Content Too Large | |
-| `NNG_HTTP_STATUS_URI_TOO_LONG`<a name="#NNG_HTTP_STATUS_URI_TOO_LONG"></a> | 414 | URI Too Long | |
-| `NNG_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE`<a name="#NNG_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE"></a> | 415 | Unsupported Media Type |
-| `NNG_HTTP_STATUS_RANGE_NOT_SATISFIABLE`<a name="#NNG_HTTP_STATUS_RANGE_NOT_SATISFIABLE"></a> | 416 | Range Not Satisfiable |
-| `NNG_HTTP_STATUS_EXPECTATION_FAILED`<a name="#NNG_HTTP_STATUS_EXPECTATION_FAILED"></a> | 417 | Expectation Failed |
-| `NNG_HTTP_STATUS_TEAPOT`<a name="#NNG_HTTP_STATUS_TEAPOT"></a> | 418 | I Am A Teapot | RFC 2324. |
-| `NNG_HTTP_STATUS_UNPROCESSABLE_ENTITY`<a name="#NNG_HTTP_STATUS_UNPROCESSABLE_ENTITY"></a> | 422 | Unprocessable Entity |
-| `NNG_HTTP_STATUS_LOCKED`<a name="#NNG_HTTP_STATUS_LOCKED"></a> | 423 | Locked |
-| `NNG_HTTP_STATUS_FAILED_DEPENDENCY`<a name="#NNG_HTTP_STATUS_FAILED_DEPEDNENCY"></a> | 424 | Failed Dependency |
-| `NNG_HTTP_STATUS_TOO_EARLY`<a name="#NNG_HTTP_STATUS_TOO_EARLY"></a> | 425 | Too Early |
-| `NNG_HTTP_STATUS_UPGRADE_REQUIRED`<a name="#NNG_HTTP_STATUS_UPGRADE_REQUIRED"></a> | 426 | Upgrade Required |
-| `NNG_HTTP_STATUS_PRECONDITION_REQUIRED`<a name="#NNG_HTTP_STATUS_PRECONDITION_REQUIRED"></a> | 428 | Precondition Required | |
-| `NNG_HTTP_STATUS_TOO_MANY_REQUESTS`<a name="#NNG_HTTP_STATUS_TOO_MANY_REQUESTS"></a> | 429 | Too Many Requests | |
-| `NNG_HTTP_STATUS_HEADERS_TOO_LARGE`<a name="#NNG_HTTP_STATUS_HEADERS_TOO_LARGE"></a> | 431 | Headers Too Large | |
-| `NNG_HTTP_STATUS_UNAVAIL_LEGAL_REASONS`<a name="#NNG_HTTP_STATUS_UNAVAIL_LEGAL_REASONS"></a> | 451 | Unavailabe For Legal Reasons | |
-| `NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR`<a name="#NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR"></a> | 500 | Internal Server Error |
-| `NNG_HTTP_STATUS_NOT_IMPLEMENTED`<a name="#NNG_HTTP_STATUS_NOT_IMPLEMENTED"></a> | 501 | Not Implemented | Server does not implement method. |
-| `NNG_HTTP_STATUS_BAD_GATEWAY`<a name="#NNG_HTTP_STATUS_BAD_GATEWAY"></a> | 502 | Bad Gateway |
-| `NNG_HTTP_STATUS_SERVICE_UNAVAILALE`<a name="#NNG_HTTP_STATUS_SERVICE_UNAVAILABLE"></a> | 503 | Service Unavailable |
-| `NNG_HTTP_STATUS_GATEWAY_TIMEOUT`<a name="#NNG_HTTP_STATUS_GATEWAY_TIMEOUT"></a> | 504 | Gateway TImeout |
-| `NNG_HTTP_STATUS_HTTP_VERSION_NOT_SUPP`<a name="#NNG_HTTP_STATUS_HTTP_VERSION_NOT_SUPP"></a> | 505 | HTTP Version Not Supported |
-| `NNG_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES`<a name="#NNG_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES"></a> | 506 | Variant Also Negotiates |
-| `NNG_HTTP_STATUS_INSUFFICIENT_STORAGE`<a name="#NNG_HTTP_STATUS_INSUFFICIENT_STORAGE"></a> | 507 | Variant Also Negotiates |
-| `NNG_HTTP_STATUS_LOOP_DETECTED`<a name="#NNG_HTTP_STATUS_LOOP_DETECTED"></a> | 508 | Loop Detected |
-| `NNG_HTTP_STATUS_NOT_EXTENDED`<a name="#NNG_HTTP_STATUS_NOT_EXTENDED"></a> | 510 | Not Extended |
-| `NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED`<a name="#NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED"></a> | 511 | Network Authentication Required |
+| Name | Code | Reason Text | Notes |
+| ----------------------------------------------------------------------------------------------- | ---- | ------------------------------- | ----------------------------------------------------- |
+| `NNG_HTTP_STATUS_CONTINUE`<a name="NNG_HTTP_STATUS_CONTINUE"></a> | 100 | Continue | Partial transfer, client may send body. |
+| `NNG_HTTP_STATUS_SWITCHING`<a name="NNG_HTTP_STATUS_SWITCHING"></a> | 101 | Switching Protocols | Used when upgrading or hijacking a connection. |
+| `NNG_HTTP_STATUS_PROCESSING`<a name="NNG_HTTP_STATUS_PROCESSING"></a> | 102 | Processing |
+| `NNG_HTTP_STATUS_OK`<a name="NNG_HTTP_STATUS_OK"></a> | 200 | OK | Successful result. |
+| `NNG_HTTP_STATUS_CREATED`<a name="NNG_HTTP_STATUS_CREATED"></a> | 201 | Created | Resource created successfully. |
+| `NNG_HTTP_STATUS_ACCEPTED`<a name="NNG_HTTP_STATUS_ACCEPTED"></a> | 202 | Created | Request accepted for future processing. |
+| `NNG_HTTP_STATUS_NOT_AUTHORITATIVE`<a name="NNG_HTTP_STATUS_NOT_AUTHORITATIVE"></a> | 203 | Not Authoritative | Request successful, but modified by proxy. |
+| `NNG_HTTP_STATUS_NO_CONTENT`<a name="NNG_HTTP_STATUS_NO_CONTENT"></a> | 204 | No Content | Request successful, no content returned. |
+| `NNG_HTTP_STATUS_RESET_CONTENT`<a name="NNG_HTTP_STATUS_NO_CONTENT"></a> | 205 | Reset Content | Request successful, client should reload content. |
+| `NNG_HTTP_STATUS_PARTIAL_CONTENT`<a name="NNG_HTTP_STATUS_NO_CONTENT"></a> | 206 | Partial Content | Response to a range request. |
+| `NNG_HTTP_STATUS_MULTI_STATUS`<a name="NNG_HTTP_STATUS_MULTI_STATUS"></a> | 207 | Multi-Status | Used with WebDAV. |
+| `NNG_HTTP_STATUS_ALREADY_REPORTED`<a name="NNG_HTTP_STATUS_ALREADY_REPORTED"></a> | 208 | Already Reported | Used with WebDAV. |
+| `NNG_HTTP_STATUS_IM_USED`<a name="NNG_HTTP_STATUS_IM_USED"></a> | 226 | IM Used | Used with delta encodings, rarely supported. |
+| `NNG_HTTP_STATUS_MULTIPLE_CHOICES`<a name="NNG_HTTP_STATUS_MULTIPLE_CHOICES"></a> | 300 | Multiple Choices | Multiple responses possible, client should choose. |
+| `NNG_HTTP_STATUS_MOVED_PERMANENTLY`<a name="NNG_HTTP_STATUS_MOVED_PERMANENTLY"></a> | 301 | Moved Permanently | Permanent redirection, may be saved by client. |
+| `NNG_HTTP_STATUS_FOUND`<a name="NNG_HTTP_STATUS_FOUND"></a> | 302 | Found | Temporary redirection, client may switch to GET. |
+| `NNG_HTTP_STATUS_SEE_OTHER`<a name="NNG_HTTP_STATUS_SEE_OTHER"></a> | 303 | See Other | Redirect, perhaps after a success POST or PUT. |
+| `NNG_HTTP_STATUS_NOT_MODIFIED`<a name="NNG_HTTP_STATUS_NOT_MODIFIED"></a> | 304 | Not Modified | Resource not modified, client may use cached version. |
+| `NNG_HTTP_STATUS_USE_PROXY`<a name="NNG_HTTP_STATUS_USE_PROXY"></a> | 305 | Use Proxy |
+| `NNG_HTTP_STATUS_TEMPORARY_REDIRECT`<a name="NNG_HTTP_STATUS_TEMPORARY_REDIRECT"></a> | 307 | Temporary Redirect | Temporary redirect, preserves method. |
+| `NNG_HTTP_STATUS_PERMANENT_REDIRECT`<a name="NNG_HTTP_STATUS_PERMANENT_REDIRECT"></a> | 308 | Permanent Redirect | Permanent redirect. |
+| `NNG_HTTP_STATUS_BAD_REQUEST`<a name="NNG_HTTP_STATUS_BAD_REQUEST"></a> | 400 | Bad Request | Generic problem with the request. |
+| `NNG_HTTP_STATUS_UNAUTHORIZED`<a name="NNG_HTTP_STATUS_UNAUTHORIZED"></a> | 401 | Unauthorized | Indicates a problem with authentication. |
+| `NNG_HTTP_STATUS_PAYMENT_REQUIRED`<a name="NNG_HTTP_STATUS_PAYMENT_REQUIRED"></a> | 402 | Payment Required |
+| `NNG_HTTP_STATUS_FORBIDDEN`<a name="NNG_HTTP_STATUS_FORBIDDEN"></a> | 403 | Forbidden | No permission to access resource. |
+| `NNG_HTTP_STATUS_NOT_FOUND`<a name="NNG_HTTP_STATUS_NOT_FOUND"></a> | 404 | Not Found | Resource does not exist. |
+| `NNG_HTTP_STATUS_METHOD_NOT_ALLOWED`<a name="NNG_HTTP_STATUS_METHOD_NOT_ALLOWED"></a> | 405 | Method Not Allowed | Resource does not support the method. |
+| `NNG_HTTP_STATUS_METHOD_NOT_ACCEPTABLE`<a name="NNG_HTTP_STATUS_METHOD_NOT_ACCEPTABLE"></a> | 406 | Not Acceptable | Could not satisfy accept requirements. |
+| `NNG_HTTP_STATUS_PROXY_AUTH_REQUIRED`<a name="NNG_HTTP_STATUS_PROXY_AUTH_REQUIRED"></a> | 407 | Proxy Authentication Required | Proxy requires authentication. |
+| `NNG_HTTP_STATUS_REQUEST_TIMEOUT`<a name="NNG_HTTP_STATUS_REQUEST_TIMEOUT"></a> | 408 | Request Timeout | Timed out waiting for request. |
+| `NNG_HTTP_STATUS_CONFLICT`<a name="NNG_HTTP_STATUS_CONFLICT"></a> | 409 | Conflict | Conflicting request. |
+| `NNG_HTTP_STATUS_GONE`<a name="NNG_HTTP_STATUS_GONE"></a> | 410 | Gone | Resource no longer exists. |
+| `NNG_HTTP_STATUS_LENGTH_REQUIRED`<a name="NNG_HTTP_STATUS_LENGTH_REQUIRED"></a> | 411 | Length Required | Missing Content-Length. |
+| `NNG_HTTP_STATUS_PRECONDITION_FAILED`<a name="NNG_HTTP_STATUS_PRECONDITION_FAILED"></a> | 412 | Precondition Failed | |
+| `NNG_HTTP_STATUS_CONTENT_TOO_LARGE`<a name="NNG_HTTP_STATUS_PAYLOAD_TOO_LARGE"></a> | 413 | Content Too Large | |
+| `NNG_HTTP_STATUS_URI_TOO_LONG`<a name="NNG_HTTP_STATUS_URI_TOO_LONG"></a> | 414 | URI Too Long | |
+| `NNG_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE`<a name="NNG_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE"></a> | 415 | Unsupported Media Type |
+| `NNG_HTTP_STATUS_RANGE_NOT_SATISFIABLE`<a name="NNG_HTTP_STATUS_RANGE_NOT_SATISFIABLE"></a> | 416 | Range Not Satisfiable |
+| `NNG_HTTP_STATUS_EXPECTATION_FAILED`<a name="NNG_HTTP_STATUS_EXPECTATION_FAILED"></a> | 417 | Expectation Failed |
+| `NNG_HTTP_STATUS_TEAPOT`<a name="NNG_HTTP_STATUS_TEAPOT"></a> | 418 | I Am A Teapot | RFC 2324. |
+| `NNG_HTTP_STATUS_UNPROCESSABLE_ENTITY`<a name="NNG_HTTP_STATUS_UNPROCESSABLE_ENTITY"></a> | 422 | Unprocessable Entity |
+| `NNG_HTTP_STATUS_LOCKED`<a name="NNG_HTTP_STATUS_LOCKED"></a> | 423 | Locked |
+| `NNG_HTTP_STATUS_FAILED_DEPENDENCY`<a name="NNG_HTTP_STATUS_FAILED_DEPEDNENCY"></a> | 424 | Failed Dependency |
+| `NNG_HTTP_STATUS_TOO_EARLY`<a name="NNG_HTTP_STATUS_TOO_EARLY"></a> | 425 | Too Early |
+| `NNG_HTTP_STATUS_UPGRADE_REQUIRED`<a name="NNG_HTTP_STATUS_UPGRADE_REQUIRED"></a> | 426 | Upgrade Required |
+| `NNG_HTTP_STATUS_PRECONDITION_REQUIRED`<a name="NNG_HTTP_STATUS_PRECONDITION_REQUIRED"></a> | 428 | Precondition Required | |
+| `NNG_HTTP_STATUS_TOO_MANY_REQUESTS`<a name="NNG_HTTP_STATUS_TOO_MANY_REQUESTS"></a> | 429 | Too Many Requests | |
+| `NNG_HTTP_STATUS_HEADERS_TOO_LARGE`<a name="NNG_HTTP_STATUS_HEADERS_TOO_LARGE"></a> | 431 | Headers Too Large | |
+| `NNG_HTTP_STATUS_UNAVAIL_LEGAL_REASONS`<a name="NNG_HTTP_STATUS_UNAVAIL_LEGAL_REASONS"></a> | 451 | Unavailabe For Legal Reasons | |
+| `NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR`<a name="NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR"></a> | 500 | Internal Server Error |
+| `NNG_HTTP_STATUS_NOT_IMPLEMENTED`<a name="NNG_HTTP_STATUS_NOT_IMPLEMENTED"></a> | 501 | Not Implemented | Server does not implement method. |
+| `NNG_HTTP_STATUS_BAD_GATEWAY`<a name="NNG_HTTP_STATUS_BAD_GATEWAY"></a> | 502 | Bad Gateway |
+| `NNG_HTTP_STATUS_SERVICE_UNAVAILALE`<a name="NNG_HTTP_STATUS_SERVICE_UNAVAILABLE"></a> | 503 | Service Unavailable |
+| `NNG_HTTP_STATUS_GATEWAY_TIMEOUT`<a name="NNG_HTTP_STATUS_GATEWAY_TIMEOUT"></a> | 504 | Gateway TImeout |
+| `NNG_HTTP_STATUS_HTTP_VERSION_NOT_SUPP`<a name="NNG_HTTP_STATUS_HTTP_VERSION_NOT_SUPP"></a> | 505 | HTTP Version Not Supported |
+| `NNG_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES`<a name="NNG_HTTP_STATUS_VARIANT_ALSO_NEGOTIATES"></a> | 506 | Variant Also Negotiates |
+| `NNG_HTTP_STATUS_INSUFFICIENT_STORAGE`<a name="NNG_HTTP_STATUS_INSUFFICIENT_STORAGE"></a> | 507 | Variant Also Negotiates |
+| `NNG_HTTP_STATUS_LOOP_DETECTED`<a name="NNG_HTTP_STATUS_LOOP_DETECTED"></a> | 508 | Loop Detected |
+| `NNG_HTTP_STATUS_NOT_EXTENDED`<a name="NNG_HTTP_STATUS_NOT_EXTENDED"></a> | 510 | Not Extended |
+| `NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED`<a name="NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED"></a> | 511 | Network Authentication Required |
### Retrieving Headers
@@ -578,6 +578,7 @@ typedef void (*nng_http_hander_func)(nng_http_conn *conn, void *arg, nng_aio *ai
nng_err nng_http_handler_alloc(nng_http_handler **hp, const char *path, nng_http_handler_func cb);
```
+<a name="nng_http_handler_alloc"/>
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_.
@@ -615,26 +616,27 @@ 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);
+nng_err nng_http_handler_directory(nng_http_handler **hp, const char *path, const char *dirname);
+nng_err nng_http_handler_file(nng_http_handler **hp, const char *path, const char *filename, const char *ctype);
```
-The {{i:`nng_http_handler_alloc_directory`}} and {{i:`nng_http_handler_alloc_file`}}
+The {{i:`nng_http_handler_directory`}} and {{i:`nng_http_handler_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".
+matches one of the built-in values already known and _ctype_ is `NULL`.
+If _ctype_ is not `NULL`, then the "Content-Type" is set to its value.
+Otherwise, if 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,
+nng_err nng_http_handler_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
+The {{i:`nng_http_handler_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.
@@ -642,11 +644,11 @@ 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_err nng_http_handler_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
+The {{i:`nng_http_handler_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_,
@@ -779,6 +781,19 @@ the path to pass additional parameters.
> service address (path) supports dynamically generated children.
> It can also provide a logical fallback instead of relying on a 404 error code.
+### Destroying a Handler
+
+```c
+void nng_http_handler_free(nng_http_handler *handler);
+```
+
+The {{i:`nng_http_handler_free`}} function can be called to destroy a handler.
+
+> [!TIP]
+> This function should not normally be needed, unless a the handler cannot be
+> added to a server. Once the handler is taken over by the server, it is owned
+> by the server and the server will dispose of it when it is removed or the server is destroyed.
+
### Sending the Response Explicitly
```c
diff --git a/docs/ref/xref.md b/docs/ref/xref.md
index e3b57585..32523c77 100644
--- a/docs/ref/xref.md
+++ b/docs/ref/xref.md
@@ -294,6 +294,11 @@
[`nng_http_read_all`]: /api/http.md#direct-read-and-write
[`nng_http_write`]: /api/http.md#direct-read-and-write
[`nng_http_write_all`]: /api/http.md#direct-read-and-write
+[`nng_http_handler_alloc`]: /api/http.md#nng_http_handler_alloc
+[`nng_http_handler_static`]: /api/http.md#nng_http_handler_static
+[`nng_http_handler_redirect`]: /api/http.md#nng_http_handler_redirect
+[`nng_http_handler_file`]: /api/http.md#nng_http_handler_file
+[`nng_http_handler_directory`]: /api/http.md#nng_http_handler_directory
<!-- Macros -->
diff --git a/include/nng/http.h b/include/nng/http.h
index 1ff541ac..e4c578a6 100644
--- a/include/nng/http.h
+++ b/include/nng/http.h
@@ -242,20 +242,21 @@ NNG_DECL void nng_http_handler_free(nng_http_handler *);
// nng_http_handler_alloc_file creates a "file" based handler, that
// serves up static content from the given file path. The content-type
-// supplied is determined from the file name using a simple built-in map.
-NNG_DECL nng_err nng_http_handler_alloc_file(
- nng_http_handler **, const char *, const char *);
+// is taken from the 3rd argument, unless that is NULL, in which case
+// it is determined from the file name using a simple built-in map.
+NNG_DECL nng_err nng_http_handler_file(
+ nng_http_handler **, const char *, const char *, const char *);
// nng_http_handler_alloc_static creates a static-content handler.
// The last argument is the content-type, which may be NULL (in which case
// "application/octet-stream" is assumed.)
-NNG_DECL nng_err nng_http_handler_alloc_static(
+NNG_DECL nng_err nng_http_handler_static(
nng_http_handler **, const char *, const void *, size_t, const char *);
// nng_http_handler_alloc_redirect creates an HTTP redirect handler.
// The status is given, along with the new URL. If the status is 0,
// then 301 will be used instead.
-NNG_DECL nng_err nng_http_handler_alloc_redirect(
+NNG_DECL nng_err nng_http_handler_redirect(
nng_http_handler **, const char *, nng_http_status, const char *);
// nng_http_handler_alloc_file creates a "directory" based handler, that
@@ -264,7 +265,7 @@ NNG_DECL nng_err nng_http_handler_alloc_redirect(
// directory content, otherwise a suitable error page is returned (the server
// does not generate index pages automatically.) The content-type for
// files is determined from the file name using a simple built-in map.
-NNG_DECL nng_err nng_http_handler_alloc_directory(
+NNG_DECL nng_err nng_http_handler_directory(
nng_http_handler **, const char *, const char *);
// nng_http_handler_set_method sets the method that the handler will be
diff --git a/src/supplemental/http/http_api.h b/src/supplemental/http/http_api.h
index 61c6e45f..c2fd5eec 100644
--- a/src/supplemental/http/http_api.h
+++ b/src/supplemental/http/http_api.h
@@ -22,14 +22,13 @@
#include <stdbool.h>
-typedef struct nng_http_req nni_http_req;
-typedef struct nng_http_res nni_http_res;
-typedef struct nng_http_conn nni_http_conn;
-typedef struct nng_http_handler nni_http_handler;
-typedef struct nng_http_server nni_http_server;
-typedef struct nng_http_client nni_http_client;
-typedef struct nng_http_chunk nni_http_chunk;
-typedef struct nng_http_chunks nni_http_chunks;
+typedef struct nng_http_req nni_http_req;
+typedef struct nng_http_res nni_http_res;
+typedef struct nng_http_conn nni_http_conn;
+typedef struct nng_http_server nni_http_server;
+typedef struct nng_http_client nni_http_client;
+typedef struct nng_http_chunk nni_http_chunk;
+typedef struct nng_http_chunks nni_http_chunks;
// These functions are private to the internal framework, and really should
// not be used elsewhere.
@@ -155,14 +154,14 @@ extern void nni_http_server_fini(nni_http_server *);
// is already registered (i.e. a handler with the same value for Host,
// Method, and URL.)
extern nng_err nni_http_server_add_handler(
- nni_http_server *, nni_http_handler *);
+ nni_http_server *, nng_http_handler *);
// nni_http_del_handler removes the given handler. The caller is
// responsible for finalizing it afterwards. If the handler was not found
// (not registered), NNG_ENOENT is returned. In this case it is unsafe
// to make assumptions about the validity of the handler.
extern nng_err nni_http_server_del_handler(
- nni_http_server *, nni_http_handler *);
+ nni_http_server *, nng_http_handler *);
// nni_http_server_set_tls adds a TLS configuration to the server,
// and enables the use of it. This returns NNG_EBUSY if the server is
@@ -220,56 +219,51 @@ extern nng_err nni_http_server_error(nni_http_server *, nng_http *);
// further processing.)
extern nng_err nni_http_hijack(nni_http_conn *);
-// nni_http_handler_init creates a server handler object, for the supplied
+// nni_http_handler_alloc creates a server handler object, for the supplied
// URI (path only) with the callback.
//
// Note that methods which modify a handler cannot be called while the handler
// is registered with the server, and that a handler can only be registered
// once per server.
-extern nng_err nni_http_handler_init(
- nni_http_handler **, const char *, nng_http_handler_func);
+extern nng_err nni_http_handler_alloc(
+ nng_http_handler **, const char *, nng_http_handler_func);
-// nni_http_handler_init_file creates a handler with a function to serve
+// nni_http_handler_creates a handler with a function to serve
// up a file named in the last argument.
-extern nng_err nni_http_handler_init_file(
- nni_http_handler **, const char *, const char *);
+extern nng_err nni_http_handler_file(
+ nng_http_handler **, const char *, const char *, const char *);
-// nni_http_handler_init_file_ctype is like nni_http_handler_init_file, but
-// provides for setting the Content-Type explicitly (last argument).
-extern nng_err nni_http_handler_init_file_ctype(
- nni_http_handler **, const char *, const char *, const char *);
-
-// nni_http_handler_init_directory arranges to serve up an entire
+// nni_http_handler_directory serves up an entire
// directory tree. The content types are determined from the built-in
// content type list. Actual directories are required to contain a
// file called index.html or index.htm. We do not generate directory
// listings for security reasons.
-extern nng_err nni_http_handler_init_directory(
- nni_http_handler **, const char *, const char *);
+extern nng_err nni_http_handler_directory(
+ nng_http_handler **, const char *, const char *);
-// nni_http_handler_init_static creates a handler that serves up static content
-// supplied, with the Content-Type supplied in the final argument.
-extern nng_err nni_http_handler_init_static(
- nni_http_handler **, const char *, const void *, size_t, const char *);
+// nni_http_handler_static creates a handler that serves up static
+// content supplied, with the Content-Type supplied in the final argument.
+extern nng_err nni_http_handler_static(
+ nng_http_handler **, const char *, const void *, size_t, const char *);
-// nni_http_handler_init_redirect creates a handler that redirects the request.
-extern nng_err nni_http_handler_init_redirect(
- nni_http_handler **, const char *, nng_http_status, const char *);
+// nni_http_handler_redirect creates a handler that redirects the request.
+extern nng_err nni_http_handler_redirect(
+ nng_http_handler **, const char *, nng_http_status, const char *);
-// nni_http_handler_fini destroys a handler. This should only be done before
+// nni_http_handler_free destroys a handler. This should only be done before
// the handler is added, or after it is deleted. The server automatically
// calls this for any handlers still registered with it if it is destroyed.
-extern void nni_http_handler_fini(nni_http_handler *);
+extern void nni_http_handler_free(nng_http_handler *);
// nni_http_handler_collect_body informs the server that it should collect
// the entitty data associated with the client request, and sets the maximum
// size to accept.
-extern void nni_http_handler_collect_body(nni_http_handler *, bool, size_t);
+extern void nni_http_handler_collect_body(nng_http_handler *, bool, size_t);
// nni_http_handler_set_tree marks the handler as servicing the entire
// tree (e.g. a directory), rather than just a leaf node. The handler
// will probably need to inspect the URL of the request.
-extern void nni_http_handler_set_tree(nni_http_handler *);
+extern void nni_http_handler_set_tree(nng_http_handler *);
// nni_http_handler_set_host limits the handler to only being called for
// the given Host: field. This can be used to set up multiple virtual
@@ -280,7 +274,7 @@ extern void nni_http_handler_set_tree(nni_http_handler *);
// on port number as we assume that clients MUST have gotten that part right
// as we do not support virtual hosting on multiple separate ports; the
// server only listens on a single port.
-extern void nni_http_handler_set_host(nni_http_handler *, const char *);
+extern void nni_http_handler_set_host(nng_http_handler *, const char *);
// nni_http_handler_set_method limits the handler to only being called
// for the given HTTP method. By default a handler is called for GET
@@ -290,16 +284,16 @@ extern void nni_http_handler_set_host(nni_http_handler *, const char *);
// is obligated to inspect the method. (Note: the passed method must be
// in upper case and should come from a statically allocated string; the
// server does not make its own copy.)
-extern void nni_http_handler_set_method(nni_http_handler *, const char *);
+extern void nni_http_handler_set_method(nng_http_handler *, const char *);
// nni_http_handler_set_data sets an opaque data element on the handler,
// which will be available to the handler function as argument.
// The callback is an optional destructor, and will be called with the
// data as its argument, when the handler is being destroyed.
-extern void nni_http_handler_set_data(nni_http_handler *, void *, nni_cb);
+extern void nni_http_handler_set_data(nng_http_handler *, void *, nni_cb);
// nni_http_handler_get_uri returns the URI set on the handler.
-extern const char *nni_http_handler_get_uri(nni_http_handler *);
+extern const char *nni_http_handler_get_uri(nng_http_handler *);
// Client stuff.
diff --git a/src/supplemental/http/http_public.c b/src/supplemental/http/http_public.c
index 84477cc1..054080c0 100644
--- a/src/supplemental/http/http_public.c
+++ b/src/supplemental/http/http_public.c
@@ -299,7 +299,7 @@ nng_http_handler_alloc(
nng_http_handler **hp, const char *uri, nng_http_handler_func cb)
{
#ifdef NNG_SUPP_HTTP
- return (nni_http_handler_init(hp, uri, cb));
+ return (nni_http_handler_alloc(hp, uri, cb));
#else
NNI_ARG_UNUSED(hp);
NNI_ARG_UNUSED(uri);
@@ -312,18 +312,18 @@ void
nng_http_handler_free(nng_http_handler *h)
{
#ifdef NNG_SUPP_HTTP
- nni_http_handler_fini(h);
+ nni_http_handler_free(h);
#else
NNI_ARG_UNUSED(h);
#endif
}
nng_err
-nng_http_handler_alloc_file(
- nng_http_handler **hp, const char *uri, const char *path)
+nng_http_handler_file(nng_http_handler **hp, const char *uri, const char *path,
+ const char *ctype)
{
#ifdef NNG_SUPP_HTTP
- return (nni_http_handler_init_file(hp, uri, path));
+ return (nni_http_handler_file(hp, uri, path, ctype));
#else
NNI_ARG_UNUSED(hp);
NNI_ARG_UNUSED(uri);
@@ -333,11 +333,11 @@ nng_http_handler_alloc_file(
}
nng_err
-nng_http_handler_alloc_directory(
+nng_http_handler_directory(
nng_http_handler **hp, const char *uri, const char *path)
{
#ifdef NNG_SUPP_HTTP
- return (nni_http_handler_init_directory(hp, uri, path));
+ return (nni_http_handler_directory(hp, uri, path));
#else
NNI_ARG_UNUSED(hp);
NNI_ARG_UNUSED(uri);
@@ -347,11 +347,11 @@ nng_http_handler_alloc_directory(
}
nng_err
-nng_http_handler_alloc_redirect(nng_http_handler **hp, const char *uri,
+nng_http_handler_redirect(nng_http_handler **hp, const char *uri,
nng_http_status status, const char *where)
{
#ifdef NNG_SUPP_HTTP
- return (nni_http_handler_init_redirect(hp, uri, status, where));
+ return (nni_http_handler_redirect(hp, uri, status, where));
#else
NNI_ARG_UNUSED(hp);
NNI_ARG_UNUSED(uri);
@@ -362,11 +362,11 @@ nng_http_handler_alloc_redirect(nng_http_handler **hp, const char *uri,
}
nng_err
-nng_http_handler_alloc_static(nng_http_handler **hp, const char *uri,
+nng_http_handler_static(nng_http_handler **hp, const char *uri,
const void *data, size_t size, const char *ctype)
{
#ifdef NNG_SUPP_HTTP
- return (nni_http_handler_init_static(hp, uri, data, size, ctype));
+ return (nni_http_handler_static(hp, uri, data, size, ctype));
#else
NNI_ARG_UNUSED(hp);
NNI_ARG_UNUSED(uri);
diff --git a/src/supplemental/http/http_server.c b/src/supplemental/http/http_server.c
index 53da78c2..725e824f 100644
--- a/src/supplemental/http/http_server.c
+++ b/src/supplemental/http/http_server.c
@@ -36,7 +36,7 @@ struct nng_http_handler {
nng_sockaddr host_addr;
bool host_ip;
bool tree;
- nni_atomic_int ref;
+ nni_refcnt ref;
nni_atomic_bool busy;
size_t maxbody;
bool getbody;
@@ -50,8 +50,8 @@ typedef struct http_sconn {
nni_list_node node;
nni_http_conn *conn;
nni_http_server *server;
- nni_http_handler *handler; // set if we deferred to read body
- nni_http_handler *release; // set if we dispatched handler
+ nng_http_handler *handler; // set if we deferred to read body
+ nng_http_handler *release; // set if we dispatched handler
bool close;
bool finished;
size_t unconsumed_body;
@@ -104,17 +104,34 @@ static nni_reap_list http_server_reap_list = {
.rl_func = (nni_cb) http_server_fini,
};
+static void
+http_handler_fini(void *arg)
+{
+ nng_http_handler *h = arg;
+ if (h->dtor != NULL) {
+ h->dtor(h->data);
+ }
+ NNI_FREE_STRUCT(h);
+}
+
+void
+nni_http_handler_free(nng_http_handler *h)
+{
+ if (h) {
+ nni_refcnt_rele(&h->ref);
+ }
+}
+
nng_err
-nni_http_handler_init(
- nni_http_handler **hp, const char *uri, nng_http_handler_func cb)
+nni_http_handler_alloc(
+ nng_http_handler **hp, const char *uri, nng_http_handler_func cb)
{
- nni_http_handler *h;
+ nng_http_handler *h;
if ((h = NNI_ALLOC_STRUCT(h)) == NULL) {
return (NNG_ENOMEM);
}
- nni_atomic_init(&h->ref);
- nni_atomic_inc(&h->ref);
+ nni_refcnt_init(&h->ref, 1, h, http_handler_fini);
// Default for HTTP is /. But remap it to "" for ease of matching.
if ((uri == NULL) || (strlen(uri) == 0) || (strcmp(uri, "/") == 0)) {
@@ -134,29 +151,15 @@ nni_http_handler_init(
return (NNG_OK);
}
-// nni_http_handler_fini just drops the reference count, only destroying
-// the handler if the reference drops to zero.
void
-nni_http_handler_fini(nni_http_handler *h)
-{
- if (nni_atomic_dec_nv(&h->ref) != 0) {
- return;
- }
- if (h->dtor != NULL) {
- h->dtor(h->data);
- }
- NNI_FREE_STRUCT(h);
-}
-
-void
-nni_http_handler_collect_body(nni_http_handler *h, bool want, size_t maxbody)
+nni_http_handler_collect_body(nng_http_handler *h, bool want, size_t maxbody)
{
h->getbody = want;
h->maxbody = maxbody;
}
void
-nni_http_handler_set_data(nni_http_handler *h, void *data, nni_cb dtor)
+nni_http_handler_set_data(nng_http_handler *h, void *data, nni_cb dtor)
{
NNI_ASSERT(!nni_atomic_get_bool(&h->busy));
h->data = data;
@@ -164,7 +167,7 @@ nni_http_handler_set_data(nni_http_handler *h, void *data, nni_cb dtor)
}
const char *
-nni_http_handler_get_uri(nni_http_handler *h)
+nni_http_handler_get_uri(nng_http_handler *h)
{
if (strlen(h->uri) == 0) {
return ("/");
@@ -173,14 +176,14 @@ nni_http_handler_get_uri(nni_http_handler *h)
}
void
-nni_http_handler_set_tree(nni_http_handler *h)
+nni_http_handler_set_tree(nng_http_handler *h)
{
NNI_ASSERT(!nni_atomic_get_bool(&h->busy));
h->tree = true;
}
void
-nni_http_handler_set_host(nni_http_handler *h, const char *host)
+nni_http_handler_set_host(nng_http_handler *h, const char *host)
{
NNI_ASSERT(!nni_atomic_get_bool(&h->busy));
@@ -214,7 +217,7 @@ nni_http_handler_set_host(nni_http_handler *h, const char *host)
}
void
-nni_http_handler_set_method(nni_http_handler *h, const char *method)
+nni_http_handler_set_method(nng_http_handler *h, const char *method)
{
NNI_ASSERT(!nni_atomic_get_bool(&h->busy));
if (method == NULL) {
@@ -360,7 +363,7 @@ nni_http_hijack(nni_http_conn *conn)
}
static bool
-http_handler_host_match(nni_http_handler *h, const char *host)
+http_handler_host_match(nng_http_handler *h, const char *host)
{
nng_sockaddr sa;
size_t len;
@@ -422,8 +425,8 @@ http_sconn_rxdone(void *arg)
nni_http_server *s = sc->server;
nni_aio *aio = &sc->rxaio;
int rv;
- nni_http_handler *h = NULL;
- nni_http_handler *head = NULL;
+ nng_http_handler *h = NULL;
+ nng_http_handler *head = NULL;
const char *val;
nni_http_req *req = nni_http_conn_req(sc->conn);
const char *uri;
@@ -604,7 +607,6 @@ finish:
// Set a reference -- this because the callback may be running
// asynchronously even after it gets removed from the server.
- nni_atomic_inc(&h->ref);
nni_aio_reset(&sc->cbaio);
@@ -615,6 +617,7 @@ finish:
nni_http_set_version(sc->conn, NNG_HTTP_VERSION_1_1);
nni_http_set_status(sc->conn, 0, NULL);
+ nni_refcnt_hold(&h->ref);
h->cb(sc->conn, h->data, &sc->cbaio);
}
@@ -623,7 +626,7 @@ http_sconn_cbdone(void *arg)
{
http_sconn *sc = arg;
nni_aio *aio = &sc->cbaio;
- nni_http_handler *h;
+ nng_http_handler *h;
nni_http_server *s = sc->server;
// Get the handler. It may be set regardless of success or
@@ -631,7 +634,7 @@ http_sconn_cbdone(void *arg)
// done with the handler for now.
if ((h = sc->release) != NULL) {
sc->release = NULL;
- nni_http_handler_fini(h);
+ nni_refcnt_rele(&h->ref);
}
if (nni_aio_result(aio) != 0) {
@@ -751,7 +754,7 @@ http_server_acccb(void *arg)
static void
http_server_fini(nni_http_server *s)
{
- nni_http_handler *h;
+ nng_http_handler *h;
http_error *epage;
nni_aio_stop(&s->accaio);
@@ -762,7 +765,7 @@ http_server_fini(nni_http_server *s)
nng_stream_listener_free(s->listener);
while ((h = nni_list_first(&s->handlers)) != NULL) {
nni_list_remove(&s->handlers, h);
- nni_http_handler_fini(h);
+ nni_refcnt_rele(&h->ref);
}
nni_mtx_unlock(&s->mtx);
nni_mtx_lock(&s->errors_mtx);
@@ -800,7 +803,7 @@ http_server_init(nni_http_server **serverp, const nng_url *url)
}
nni_mtx_init(&s->mtx);
nni_mtx_init(&s->errors_mtx);
- NNI_LIST_INIT(&s->handlers, nni_http_handler, node);
+ NNI_LIST_INIT(&s->handlers, nng_http_handler, node);
NNI_LIST_INIT(&s->conns, http_sconn, node);
nni_mtx_init(&s->errors_mtx);
@@ -1009,9 +1012,9 @@ nni_http_server_error(nni_http_server *s, nng_http *conn)
}
nng_err
-nni_http_server_add_handler(nni_http_server *s, nni_http_handler *h)
+nni_http_server_add_handler(nni_http_server *s, nng_http_handler *h)
{
- nni_http_handler *h2;
+ nng_http_handler *h2;
// Must have a legal method (and not one that is HEAD), path,
// and handler. (The reason HEAD is verboten is that we supply
@@ -1066,23 +1069,23 @@ nni_http_server_add_handler(nni_http_server *s, nni_http_handler *h)
}
nng_err
-nni_http_server_del_handler(nni_http_server *s, nni_http_handler *h)
+nni_http_server_del_handler(nni_http_server *s, nng_http_handler *h)
{
- nng_err rv = NNG_ENOENT;
- nni_http_handler *srch;
+ nng_http_handler *srch;
nni_mtx_lock(&s->mtx);
NNI_LIST_FOREACH (&s->handlers, srch) {
if (srch == h) {
// NB: We are giving the caller our reference
// on the handler.
nni_list_remove(&s->handlers, h);
- rv = NNG_OK;
- break;
+ nni_mtx_unlock(&s->mtx);
+ nni_refcnt_rele(&h->ref);
+ return (NNG_OK);
}
}
nni_mtx_unlock(&s->mtx);
- return (rv);
+ return (NNG_ENOENT);
}
// Very limited MIME type map. Used only if the handler does not
@@ -1216,10 +1219,10 @@ http_file_free(void *arg)
}
nng_err
-nni_http_handler_init_file_ctype(nni_http_handler **hpp, const char *uri,
+nni_http_handler_file(nng_http_handler **hpp, const char *uri,
const char *path, const char *ctype)
{
- nni_http_handler *h;
+ nng_http_handler *h;
http_file *hf;
nng_err rv;
@@ -1241,7 +1244,7 @@ nni_http_handler_init_file_ctype(nni_http_handler **hpp, const char *uri,
return (NNG_ENOMEM);
}
- if ((rv = nni_http_handler_init(&h, uri, http_handle_file)) != 0) {
+ if ((rv = nni_http_handler_alloc(&h, uri, http_handle_file)) != 0) {
http_file_free(hf);
return (rv);
}
@@ -1255,13 +1258,6 @@ nni_http_handler_init_file_ctype(nni_http_handler **hpp, const char *uri,
return (NNG_OK);
}
-nng_err
-nni_http_handler_init_file(
- nni_http_handler **hpp, const char *uri, const char *path)
-{
- return (nni_http_handler_init_file_ctype(hpp, uri, path, NULL));
-}
-
static void
http_handle_dir(nng_http *conn, void *arg, nng_aio *aio)
{
@@ -1388,11 +1384,11 @@ http_handle_dir(nng_http *conn, void *arg, nng_aio *aio)
}
nng_err
-nni_http_handler_init_directory(
- nni_http_handler **hpp, const char *uri, const char *path)
+nni_http_handler_directory(
+ nng_http_handler **hpp, const char *uri, const char *path)
{
http_file *hf;
- nni_http_handler *h;
+ nng_http_handler *h;
nng_err rv;
if ((hf = NNI_ALLOC_STRUCT(hf)) == NULL) {
@@ -1404,7 +1400,7 @@ nni_http_handler_init_directory(
return (NNG_ENOMEM);
}
- if ((rv = nni_http_handler_init(&h, uri, http_handle_dir)) != 0) {
+ if ((rv = nni_http_handler_alloc(&h, uri, http_handle_dir)) != 0) {
http_file_free(hf);
return (rv);
}
@@ -1480,10 +1476,10 @@ http_redirect_free(void *arg)
}
nng_err
-nni_http_handler_init_redirect(nni_http_handler **hpp, const char *uri,
+nni_http_handler_redirect(nng_http_handler **hpp, const char *uri,
nng_http_status status, const char *where)
{
- nni_http_handler *h;
+ nng_http_handler *h;
nng_err rv;
http_redirect *hr;
@@ -1500,7 +1496,8 @@ nni_http_handler_init_redirect(nni_http_handler **hpp, const char *uri,
}
hr->code = status;
- if ((rv = nni_http_handler_init(&h, uri, http_handle_redirect)) != 0) {
+ if ((rv = nni_http_handler_alloc(&h, uri, http_handle_redirect)) !=
+ 0) {
http_redirect_free(hr);
return (rv);
}
@@ -1555,10 +1552,10 @@ http_static_free(void *arg)
}
nng_err
-nni_http_handler_init_static(nni_http_handler **hpp, const char *uri,
+nni_http_handler_static(nng_http_handler **hpp, const char *uri,
const void *data, size_t size, const char *ctype)
{
- nni_http_handler *h;
+ nng_http_handler *h;
nng_err rv;
http_static *hs;
@@ -1573,7 +1570,7 @@ nni_http_handler_init_static(nni_http_handler **hpp, const char *uri,
hs->size = size;
memcpy(hs->data, data, size);
- if ((rv = nni_http_handler_init(&h, uri, http_handle_static)) != 0) {
+ if ((rv = nni_http_handler_alloc(&h, uri, http_handle_static)) != 0) {
http_static_free(hs);
return (rv);
}
diff --git a/src/supplemental/http/http_server_test.c b/src/supplemental/http/http_server_test.c
index e091cd89..b42a15d6 100644
--- a/src/supplemental/http/http_server_test.c
+++ b/src/supplemental/http/http_server_test.c
@@ -203,7 +203,7 @@ test_server_basic(void)
nng_iov iov;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -245,7 +245,7 @@ test_server_canonify(void)
nng_iov iov;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home/index.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -287,7 +287,7 @@ test_server_head(void)
size_t size;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -354,7 +354,7 @@ test_server_no_authoritive_form(void)
struct server_test st;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -381,7 +381,7 @@ test_server_bad_canonify(void)
struct server_test st;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -451,7 +451,7 @@ test_server_method_too_long(void)
{
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
nng_http_handler_set_method(h,
@@ -467,7 +467,7 @@ test_server_wrong_method(void)
struct server_test st;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -495,7 +495,7 @@ test_server_uri_too_long(void)
nng_http_handler *h;
char buf[32768];
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -526,7 +526,7 @@ test_server_header_too_long(void)
nng_http_handler *h;
char buf[32768];
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -557,7 +557,7 @@ test_server_invalid_utf8(void)
struct server_test st;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_static(
+ NUTS_PASS(nng_http_handler_static(
&h, "/home.html", doc1, strlen(doc1), "text/html"));
server_setup(&st, h);
@@ -625,7 +625,7 @@ test_server_get_redirect(void)
struct server_test st;
// We'll use a 303 (SEE OTHER) to ensure codes carry thru
- NUTS_PASS(nng_http_handler_alloc_redirect(
+ NUTS_PASS(nng_http_handler_redirect(
&h, "/here", NNG_HTTP_STATUS_SEE_OTHER, "http://127.0.0.1/there"));
server_setup(&st, h);
@@ -651,7 +651,7 @@ test_server_tree_redirect(void)
struct server_test st;
// We'll use a permanent redirect to ensure codes carry thru
- NUTS_PASS(nng_http_handler_alloc_redirect(&h, "/here",
+ NUTS_PASS(nng_http_handler_redirect(&h, "/here",
NNG_HTTP_STATUS_PERMANENT_REDIRECT, "http://127.0.0.1/there"));
nng_http_handler_set_tree(h);
server_setup(&st, h);
@@ -679,7 +679,7 @@ test_server_post_redirect(void)
struct server_test st;
nng_http_handler *h;
- NUTS_PASS(nng_http_handler_alloc_redirect(
+ NUTS_PASS(nng_http_handler_redirect(
&h, "/here", 301, "http://127.0.0.1/there"));
server_setup(&st, h);
@@ -772,20 +772,20 @@ test_server_multiple_trees(void)
NUTS_PASS(nni_file_put(file1, doc1, strlen(doc1)));
NUTS_PASS(nni_file_put(file2, doc2, strlen(doc2)));
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", workdir));
nng_http_handler_set_tree(h);
server_setup(&st, h);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", workdir));
nng_http_handler_set_tree(h);
NUTS_FAIL(nng_http_server_add_handler(st.s, h), NNG_EADDRINUSE);
nng_http_handler_free(h);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/subdir", workdir2));
+ NUTS_PASS(nng_http_handler_directory(&h, "/subdir", workdir2));
nng_http_handler_set_tree(h);
NUTS_PASS(nng_http_server_add_handler(st.s, h));
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/subdir", workdir2));
+ NUTS_PASS(nng_http_handler_directory(&h, "/subdir", workdir2));
nng_http_handler_set_tree(h);
NUTS_FAIL(nng_http_server_add_handler(st.s, h), NNG_EADDRINUSE);
nng_http_handler_free(h);
@@ -892,7 +892,7 @@ test_serve_directory(void)
struct serve_directory sd;
setup_directory(&sd);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", sd.workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", sd.workdir));
server_setup(&st, h);
NUTS_PASS(nng_http_set_uri(st.conn, "/subdir1/index.html", NULL));
@@ -921,7 +921,7 @@ test_serve_directory_index(void)
struct serve_directory sd;
setup_directory(&sd);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", sd.workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", sd.workdir));
server_setup(&st, h);
NUTS_CASE("Directory 1: index.html");
@@ -963,7 +963,7 @@ test_serve_plain_text(void)
struct serve_directory sd;
setup_directory(&sd);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", sd.workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", sd.workdir));
server_setup(&st, h);
NUTS_PASS(nng_http_set_uri(st.conn, "/file.txt", NULL));
@@ -992,7 +992,7 @@ test_serve_file_parameters(void)
struct serve_directory sd;
setup_directory(&sd);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", sd.workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", sd.workdir));
server_setup(&st, h);
NUTS_PASS(nng_http_set_uri(st.conn, "/file.txt?param=1234", NULL));
@@ -1033,7 +1033,7 @@ test_serve_missing_index(void)
struct serve_directory sd;
setup_directory(&sd);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", sd.workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", sd.workdir));
server_setup(&st, h);
NUTS_PASS(nng_http_set_uri(st.conn, "/index.html", NULL));
@@ -1059,7 +1059,7 @@ test_serve_index_not_post(void)
struct serve_directory sd;
setup_directory(&sd);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/", sd.workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/", sd.workdir));
server_setup(&st, h);
NUTS_PASS(nng_http_set_uri(st.conn, "/subdir2/index.html", NULL));
@@ -1086,7 +1086,7 @@ test_serve_subdir_index(void)
struct serve_directory sd;
setup_directory(&sd);
- NUTS_PASS(nng_http_handler_alloc_directory(&h, "/docs", sd.workdir));
+ NUTS_PASS(nng_http_handler_directory(&h, "/docs", sd.workdir));
server_setup(&st, h);
NUTS_PASS(nng_http_set_uri(st.conn, "/docs/subdir1/", NULL));
diff --git a/src/supplemental/websocket/websocket.c b/src/supplemental/websocket/websocket.c
index 86edf123..08b3a071 100644
--- a/src/supplemental/websocket/websocket.c
+++ b/src/supplemental/websocket/websocket.c
@@ -102,7 +102,7 @@ struct nni_ws_listener {
bool isstream;
bool send_text;
bool recv_text;
- nni_http_handler *handler;
+ nng_http_handler *handler;
nni_ws_listen_hook hookfn;
void *hookarg;
nni_list headers; // response headers
@@ -1403,9 +1403,8 @@ ws_init(nni_ws **wsp)
static void
ws_listener_stop(void *arg)
{
- nni_ws_listener *l = arg;
- nni_http_handler *h;
- nni_http_server *s;
+ nni_ws_listener *l = arg;
+ nni_http_server *s;
ws_listener_close(l);
@@ -1413,15 +1412,10 @@ ws_listener_stop(void *arg)
while (!nni_list_empty(&l->reply)) {
nni_cv_wait(&l->cv);
}
- h = l->handler;
- s = l->server;
- l->handler = NULL;
- l->server = NULL;
+ s = l->server;
+ l->server = NULL;
nni_mtx_unlock(&l->mtx);
- if (h != NULL) {
- nni_http_handler_fini(h);
- }
if (s != NULL) {
nni_http_server_fini(s);
}
@@ -2026,7 +2020,7 @@ nni_ws_listener_alloc(nng_stream_listener **wslp, const nng_url *url)
if (strlen(host) == 0) {
host = NULL;
}
- rv = nni_http_handler_init(&l->handler, url->u_path, ws_handler);
+ rv = nng_http_handler_alloc(&l->handler, url->u_path, ws_handler);
if (rv != 0) {
ws_listener_free(l);
return (rv);