mirror of
https://github.com/bdnugget/kcgi.git
synced 2026-11-07 05:47:27 +00:00
929 lines
22 KiB
Plaintext
929 lines
22 KiB
Plaintext
.\" $Id$
|
|
.\"
|
|
.\" Copyright (c) 2014--2017 Kristaps Dzonsons <kristaps@bsd.lv>
|
|
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
|
.\"
|
|
.\" 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 KHTTP_PARSE 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm khttp_parse ,
|
|
.Nm khttp_parsex
|
|
.Nd parse a CGI instance for kcgi
|
|
.Sh LIBRARY
|
|
.Lb libkcgi
|
|
.Sh SYNOPSIS
|
|
.In sys/types.h
|
|
.In stdarg.h
|
|
.In stdint.h
|
|
.In kcgi.h
|
|
.Ft "enum kcgi_err"
|
|
.Fo khttp_parse
|
|
.Fa "struct kreq *req"
|
|
.Fa "const struct kvalid *keys"
|
|
.Fa "size_t keysz"
|
|
.Fa "const char *const *pages"
|
|
.Fa "size_t pagesz"
|
|
.Fa "size_t defpage"
|
|
.Fc
|
|
.Ft "enum kcgi_err"
|
|
.Fo khttp_parsex
|
|
.Fa "struct kreq *req"
|
|
.Fa "const struct kmimemap *suffixes"
|
|
.Fa "const char *const *mimes"
|
|
.Fa "size_t mimesz"
|
|
.Fa "const struct kvalid *keys"
|
|
.Fa "size_t keysz"
|
|
.Fa "const char *const *pages"
|
|
.Fa "size_t pagesz"
|
|
.Fa "size_t defmime"
|
|
.Fa "size_t defpage"
|
|
.Fa "void *arg"
|
|
.Fa "void (*argfree)(void *arg)"
|
|
.Fa "unsigned int debugging"
|
|
.Fa "const struct kopts *opts"
|
|
.Fc
|
|
.Vt extern const char *const kmimetypes[KMIME__MAX];
|
|
.Vt extern const char *const khttps[KHTTP__MAX];
|
|
.Vt extern const char *const kschemes[KSCHEME__MAX];
|
|
.Vt extern const char *const kmethods[KMETHOD__MAX];
|
|
.Vt extern const struct kmimemap ksuffixmap[];
|
|
.Vt extern const char *const ksuffixes[KMIME__MAX];
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Fn khttp_parse
|
|
and
|
|
.Fn khttp_parsex
|
|
functions parse and validate input and the HTTP environment
|
|
(compression, paths, MIME types, and so on).
|
|
They are the central functions in the
|
|
.Xr kcgi 3
|
|
library, parsing and validating key-value form (query string, message
|
|
body, cookie) data and opaque message bodies.
|
|
.Pp
|
|
They must be matched by
|
|
.Xr khttp_free 3
|
|
if and only if the return value is
|
|
.Dv KCGI_OK .
|
|
Otherwise, resources are internally freed.
|
|
.Pp
|
|
The collective arguments are as follows:
|
|
.Bl -tag -width Ds
|
|
.It Fa arg
|
|
A pointer to private application data.
|
|
It is not touched unless
|
|
.Fa argfree
|
|
is provided.
|
|
.It Fa argfree
|
|
Function invoked with
|
|
.Fa arg
|
|
by the child process starting to parse untrusted network data.
|
|
This makes sure that no unnecessary data is leaked into the child.
|
|
.It Fa debugging
|
|
This bit-field enables debugging of the underlying parse and/or write
|
|
routines.
|
|
It may have
|
|
.Dv KREQ_DEBUG_WRITE
|
|
for writes and
|
|
.Dv KREQ_DEBUG_READ_BODY
|
|
for the pre-parsed body.
|
|
Debugging messages to
|
|
.Xr kutil_info 3
|
|
consist of the process ID followed by
|
|
.Qq -tx
|
|
or
|
|
.Qq -rx
|
|
for writing or reading, a colon and space, then the logged data.
|
|
A newline will flush the existing line, as well reaching 80 characters.
|
|
If flushed at 80 characters and not a newline, an ellipsis will follow
|
|
the line.
|
|
The total logged bytes will be emitted at the end of all reads or
|
|
writes.
|
|
.It Fa defmime
|
|
If no MIME type is specified (that is, there's no suffix to the
|
|
page request), use this index in the
|
|
.Fa mimes
|
|
array.
|
|
.It Fa defpage
|
|
If no page was specified (e.g., the default landing page), this is
|
|
provided as the requested page index.
|
|
.It Fa keys
|
|
An optional array of input and validation fields or
|
|
.Dv NULL .
|
|
.It Fa keysz
|
|
The number of elements in
|
|
.Fa keys .
|
|
.It Fa mimesz
|
|
The number of elements in
|
|
.Fa mimes .
|
|
Also the MIME index used if no MIME type was matched.
|
|
This differs from
|
|
.Fa defmime ,
|
|
which is used if there is no MIME suffix at all.
|
|
.It Fa mimes
|
|
An array of MIME types (e.g.,
|
|
.Dq text/html ) ,
|
|
mapped into a MIME index during MIME body parsing.
|
|
This relates both to pages and input fields with a body type.
|
|
Any array should include at least
|
|
.Li text/plain ,
|
|
as this is the default content type for MIME documents.
|
|
.It Fa opts
|
|
Tunable options regarding socket buffer sizes and so on.
|
|
If set to
|
|
.Dv NULL ,
|
|
meaningful defaults are used.
|
|
.It Fa pages
|
|
An array of recognised pathnames.
|
|
When pathnames are parsed, they're matched to indices in this array.
|
|
.It Fa pagesz
|
|
The number of pages in
|
|
.Fa pages .
|
|
Also used if the requested page was not in
|
|
.Fa pages .
|
|
.It Fa req
|
|
This structure is cleared and filled with input fields and HTTP context
|
|
parsed from the CGI environment.
|
|
It is the main structure carried around in a
|
|
.Xr kcgi 3
|
|
application.
|
|
.It Fa suffixes
|
|
Define the MIME type (suffix) mapping.
|
|
.El
|
|
.Pp
|
|
The first form,
|
|
.Fn khttp_parse ,
|
|
is for applications using the system-recognised MIME types.
|
|
This should work well enough for most applications.
|
|
It is equivalent to invoking the second form,
|
|
.Fn khttp_parsex ,
|
|
as follows:
|
|
.Bd -literal -offset indent
|
|
khttp_parsex(req, ksuffixmap,
|
|
kmimetypes, KMIME__MAX, keys, keysz,
|
|
pages, pagesz, KMIME_TEXT_HTML,
|
|
defpage, NULL, NULL, 0, NULL);
|
|
.Ed
|
|
.Ss Types
|
|
A
|
|
.Vt "struct kreq"
|
|
object is filled in by
|
|
.Fn khttp_parse
|
|
and
|
|
.Fn khttp_parsex .
|
|
It consists of the following fields:
|
|
.Bl -tag -width Ds
|
|
.It Vt "void *" Ns Va arg
|
|
Private application data.
|
|
This is set during
|
|
.Fn khttp_parse .
|
|
.It Vt "enum kauth" Va auth
|
|
Type of
|
|
.Dq managed
|
|
HTTP authorisation performed by the web server according to the
|
|
.Ev AUTH_TYPE
|
|
header variable, if any.
|
|
This is
|
|
.Dv KAUTH_DIGEST
|
|
for the
|
|
.Ev AUTH_TYPE
|
|
of
|
|
.Qq digest ,
|
|
.Dv KAUTH_BASIC
|
|
for
|
|
.Qq basic ,
|
|
.Dv KAUTH_BEARER
|
|
for
|
|
.Qq bearer ,
|
|
.Dv KAUTH_UNKNOWN
|
|
for other values of
|
|
.Ev AUTH_TYPE ,
|
|
or
|
|
.Dv KAUTH_NONE
|
|
if
|
|
.Ev AUTH_TYPE
|
|
is not set.
|
|
See the
|
|
.Va rawauth
|
|
field for raw (i.e., not processed by the web server) authorisation
|
|
requests.
|
|
.It Vt "struct kpair **" Ns Va cookiemap
|
|
An array of
|
|
.Fa keysz
|
|
singly linked lists of elements of the
|
|
.Va cookies
|
|
array.
|
|
If
|
|
.Va cookie Ns -> Ns Va key
|
|
is equal to one of the entries of
|
|
.Fa keys
|
|
and
|
|
.Va cookie Ns -> Ns Va state
|
|
is
|
|
.Dv KPAIR_VALID
|
|
or
|
|
.Dv KPAIR_UNCHECKED ,
|
|
the cookie is added to the list
|
|
.Va cookiemap Ns Bq Va cookie Ns -> Ns Va keypos .
|
|
Empty lists are
|
|
.Dv NULL .
|
|
If a list contains more than one cookie,
|
|
.Va cookie Ns -> Ns Va next
|
|
points to the next cookie.
|
|
For the last cookie in a list,
|
|
.Va cookie Ns -> Ns Va next
|
|
is NULL.
|
|
.It Vt "struct kpair **" Ns Va cookienmap
|
|
Similar to
|
|
.Va cookiemap ,
|
|
except that it contains the cookies where
|
|
.Va cookie Ns -> Ns Va state
|
|
is
|
|
.Dv KPAIR_INVALID .
|
|
.It Vt "struct kpair *" Ns Va cookies
|
|
Key-value pairs read from request cookies found in the
|
|
.Ev HTTP_COOKIE
|
|
header variable, or
|
|
.Dv NULL
|
|
if
|
|
.Va cookiesz
|
|
is 0.
|
|
See
|
|
.Va fields
|
|
for key-value pairs from the request query string or message body.
|
|
.It Vt size_t Va cookiesz
|
|
The size of the
|
|
.Va cookies
|
|
array.
|
|
.It Vt "struct kpair **" Ns Va fieldmap
|
|
Similar to
|
|
.Va cookiemap ,
|
|
except that the lists contain elements of the
|
|
.Va fields
|
|
array.
|
|
.It Vt "struct kpair **" Ns Va fieldnmap
|
|
Similar to
|
|
.Va fieldmap ,
|
|
except that it contains the fields where
|
|
.Va field Ns -> Ns Va state
|
|
is
|
|
.Dv KPAIR_INVALID .
|
|
.It Vt "struct kpair *" Ns Va fields
|
|
Key-value pairs read from the
|
|
.Ev QUERY_STRING
|
|
header variable and from the message body, or
|
|
.Dv NULL
|
|
if
|
|
.Dv fieldsz
|
|
is 0.
|
|
See
|
|
.Va cookies
|
|
for key-value pairs from request cookies.
|
|
.It Vt size_t Va fieldsz
|
|
The number of elements in the
|
|
.Va fields
|
|
array.
|
|
.It Vt "char *" Ns Va fullpath
|
|
The full requested path as contained in the
|
|
.Ev PATH_INFO
|
|
header variable.
|
|
For example, requesting
|
|
.Qq https://bsd.lv/app.cgi/dir/file.html?q=v ,
|
|
where
|
|
.Qq app.cgi
|
|
is the CGI program, this value would be
|
|
.Pa /dir/file.html .
|
|
It is not guaranteed to start with a slash and it may be an empty
|
|
string.
|
|
.It Vt "char *" Ns Va host
|
|
The host name received in the
|
|
.Ev HTTP_HOST
|
|
header variable.
|
|
When using name-based virtual hosting, this is typically the virtual
|
|
host name specified by the client in the HTTP request, and it should
|
|
not be confused with the canonical DNS name of the host running the
|
|
web server.
|
|
For example, a request to
|
|
.Qq https://bsd.lv/app.cgi/file
|
|
would have a host of
|
|
.Qq bsd.lv .
|
|
If
|
|
.Ev HTTP_HOST
|
|
is not defined,
|
|
.Va host
|
|
is set to
|
|
.Qq localhost .
|
|
.It Vt "struct kdata *" Ns Va kdata
|
|
Internal data.
|
|
Should not be touched.
|
|
.It Vt "const struct kvalid *" Ns Va keys
|
|
Value passed to
|
|
.Fn khttp_parse .
|
|
.It Vt size_t Va keysz
|
|
Value passed to
|
|
.Fn khttp_parse .
|
|
.It Vt "enum kmethod" Va method
|
|
The
|
|
.Dv KMETHOD_ACL ,
|
|
.Dv KMETHOD_CONNECT ,
|
|
.Dv KMETHOD_COPY ,
|
|
.Dv KMETHOD_DELETE ,
|
|
.Dv KMETHOD_GET ,
|
|
.Dv KMETHOD_HEAD ,
|
|
.Dv KMETHOD_LOCK ,
|
|
.Dv KMETHOD_MKCALENDAR ,
|
|
.Dv KMETHOD_MKCOL ,
|
|
.Dv KMETHOD_MOVE ,
|
|
.Dv KMETHOD_OPTIONS ,
|
|
.Dv KMETHOD_POST ,
|
|
.Dv KMETHOD_PROPFIND ,
|
|
.Dv KMETHOD_PROPPATCH ,
|
|
.Dv KMETHOD_PUT ,
|
|
.Dv KMETHOD_REPORT ,
|
|
.Dv KMETHOD_TRACE ,
|
|
or
|
|
.Dv KMETHOD_UNLOCK
|
|
submission method obtained from the
|
|
.Ev REQUEST_METHOD
|
|
header variable.
|
|
If an unknown method was requested,
|
|
.Dv KMETHOD__MAX
|
|
is used.
|
|
If no method was specified, the default is
|
|
.Dv KMETHOD_GET .
|
|
.Pp
|
|
Applications will usually accept only
|
|
.Dv KMETHOD_GET
|
|
and
|
|
.Dv KMETHOD_POST ,
|
|
so be sure to emit a
|
|
.Dv KHTTP_405
|
|
status for undesired methods.
|
|
.It Vt size_t Va mime
|
|
The MIME type of the requested file as determined by its
|
|
.Pa suffix
|
|
matched to the
|
|
.Fa mimemap
|
|
map passed to
|
|
.Fn khttp_parsex
|
|
or the default
|
|
.Va kmimemap
|
|
if using
|
|
.Fn khttp_parse .
|
|
This defaults to the
|
|
.Va mimesz
|
|
value passed to
|
|
.Fn khttp_parsex
|
|
or the default
|
|
.Dv KMIME__MAX
|
|
if using
|
|
.Fn khttp_parse
|
|
when no suffix is specified or when the suffix is specified but not known.
|
|
.It Vt size_t Va page
|
|
The page index found by looking up
|
|
.Va pagename
|
|
in the
|
|
.Fa pages
|
|
array.
|
|
If
|
|
.Va pagename
|
|
is not found in
|
|
.Fa pages ,
|
|
.Fa pagesz
|
|
is used; if
|
|
.Va pagename
|
|
is empty,
|
|
.Fa defpage
|
|
is used.
|
|
.It Vt "char *" Ns Va pagename
|
|
The first component of
|
|
.Va fullpath
|
|
or an empty string if there is none.
|
|
It is compared to the elements of the
|
|
.Fa pages
|
|
array to determine which
|
|
.Va page
|
|
it corresponds to.
|
|
For example, for a
|
|
.Va fullpath
|
|
of
|
|
.Qq /dir/file.html
|
|
this component corresponds to
|
|
.Pa dir .
|
|
For
|
|
.Qq /file.html ,
|
|
it's
|
|
.Pa file .
|
|
.It Vt "char *" Ns Va path
|
|
The middle part of
|
|
.Va fullpath ,
|
|
after stripping
|
|
.Va pagename Ns /
|
|
at the beginning and
|
|
.Pf \&. Va suffix
|
|
at the end, or an empty string if there is none.
|
|
For example, if the
|
|
.Va fullpath
|
|
is
|
|
.Pa bar/baz.html ,
|
|
this component is
|
|
.Pa baz .
|
|
.It Vt "char *" Ns Va pname
|
|
The script name received in the
|
|
.Ev SCRIPT_NAME
|
|
header variable.
|
|
For example, for a request to a CGI program
|
|
.Pa /var/www/cgi-bin/app.cgi
|
|
mapped by the web server from
|
|
.Qq https://bsd.lv/app.cgi/file ,
|
|
this would be
|
|
.Pa app.cgi .
|
|
This may not reflect a file system entity and it may be an empty string.
|
|
.It Vt uint16_t Va port
|
|
The server's receiving TCP port according to the
|
|
.Ev SERVER_PORT
|
|
header variable, or 80 if that is not defined or an invalid number.
|
|
.It Vt "struct khttpauth" Va rawauth
|
|
The raw authorization request according to the
|
|
.Ev HTTP_AUTHORIZATION
|
|
header variable passed by the web server.
|
|
This is only set if the web server is not managing authorisation itself.
|
|
.It Vt "char *" Ns Va remote
|
|
The string form of the client's IPv4 or IPv6 address taken from the
|
|
.Ev REMOTE_ADDR
|
|
header variable, or
|
|
.Qq 127.0.0.1
|
|
if that is not defined.
|
|
The address format of the string is not checked.
|
|
.It Vt "struct khead *" Ns Va reqmap Ns Bq Dv KREQU__MAX
|
|
Mapping of
|
|
.Vt "enum krequ"
|
|
enumeration values to
|
|
.Va reqs
|
|
parsed from the input stream.
|
|
.It Vt "struct khead *" Ns Va reqs
|
|
List of all HTTP request headers, known via
|
|
.Vt "enum krequ"
|
|
and not known, parsed from the input stream, or
|
|
.Dv NULL
|
|
if
|
|
.Va reqsz
|
|
is 0.
|
|
.It Vt size_t Va reqsz
|
|
Number of request headers in
|
|
.Va reqs .
|
|
.It Vt "enum kscheme" Va scheme
|
|
The access scheme according to the
|
|
.Ev HTTPS
|
|
header variable, either
|
|
.Dv KSCHEME_HTTPS
|
|
if
|
|
.Ev HTTPS
|
|
is set and equal to the string
|
|
.Qq on
|
|
or
|
|
.Dv KSCHEME_HTTP
|
|
otherwise.
|
|
.It Vt "char *" Ns Va suffix
|
|
The suffix part of the last component of
|
|
.Va fullpath
|
|
or an empty string if there is none.
|
|
For example, if the
|
|
.Va fullpath
|
|
is
|
|
.Pa /bar/baz.html ,
|
|
this component is
|
|
.Pa html .
|
|
See the
|
|
.Va mime
|
|
field for the MIME type parsed from the suffix.
|
|
.El
|
|
.Pp
|
|
The application may optionally define
|
|
.Vt keys
|
|
provided to
|
|
.Fn khttp_parse
|
|
and
|
|
.Fn khttp_parsex
|
|
as an array of
|
|
.Vt "struct kvalid" .
|
|
This structure is central to the validation of input data.
|
|
It consists of the following fields:
|
|
.Bl -tag -width Ds
|
|
.It Vt "const char *" Ns Va name
|
|
The field name, i.e., how it appears in the HTML form input name.
|
|
This cannot be
|
|
.Dv NULL .
|
|
If the field name is an empty string and the HTTP message consists of an
|
|
opaque body (and not key-value pairs), then that field will be used to
|
|
validate the HTTP message body.
|
|
This is useful for
|
|
.Dv KMETHOD_PUT
|
|
style requests.
|
|
.It Vt "int (*)(struct kpair *)" Va valid
|
|
A validation function returning non-zero if parsing and validation
|
|
succeed or 0 otherwise.
|
|
If it is
|
|
.Dv NULL ,
|
|
then no validation is performed, the data is considered as valid,
|
|
and it is bucketed into
|
|
.Va cookiemap
|
|
or
|
|
.Va fieldmap
|
|
as such.
|
|
.Pp
|
|
User-defined
|
|
.Fa valid
|
|
functions usually set the
|
|
.Va type
|
|
and
|
|
.Va parsed
|
|
fields in the key-value pair.
|
|
When working with binary data or with a key that can take different
|
|
data types, it is acceptable for a validation function to set the
|
|
.Va type
|
|
to
|
|
.Dv KPAIR__MAX
|
|
and for the application to ignore the
|
|
.Va parsed
|
|
field and to work directly with
|
|
.Va val
|
|
and
|
|
.Va valsz .
|
|
.Pp
|
|
The validation function is allowed to allocate new memory for
|
|
.Va val :
|
|
if the
|
|
.Va val
|
|
pointer changes during validation, the memory pointed to after validation
|
|
will be freed with
|
|
.Xr free 3
|
|
after the data is passed out of the sandbox.
|
|
.Pp
|
|
These functions are invoked from within a system-specific sandbox
|
|
that may not allow some system calls, for example opening files or
|
|
sockets.
|
|
In other words, validation functions should only do pure computation.
|
|
.El
|
|
.Pp
|
|
The
|
|
.Vt "struct kpair"
|
|
structure presents the user with fields parsed from input and (possibly)
|
|
matched to the
|
|
.Fa keys
|
|
variable passed to
|
|
.Fn khttp_parse
|
|
and
|
|
.Fn khttp_parsex .
|
|
It is also passed to the validation function to be filled in.
|
|
In this case, the MIME-related fields are already filled in and may be
|
|
examined to determine the method of validation.
|
|
This is useful when validating opaque message bodies.
|
|
.Bl -tag -width Ds
|
|
.It Vt "char *" Ns Va ctype
|
|
The value's MIME content type (e.g.,
|
|
.Li image/jpeg ) ,
|
|
or
|
|
an empty string if not defined.
|
|
.It Vt "size_t" Va ctypepos
|
|
If
|
|
.Va ctype
|
|
is not
|
|
.Dv NULL ,
|
|
it is looked up in the
|
|
.Fa mimes
|
|
parameter passed to
|
|
.Fn khttp_parsex
|
|
or
|
|
.Va ksuffixmap
|
|
if using
|
|
.Fn khttp_parse .
|
|
If found, it is set to the appropriate index.
|
|
Otherwise, it's
|
|
.Fa mimesz .
|
|
.It Vt "char *" Ns Va file
|
|
The value's MIME source filename or
|
|
an empty string
|
|
if not defined.
|
|
.It Vt "char *" Ns Va key
|
|
The NUL-terminated key (input) name.
|
|
If the HTTP message body is opaque (e.g.,
|
|
.Dv KMETHOD_PUT ) ,
|
|
then an empty-string key is cooked up.
|
|
The key may contain an arbitrary sequence of non-NUL bytes, even
|
|
non-ASCII bytes, control characters, and shell metacharacters.
|
|
.It Vt "size_t" Va keypos
|
|
If found in the
|
|
.Fa keys
|
|
array passed to
|
|
.Fn khttp_parse ,
|
|
the index of the matching key.
|
|
Otherwise
|
|
.Fa keysz .
|
|
.It Vt "struct kpair *" Ns Va next
|
|
In a cookie or field map,
|
|
.Fa next
|
|
points to the next parsed key-value pair with the same
|
|
.Fa key
|
|
name.
|
|
This occurs most often in HTML checkbox forms, where many fields may
|
|
have the same name.
|
|
.It Vt "union parsed" Va parsed
|
|
The parsed, validated value.
|
|
These may be integer in
|
|
.Va i ,
|
|
for a 64-bit signed integer; a string
|
|
.Va s ,
|
|
for a NUL-termianted character string; or a double
|
|
.Va d ,
|
|
for a double-precision floating-point number.
|
|
This is intentionally basic because the resulting data must be reliably
|
|
passed from the parsing context back into the web application.
|
|
.It Vt "enum kpairstate" Va state
|
|
The validation state:
|
|
.Dv KPAIR_VALID
|
|
if the pair was successfully validated by a validation function,
|
|
.Dv KPAIR_INVALID
|
|
if a validation function was invoked but failed, or
|
|
.Dv KPAIR_UNCHECKED
|
|
if no validation function is defined for this
|
|
.Va key .
|
|
.It Vt "enum kpairtype" Va type
|
|
If parsed, the type of data in
|
|
.Fa parsed ,
|
|
otherwise
|
|
.Dv KFIELD__MAX .
|
|
.It Vt "char *" Ns Va val
|
|
The (input) value, which may contain an arbitrary sequence of bytes,
|
|
even NUL bytes, non-ASCII bytes, control characters, and shell
|
|
metacharacters.
|
|
The byte following the end of the array,
|
|
.Va val Ns Va [ valsz ] ,
|
|
is always guaranteed to be NUL.
|
|
The validation function may modify the contents.
|
|
For example, for integer numbers and e-mail adresses, trailing
|
|
whitespace may be replaced with NUL bytes.
|
|
.It Vt "size_t" Va valsz
|
|
The length of the
|
|
.Va val
|
|
buffer in bytes.
|
|
It is not a string length.
|
|
.It Vt "char *" Ns Va xcode
|
|
The value's MIME content transfer encoding (e.g.,
|
|
.Li base64 ) ,
|
|
or an empty string if not defined.
|
|
.El
|
|
.Pp
|
|
The
|
|
.Vt struct khttpauth
|
|
structure holds authorisation data if passed by the server.
|
|
The specific fields are as follows.
|
|
.Bl -tag -width Ds
|
|
.It Vt "enum kauth" Va type
|
|
If no data was passed by the server, the
|
|
.Va type
|
|
value is
|
|
.Dv KAUTH_NONE .
|
|
Otherwise it's
|
|
.Dv KAUTH_BASIC ,
|
|
.Dv KAUTH_BEARER ,
|
|
or
|
|
.Dv KAUTH_DIGEST .
|
|
.Dv KAUTH_UNKNOWN
|
|
signals that the authorisation type was not recognised.
|
|
.It Vt "int" Va authorised
|
|
For
|
|
.Dv KAUTH_BASIC ,
|
|
.Dv KAUTH_BEARER ,
|
|
or
|
|
.Dv KAUTH_DIGEST
|
|
authorisation, this field indicates whether all required values were
|
|
specified for the application to perform authorisation.
|
|
.It Vt "char *" Ns Va digest
|
|
An MD5 digest of
|
|
.Ev REQUEST_METHOD ,
|
|
.Ev SCRIPT_NAME ,
|
|
.Ev PATH_INFO ,
|
|
header variables and the request body.
|
|
It is not a NUL-terminated string, but an array of exactly
|
|
.Dv MD5_DIGEST_LENGTH
|
|
bytes.
|
|
Only filled in when
|
|
.Ev HTTP_AUTHORIZATION
|
|
is
|
|
.Qq digest
|
|
and
|
|
.Va authorised
|
|
is non-zero.
|
|
Otherwise, it remains
|
|
.Dv NULL .
|
|
Used in
|
|
.Xr khttpdigest_validatehash 3 .
|
|
.It Va d
|
|
An anonymous union containing parsed fields per type:
|
|
.Vt "struct khttpbasic" Va basic
|
|
for
|
|
.Dv KAUTH_BASIC
|
|
or
|
|
.Dv KAUTH_BEARER ,
|
|
or
|
|
.Vt "struct khttpdigest" Va digest
|
|
for
|
|
.Dv KAUTH_DIGEST .
|
|
.El
|
|
.Pp
|
|
If the field for an HTTP authorisation request is
|
|
.Dv KAUTH_BASIC
|
|
or
|
|
.Dv KAUTH_BEARER ,
|
|
it will consist of the following for its parsed entities in its
|
|
.Vt struct khttpbasic
|
|
structure:
|
|
.Bl -tag -width Ds
|
|
.It Va response
|
|
The hashed and encoded response string for
|
|
.Dv KAUTH_BASIC ,
|
|
or an opaque string for
|
|
.Dv KAUTH_BEARER .
|
|
.El
|
|
.Pp
|
|
If the field for an HTTP authorisation request is
|
|
.Dv KAUTH_DIGEST ,
|
|
it will consist of the following in its
|
|
.Vt struct khttpdigest
|
|
structure:
|
|
.Bl -tag -width Ds
|
|
.It Va alg
|
|
The encoding algorithm, parsed from the possible
|
|
.Li MD5
|
|
or
|
|
.Li MD5-Sess
|
|
values.
|
|
.It Va qop
|
|
The quality of protection algorithm, which may be unspecified,
|
|
.Li Auth
|
|
or
|
|
.Li Auth-Init .
|
|
.It Va user
|
|
The user coordinating the request.
|
|
.It Va uri
|
|
The URI for which the request is designated.
|
|
.Pq This must match the request URI .
|
|
.It Va realm
|
|
The request realm.
|
|
.It Va nonce
|
|
The server-generated nonce value.
|
|
.It Va cnonce
|
|
The (optional) client-generated nonce value.
|
|
.It Va response
|
|
The hashed and encoded response string, which entangled fields depending
|
|
on algorithm and quality of protection.
|
|
.It Va count
|
|
The (optional)
|
|
.Va cnonce
|
|
counter.
|
|
.It Va opaque
|
|
The (optional) opaque string requested by the server.
|
|
.El
|
|
.Pp
|
|
The
|
|
.Vt struct kopts
|
|
structure consists of tunables for network performance.
|
|
You probably don't want to use these unless you really know what you're
|
|
doing!
|
|
.Bl -tag -width Ds
|
|
.It Va sndbufsz
|
|
The size of the output buffer.
|
|
The output buffer is a heap-allocated region into which writes (via
|
|
.Xr khttp_write 3
|
|
and
|
|
.Xr khttp_head 3 )
|
|
are buffered instead of being flushed directly to the wire.
|
|
The buffer is flushed when it is full, when
|
|
the HTTP headers are flushed, and when
|
|
.Xr khttp_free 3
|
|
is invoked.
|
|
If the buffer size is zero, writes are flushed immediately to the wire.
|
|
If the buffer size is less than zero, it is filled with a meaningful
|
|
default.
|
|
.El
|
|
.Pp
|
|
Lastly, the
|
|
.Vt struct khead
|
|
structure holds parsed HTTP headers.
|
|
.Bl -tag -width Ds
|
|
.It Va key
|
|
Holds the HTTP header name.
|
|
This is not the CGI header name (e.g.,
|
|
.Li HTTP_COOKIE ) ,
|
|
but the reconstituted HTTP name (e.g.,
|
|
.Li Coookie ) .
|
|
.It Va val
|
|
The opaque header value, which may be an empty string.
|
|
.El
|
|
.Ss Variables
|
|
A number of variables are defined
|
|
.In kcgi.h
|
|
to simplify invocations of the
|
|
.Fn khttp_parse
|
|
family.
|
|
Applications are strongly suggested to use these variables (and
|
|
associated enumerations) in
|
|
.Fn khttp_parse
|
|
instead of overriding them with hand-rolled sets in
|
|
.Fn khttp_parsex .
|
|
.Bl -tag -width Ds
|
|
.It Va kmimetypes
|
|
Indexed list of common MIME types, for example,
|
|
.Dq text/html
|
|
and
|
|
.Dq application/json .
|
|
Corresponds to
|
|
.Vt enum kmime
|
|
.Vt enum khttp .
|
|
.It Va khttps
|
|
Indexed list of HTTP status code and identifier, for example,
|
|
.Dq 200 OK .
|
|
Corresponds to
|
|
.Vt enum khttp .
|
|
.It Va kschemes
|
|
Indexed list of URL schemes, for example,
|
|
.Dq https
|
|
or
|
|
.Dq ftp .
|
|
Corresponds to
|
|
.Vt enum kscheme .
|
|
.It Va kmethods
|
|
Indexed list of HTTP methods, for example,
|
|
.Dq GET
|
|
and
|
|
.Dq POST .
|
|
Corresponds to
|
|
.Vt enum kmethod .
|
|
.It Va ksuffixmap
|
|
Map of MIME types defined in
|
|
.Vt enum kmime
|
|
to possible suffixes.
|
|
This array is terminated with a MIME type of
|
|
.Dv KMIME__MAX
|
|
and name
|
|
.Dv NULL .
|
|
.It Va ksuffixes
|
|
Indexed list of canonical suffixes for MIME types corresponding to
|
|
.Vt enum kmime .
|
|
This may be a
|
|
.Dv NULL
|
|
pointer for types that have no canonical suffix, for example.
|
|
.Dq application/octet-stream .
|
|
.El
|
|
.Sh RETURN VALUES
|
|
.Fn khttp_parse
|
|
and
|
|
.Fn khttp_parsex
|
|
return an error code:
|
|
.Bl -tag -width -Ds
|
|
.It Dv KCGI_OK
|
|
Success (not an error).
|
|
.It Dv KCGI_ENOMEM
|
|
Memory failure.
|
|
This can occur in many places: spawning a child, allocating memory,
|
|
creating sockets, etc.
|
|
.It Dv KCGI_ENFILE
|
|
Could not allocate file descriptors.
|
|
.It Dv KCGI_EAGAIN
|
|
Could not spawn a child.
|
|
.It Dv KCGI_FORM
|
|
Malformed data between parent and child whilst parsing an HTTP request.
|
|
(Internal system error.)
|
|
.It Dv KCGI_SYSTEM
|
|
Opaque operating system error.
|
|
.El
|
|
.Pp
|
|
On failure, the calling application should terminate as soon as possible.
|
|
Applications should
|
|
.Em not
|
|
try to write an HTTP 505 error or similar, but allow the web server to
|
|
handle the empty CGI response on its own.
|
|
.Sh SEE ALSO
|
|
.Xr kcgi 3 ,
|
|
.Xr khttp_free 3
|
|
.Sh AUTHORS
|
|
The
|
|
.Fn khttp_parse
|
|
and
|
|
.Fn khttp_parsex
|
|
functions were written by
|
|
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|