Getting and Setting CGI Cookies in C
Kristaps Dzonsons
Source Code
Setting and getting cookies with kcgi is easy. It uses the same logic as setting and getting form fields. Cookies consist of name-value pairs that we can grok from a table. I'll lead this tutorial as if we were reading a source file from top to bottom, so let's start with headers. We'll obviously need kcgi and stdint.h, which is necessary for some types found in the header file.
Next, let's define identifiers for our cookies. These will later be mapped to the cookie names and the validators for their values.
The enumeration will allow us to bound an array to COOKIE__MAX
and refer to individual buckets in the array by the
enumeration value.
I'll assume that COOKIE_STRING
is assigned 0 and COOKIE_INTEGER
, 1.
Next, connect the indices with validation functions and names.
The validation function is run by khttp_parse(3); the name is the cookie key name.
Built-in validation functions, which we'll use, are described in kvalid_string(3).
In this example, kvalid_stringne
will validate a non-empty (nil-terminated) C string, while kvalid_int
will validate a signed 64-bit integer.
Before doing any parsing, I sanitise the HTTP context. I'll let any page request pass, but will make sure our MIME type and HTTP method are sane.
Now the scaffolding is done.
What about the cookies?
To begin with, you should glance at the RFC 6265, HTTP State Management
Mechanism
, to gain an understanding of how cookies work.
You may also want to read about the HttpOnly
and
Secure flags also available.
In our application, let's just attempt to read the cookie; and if it doesn't exist, write the cookie along with the page.
If it does exist, we'll indicate that in our page.
We'll focus only on the COOKIE_STRING
cookie, and will set the cookie to be visible to the path root and expire in
an hour.
We'll use kutil_epoch2str(3) to format the date.
Headers are output using khttp_head(3), with the document body started
with khttp_body(3).
Most of the above code is just to handle the HTML5 bits, and we deliberately used the smallest possible page. (Yes, this is a valid page—validate it yourself to find out!) For any significant page, you'd want to use kcgihtml(3).
Putting all of these together: parse the HTTP context, validate it, process it, then free the resources.
The HTTP context is closed with khttp_free(3).
Note that the identifiers for the cookies, enum cookie
, are also used to identify any form input.
So if you have both form input and cookies (which is common), they can either share identifiers or use unique ones.
In other words, COOKIE__MAX
defines the size of both fieldmap
and cookiemap
, so the
validator for COOKIE_STRING
is also valid for form inputs of the same name.
For compilation, linking, and installation, see Getting Started with CGI in C.