From 58eb666f53b014c37af5b57893537a0c6f54c917 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Tue, 13 Dec 2022 14:06:18 +0000 Subject: [PATCH] Document HttpServer --- TODO.txt | 17 +---- man/man3/HttpServer.3 | 157 ++++++++++++++++++++++++++++++++++++++++++ site/index.html | 6 ++ 3 files changed, 164 insertions(+), 16 deletions(-) create mode 100644 man/man3/HttpServer.3 diff --git a/TODO.txt b/TODO.txt index aa5b562..4361b8b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -12,22 +12,7 @@ Milestone: v0.1.0 Due: January 1, 2023 --------------------- -[~] Internal API docs - [x] Array - [x] Base64 - [x] CanonicalJson - [x] HashMap - [x] Http - [ ] HttpServer - [x] Json - [x] Log - [x] Matrix - [x] Queue - [x] Routes - [x] TelodendriaConfig - [x] Util - [x] Memory - [x] Db +[ ] Release Milestone: v1.0.0 ----------------- diff --git a/man/man3/HttpServer.3 b/man/man3/HttpServer.3 new file mode 100644 index 0000000..0d48a14 --- /dev/null +++ b/man/man3/HttpServer.3 @@ -0,0 +1,157 @@ +.Dd $Mdocdate: December 13 2022 $ +.Dt HTTPSERVER 3 +.Os Telodendria Project +.Sh NAME +.Nm HttpServer +.Nd Extremely simple HTTP server. +.Sh SYNOPSIS +.In HttpServer.h +.Ft HttpServer * +.Fn HttpServerCreate "unsigned short" "unsigned int" "unsigned int" "HttpHandler *" "void *" +.Ft void +.Fn HttpServerFree "HttpServer *" +.Ft int +.Fn HttpServerStart "HttpServer *" +.Ft void +.Fn HttpServerJoin "HttpServer *" +.Ft void +.Fn HttpServerStop "HttpServer *" +.Ft HashMap * +.Fn HttpRequestHeaders "HttpServerContext *" +.Ft HttpRequestMethod +.Fn HttpRequestMethodGet "HttpServerContext *" +.Ft char * +.Fn HttpRequestPath "HttpServerContext *" +.Ft HashMap * +.Fn HttpRequestParams "HttpServerContext *" +.Ft char * +.Fn HttpResponseHeader "HttpServerContext *" "char *" "char *" +.Ft void +.Fn HttpResponseStatus "HttpServerContext *" HttpStatus" +.Ft FILE * +.Fn HttpStream "HttpServerContext *" +.Ft void +.Fn HttpSendHeaders "HttpServerContext *" +.Sh DESCRIPTION +.Nm +builds on the +.Xr Http 3 +API, and provides a very simple, yet very functional API for +creating an HTTP server. It aims at being easy to use and minimal, +yet also efficient. It uses non-blocking I/O, is fully multi-threaded, +very configurable, yet also able to be set up in just two function calls. +.Pp +This API should be familiar to those that have dealt with the HTTP server +libraries of other programming languages, particularly Java. In fact, +much of the terminology used in this code came from Java, and you'll +notice that the way responses are sent and received very closely resemble +the way it's done in Java. +.Pp +An HTTP server itself is created with +.Fn HttpServerCreate , +which takes the port number to create the server on, the number of threads to +use, the maximum number of connections, a request handler function, and the +arguments to that function, in that order. The request handler function is +of the following type: +.Bd -literal -offset indent +typedef void (HttpHandler) (HttpServerContext *, void *) +.Ed +.Pp +Where the void pointer received is the same pointer that was passed into +.Fn HttpServerCreate +as the last parameter. +.Pp +The returned HttpServer pointer is then managed by +.Fn HttpServerStart , +.Fn HttpServerStop , +.Fn HttpServerJoin , +and +.Fn HttpServerFree . +.Fn HttpServerStart +attempts to start the HTTP server, and returns immediately with the status. +This API is fully threaded and asyncronous, so the caller can continue working +while the HTTP server is running in a separate thread, and managing a pool +of threads to handle responses. Typically at some point after calling +.Fn HttpServerStart , +the program will have no more work to do, and so it will want to wait for +the HTTP server to finish. This is accomplished with +.Fn HttpServerJoin , +which joins the HTTP worker thread to the calling thread, making the +calling thread wait until the HTTP server has stopped. +.Pp +The only condition that will cause the HTTP server to stop is when +.Fn HttpServerStop +is invoked. This will typically happen in a signal handler that catches +signals instructing the program to shut down. Only after the server has +been stopped can it be freed with +.Fn HttpServerFree . +Note that calling +.Fn HttpServerFree +while the server is running results in undefined behavior. +.Pp +The remainder of the functions in this API are used inside of the +HTTP handler function passed by the caller of +.Fn HttpServerCreate . +They allow the handler to figure out the context of an HTTP request, +which includes the path that was requested, any parameters, and the +headers used to make the request. They also allow the handler +to respond with a status code, headers, and a body. +.Pp +.Fn HttpRequestHeaders , +.Fn HttpRequestMethodGet , +.Fn HttpRequestPath , +and +.Fn HttpRequestParams +get the information about the request. They should all be passed the +server context pointer that was passed into the handler function. +The data returned by these functions should be treated as read-only, +and should not be freed; their memory is handled outside of the HTTP +server handler function. +.Pp +.Fn HttpResponseHeader +and +.Fn HttpResponseStatus +are used to set response headers, and the response status of the +request, respectively. +.Pp +.Fn HttpStream +returns a stream that is both readable and writable. Reading from +the stream reads the request body that the client sent, if there is +one. Note that the request headers have already been read, so the stream +is correctly positioned at the beginning of the body of the request. +.Fn HttpSendHeaders +must be called before the stream is written to, otherwise a malformed +HTTP response will be sent. An HTTP handler should properly set all +the headers it intends to send, send those headers, and then write the +response body to the stream. Finally, note that the stream does not +need to be closed by the HTTP handler; in fact, doing so results in +undefined behavior. The stream is managed by the server itself. +.Sh RETURN VALUES +.Pp +.Fn HttpRequestHeaders +and +.Fn HttpRequestParams +return a hash map that can be used to access the request headers and +parameters, if necessary. Note that the request parameters would be +GET parameters, attached to the path that was requested. To get POST +parameters, read the stream returned by +.Fn HttpStream +and pass the contents into +.Fn HttpParamDecode +to get a hash map. +.Pp +.Fn HttpRequestPath +returns a string that represents the path that the client requested. Note +that it is not normalized; it is exactly what the client sent, so it should +be checked for path traversal attacks and other malformed paths that the +client may sent. +.Pp +.Fn HttpResponseHeader +returns the previous value of the given header, or NULL if there was no +previous value. +.Pp +.Fn HttpStream +returns a FILE pointer that can be read and written using the C standard +I/O functions. +.Sh SEE ALSO +.Xr Http 3 diff --git a/site/index.html b/site/index.html index 737cc19..bda2a2b 100644 --- a/site/index.html +++ b/site/index.html @@ -268,6 +268,12 @@ Matrix API endpoint abstractions. Encode and decode various parts of the HTTP protocol. + +HttpServer(3) + +Extremely simple HTTP server. + +

Resources