mirror of
https://github.com/bdnugget/kcgi.git
synced 2026-11-07 05:47:27 +00:00
384 lines
9.7 KiB
Plaintext
384 lines
9.7 KiB
Plaintext
.\" $Id$
|
|
.\"
|
|
.\" Copyright (c) 2014, 2018 Kristaps Dzonsons <kristaps@bsd.lv>
|
|
.\"
|
|
.\" Permission to use, copy, modify, and distribute this software for any
|
|
.\" purpose with or without fee is hereby granted, provided that the above
|
|
.\" copyright notice and this permission notice appear in all copies.
|
|
.\"
|
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
.\"
|
|
.Dd $Mdocdate$
|
|
.Dt KCGI 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm kcgi
|
|
.Nd minimal CGI and FastCGI library in C
|
|
.Sh LIBRARY
|
|
.Lb libkcgi
|
|
.Sh SYNOPSIS
|
|
.In sys/types.h
|
|
.In stdarg.h
|
|
.In stdint.h
|
|
.In kcgi.h
|
|
.Fd #define KCGI_VMAJOR x
|
|
.Fd #define KCGI_VMINOR y
|
|
.Fd #define KCGI_VBUILD z
|
|
.Fd #define KCGI_VERSION "x.y.z"
|
|
.Fd #define KCGI_VSTAMP xxxyyyzzz
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm kcgi
|
|
library handles the CGI or FastCGI environment for C web applications.
|
|
Interfacing applications generally work as follows:
|
|
.Bl -enum
|
|
.It
|
|
Call
|
|
.Xr khttp_parse 3
|
|
as early as possible.
|
|
This will parse and validate input fields and cookies with the
|
|
.Xr kvalid_string 3
|
|
family of functions or those provided by the calling application.
|
|
It will do so
|
|
.Em in memory ,
|
|
so enormous requests (e.g., files) will occur entirely in memory!
|
|
It also sets up the HTTP environment: compression, paths, MIME types, and so on.
|
|
.It
|
|
Process input fields by examining the
|
|
.Vt "struct kpair"
|
|
elements.
|
|
.It
|
|
Emit HTTP headers with
|
|
.Xr khttp_head 3 ,
|
|
followed by
|
|
.Xr khttp_body 3
|
|
to begin the HTTP body.
|
|
.It
|
|
Emit HTTP body output using the
|
|
.Xr khttp_template 3
|
|
templating system, the
|
|
.Xr khttp_write 3
|
|
family for general HTTP content, and/or an external library such as
|
|
.Xr kcgihtml 3 .
|
|
.Em \&Do not
|
|
use
|
|
.Xr printf 3
|
|
or other functions to append to standard output:
|
|
.Nm kcgi
|
|
will automatically compress output if requested by the client, and
|
|
overriding the output stream will circumvent this behaviour and might
|
|
mix compressed and uncompressed data.
|
|
.It
|
|
Call
|
|
.Xr khttp_free 3
|
|
to clean up.
|
|
.El
|
|
.Pp
|
|
It can also accept FastCGI connections in a manner similar to the above,
|
|
except that the parse routine is run within a loop.
|
|
.Bl -enum
|
|
.It
|
|
Call
|
|
.Xr khttp_fcgi_init 3
|
|
as early as possible.
|
|
.It
|
|
Iterate over
|
|
.Xr khttp_fcgi_parse 3
|
|
for as many connections as desired, performing any processing on the
|
|
created request.
|
|
Each successful parse must be matched with
|
|
.Xr khttp_free 3 .
|
|
.It
|
|
Call
|
|
.Xr khttp_fcgi_free 3
|
|
when all processing is complete.
|
|
.El
|
|
.Pp
|
|
To compile applications with
|
|
.Nm ,
|
|
include the
|
|
.Pa kcgi.h
|
|
as follows:
|
|
.Bd -literal -offset indent
|
|
#include <sys/types.h> /* size_t, ssize_t */
|
|
#include <stdarg.h> /* va_list */
|
|
#include <stdint.h> /* int64_t */
|
|
#include <kcgi.h>
|
|
.Ed
|
|
.Pp
|
|
To compile and link, use
|
|
.Xr pkg-config 1 :
|
|
.Bd -literal -offset indent
|
|
% cc `pkg-config --cflags kcgi` -c -o sample.o sample.c
|
|
% cc -o sample sample.o `pkg-config --libs kcgi`
|
|
.Ed
|
|
.Pp
|
|
If the library will be statically linked (e.g., for running within a
|
|
.Xr chroot 2 ) ,
|
|
link as follows:
|
|
.Bd -literal -offset indent
|
|
% cc `pkg-config --static --cflags kcgi` -c -o sample.o sample.c
|
|
% cc -static -o sample sample.o `pkg-config --static --libs kcgi`
|
|
.Ed
|
|
.Pp
|
|
The current version of the library is defined in
|
|
.Dv KCGI_VERSION
|
|
as a string of major number, minor number, and build.
|
|
These values are available seperately as
|
|
.Dv KCGI_VMAJOR ,
|
|
.Dv KCGI_VMINOR ,
|
|
and
|
|
.Dv KCGI_VBUILD ,
|
|
respectively.
|
|
A numeric concatenation of the version is defined as
|
|
.Dv KCGI_VSTAMP ,
|
|
which may be used to test for version number applicability.
|
|
.Ss Pledge Promises
|
|
The
|
|
.Nm kcgi
|
|
library is built to operate in security-sensitive environments, including
|
|
.Xr pledge 2
|
|
on
|
|
.Ox .
|
|
The following is a list of all required promises.
|
|
.Bl -tag -width Ds
|
|
.It Va cpath wpath
|
|
.Xr kutil_openlog 3
|
|
requires file-system access to produce its log.
|
|
.It Va proc
|
|
.Xr khttp_parse 3
|
|
and
|
|
.Xr khttp_fcgi_init 3
|
|
must create child processes.
|
|
.It Va stdio
|
|
Required by essentially all
|
|
.Nm
|
|
functions.
|
|
.It Va rpath
|
|
.Xr khttp_template 3
|
|
and
|
|
.Xr khttp_templatex 3
|
|
need access to their template files.
|
|
.It Va recvfd
|
|
.Xr khttp_fcgi_init 3
|
|
needs these for inheritence by its child processes and
|
|
.Xr khttp_fcgi_parse 3
|
|
needs this for accepting the end-point descriptor for each connection.
|
|
.It Va unix sendfd
|
|
.Xr khttp_fcgi_init 3
|
|
needs these for inheritence by its child processes.
|
|
.El
|
|
.Sh EXAMPLES
|
|
The following simple example assumes that
|
|
.Pa kcgi.h
|
|
is in the compiler's include path.
|
|
None of them perform error checking: each call into the
|
|
.Nm kcgi
|
|
library should have its error code checked!
|
|
.Pp
|
|
The following does nothing but emit
|
|
.Dq Hello, world!
|
|
to the output.
|
|
.Bd -literal -offset indent
|
|
#include <sys/types.h> /* size_t, ssize_t */
|
|
#include <stdarg.h> /* va_list */
|
|
#include <stddef.h> /* NULL */
|
|
#include <stdint.h> /* int64_t */
|
|
#include <kcgi.h>
|
|
|
|
int main(void) {
|
|
struct kreq r;
|
|
const char *page = "index";
|
|
|
|
if (khttp_parse(&r, NULL, 0, &page, 1, 0) != KCGI_OK)
|
|
return 1;
|
|
|
|
khttp_head(&r, kresps[KRESP_STATUS],
|
|
"%s", khttps[KHTTP_200]);
|
|
khttp_head(&r, kresps[KRESP_CONTENT_TYPE],
|
|
"%s", kmimetypes[r.mime]);
|
|
khttp_body(&r);
|
|
khttp_puts(&r, "Hello, world!");
|
|
|
|
khttp_free(&r);
|
|
return 0;
|
|
}
|
|
.Ed
|
|
.Pp
|
|
This can be extended to work with the FastCGI interface by allowing the
|
|
request parser to operate within a loop.
|
|
.Bd -literal -offset indent
|
|
#include <sys/types.h> /* size_t, ssize_t */
|
|
#include <stdarg.h> /* va_list */
|
|
#include <stddef.h> /* NULL */
|
|
#include <stdint.h> /* int64_t */
|
|
#include <kcgi.h>
|
|
|
|
int main(void) {
|
|
struct kreq r;
|
|
struct kfcgi *fcgi;
|
|
const char *page = "index";
|
|
|
|
if (khttp_fcgi_init(&fcgi, NULL, 0, &page, 1, 0) != KCGI_OK)
|
|
return 1;
|
|
|
|
while (khttp_fcgi_parse(fcgi, &r) == KCGI_OK) {
|
|
khttp_head(&r, kresps[KRESP_STATUS],
|
|
"%s", khttps[KHTTP_200]);
|
|
khttp_head(&r, kresps[KRESP_CONTENT_TYPE],
|
|
"%s", kmimetypes[r.mime]);
|
|
khttp_body(&r);
|
|
khttp_puts(&r, "Hello, world!");
|
|
khttp_free(&r);
|
|
}
|
|
|
|
khttp_fcgi_free(fcgi);
|
|
return 0;
|
|
}
|
|
.Ed
|
|
.Pp
|
|
In a more complicated example,
|
|
.Nm
|
|
accepts a single parameter
|
|
.Dq string
|
|
to validate and display.
|
|
This might be provided as part of an HTML form or directly as part of
|
|
the URL query string.
|
|
.Bd -literal -offset indent
|
|
#include <sys/types.h> /* size_t, ssize_t */
|
|
#include <stdarg.h> /* va_list */
|
|
#include <stdint.h> /* int64_t */
|
|
#include <kcgi.h>
|
|
|
|
int main(void) {
|
|
struct kreq r;
|
|
struct kpair *p;
|
|
const char *page = "index";
|
|
struct kvalid key = { kvalid_stringne, "string" };
|
|
|
|
if (khttp_parse(&r, &key, 1, &page, 1, 0) != KCGI_OK)
|
|
return 1;
|
|
|
|
khttp_head(&r, kresps[KRESP_STATUS],
|
|
"%s", khttps[KHTTP_200]);
|
|
khttp_head(&r, kresps[KRESP_CONTENT_TYPE],
|
|
"%s", kmimetypes[r.mime]);
|
|
khttp_body(&r);
|
|
khttp_puts(&r, "Result: ");
|
|
if ((p = r.fieldmap[0]))
|
|
khttp_puts(&r, p->parsed.s);
|
|
else if (r.fieldnmap[0])
|
|
khttp_puts(&r, "bad parse");
|
|
else
|
|
khttp_puts(&r, "no value");
|
|
|
|
khttp_free(&r);
|
|
return 0;
|
|
}
|
|
.Ed
|
|
.Pp
|
|
Applications will usually specify an array of key-value pairs to
|
|
validate; or in the event of web services, a default validator (empty
|
|
string) for the full HTTP message body.
|
|
.Sh SEE ALSO
|
|
.Xr kcgi_buf_printf 3 ,
|
|
.Xr kcgi_buf_putc 3 ,
|
|
.Xr kcgi_buf_puts 3 ,
|
|
.Xr kcgi_buf_write 3 ,
|
|
.Xr kcgi_strerror 3 ,
|
|
.Xr kcgi_writer_disable 3 ,
|
|
.Xr kcgihtml 3 ,
|
|
.Xr kcgijson 3 ,
|
|
.Xr kcgiregress 3 ,
|
|
.Xr kcgixml 3 ,
|
|
.Xr khttp_body 3 ,
|
|
.Xr khttp_epoch2str 3 ,
|
|
.Xr khttp_fcgi_free 3 ,
|
|
.Xr khttp_fcgi_init 3 ,
|
|
.Xr khttp_fcgi_parse 3 ,
|
|
.Xr khttp_fcgi_test 3 ,
|
|
.Xr khttp_free 3 ,
|
|
.Xr khttp_head 3 ,
|
|
.Xr khttp_parse 3 ,
|
|
.Xr khttp_printf 3 ,
|
|
.Xr khttp_putc 3 ,
|
|
.Xr khttp_puts 3 ,
|
|
.Xr khttp_template 3 ,
|
|
.Xr khttp_templatex 3 ,
|
|
.Xr khttp_urlencode 3 ,
|
|
.Xr khttp_write 3 ,
|
|
.Xr khttpbasic_validate 3 ,
|
|
.Xr khttpdigest_validate 3 ,
|
|
.Xr kmalloc 3 ,
|
|
.Xr kutil_invalidate 3 ,
|
|
.Xr kutil_log 3 ,
|
|
.Xr kutil_openlog 3 ,
|
|
.Xr kvalid_string 3 ,
|
|
.Xr kfcgi 8
|
|
.Sh STANDARDS
|
|
Many standards are involved in the
|
|
.Nm
|
|
library, most significantly being draft RFC 3875,
|
|
.Dq The Common Gateway Interface (CGI) Version 1.1 ,
|
|
and the
|
|
.Dq FastCGI Specification ,
|
|
version 1.0, published 29 April 1996.
|
|
.Bl -bullet
|
|
.It
|
|
Cookies are parsed according to
|
|
.Dq HTTP State Management Mechanism ,
|
|
RFC 6265.
|
|
However, quoted cookies are
|
|
.Em not
|
|
supported.
|
|
.It
|
|
The
|
|
.Dq Authentication
|
|
header is parsed for digest or basic tokens as defined by RFC 2617,
|
|
.Dq HTTP Authentication: Basic and Digest Access Authentication ,
|
|
and RFC 6750,
|
|
.Dq The OAuth 2.0 Authorization Framework: Bearer Token Usage .
|
|
.It
|
|
The partial multipart form data support is defined by RFC 2388,
|
|
.Dq Returning Values from Forms: multipart/form-data ,
|
|
which is further defined by RFCs 2045 and 2046,
|
|
.Dq Multipurpose Internet Mail Extensions .
|
|
.It
|
|
MIME type names are registered with IANA.
|
|
.It
|
|
URLs are formatted according to RFC 1630,
|
|
.Dq Universal Resource Identifiers in WWW .
|
|
.It
|
|
HTTP response headers are standardised in RFC 2616,
|
|
.Dq HTTP/1.1
|
|
and further in RFC 4229,
|
|
.Dq HTTP Header Field Registrations .
|
|
.It
|
|
Permanent URI schemes are registered with IANA.
|
|
.It
|
|
The
|
|
.Lk https://kristaps.bsd.lv/kcgi/extending01.html "FastCGI Extensions for Management Control" .
|
|
.It
|
|
HTTP dates (logging and date-time management) are specified by
|
|
.Dq RFC 822 .
|
|
.It
|
|
URL encoding and decoding is defined by RFC 3986,
|
|
.Dq Uniform Resource Identifier (URI): Generic Syntax .
|
|
.El
|
|
.Pp
|
|
Additional HTTP methods are defined by RFC 4918,
|
|
.Dq HTTP Extensions for Web Distributed Authoring and Versioning ;
|
|
and RFC 4791 ,
|
|
.Dq Calendaring Extensions to WebDAV .
|
|
.Sh AUTHORS
|
|
The
|
|
.Nm
|
|
library was written by
|
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|