forked from lda/telodendria
Document HttpServer
This commit is contained in:
parent
aaa97f8752
commit
58eb666f53
3 changed files with 164 additions and 16 deletions
17
TODO.txt
17
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
|
||||
-----------------
|
||||
|
|
157
man/man3/HttpServer.3
Normal file
157
man/man3/HttpServer.3
Normal file
|
@ -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
|
|
@ -268,6 +268,12 @@ Matrix API endpoint abstractions.
|
|||
Encode and decode various parts of the HTTP protocol.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="man/man3/HttpServer.3.html">HttpServer(3)</a></td>
|
||||
<td>
|
||||
Extremely simple HTTP server.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</details>
|
||||
<h2 id="resources">Resources</h2>
|
||||
|
|
Loading…
Reference in a new issue