KUTIL_URLENCODE(3) Library Functions Manual KUTIL_URLENCODE(3)

kutil_urlabs, kutil_urlpart, kutil_urlpartx, kutil_urlencode, kutil_urldecode, kutil_urldecode_inplace
URL formatting for kcgi

library “libkcgi”

#include <sys/types.h>
#include <stdarg.h>
#include <stdint.h>
#include <kcgi.h>

char *
kutil_urlabs(enum kscheme scheme, const char *host, uint16_t port, const char *path);

char *
kutil_urlpart(struct kreq *req, const char *path, const char *suffix, const char *page, ...);

char *
kutil_urlpartx(struct kreq *req, const char *path, const char *suffix, const char *page, ...);

char *
kutil_urlencode(const char *cp);

enum kcgi_err
kutil_urldecode(const char *src, char **dst);

enum kcgi_err
kutil_urldecode_inplace(char *cp);

These functions format or manipulate various parts of a URL.

The kutil_urlpart() and kutil_urlpartx() functions format the path/page.suffix part of an HTTP URL, appending a variable number of query string key-value pairs. If page is NULL, these return NULL. If path is NULL, the URL will be relative to page; otherwise, path will be followed by a path separator. The last argument must be NULL. If the suffix is NULL, it is omitted from the URL. The page, the keys, and the values are URL-encoded, but the path and the suffix are not.

kutil_urlpart() accepts a variable number of pairs of char * arguments. In each pair, the first argument is the key and the second one the corresponding value.

kutil_urlpartx() accepts a variable number of groups of three arguments each. In each group, the first argument is a char * giving the key. The second argument is an enum kattrx specifying the type of the third argument: KATTRX_STRING followed by a char * string, KATTRX_INT followed by an int64_t signed integer, or KATTRX_DOUBLE followed by a double floating-point number. If all types are KATTRX_STRING, the invocation can be shortened to kutil_urlpart().

The kutil_urlencode() function encodes a string for embedding in a URL.

The kutil_urldecode() function decodes the given string src and stores the result in the allocated string dst. If the return code is not KCGI_OK, the result is set to NULL.

The kutil_urldecode_inplace() function decodes the given string in-place. If the string is malformed, the string may be only partially decoded.

The kutil_urlabs() function assembles the URL schema://host:portpath. Unless the path is an empty string, it needs to begin with a slash. None of this is URL-encoded, so make sure to use kutil_urlpart(), kutil_urlpartx(), or just kutil_urlencode() for the sensitive parts.

The kutil_urlabs(), kutil_urlpart(), kutil_urlpartx() and kutil_urlencode() functions return newly-allocated strings that must be freed with free(3). They return NULL if allocation fails. The kutil_urlencode() function also returns NULL if cp is NULL.

Additionally the kutil_urldecode() and kutil_urldecode_inplace() functions return an error code:

Success (not an error).
Memory failure (only kutil_urldecode()).
Malformed or NULL input data.

The following creates a relative URL with path, page, suffix, and query string parts.
url = kutil_urlpart
	(NULL, "/path", "html", "page",
	 "foo", "bar", "baz", "xyzzy", NULL);
puts(url);

This will output the following URL:

/path/page.html?foo=bar&baz=xyzzy

For typed arguments, the extended form may be used. Integer and real literals must have the int64_t and double types, respectively.

url = kutil_urlpartx
	(NULL, "/path", "html", "page",
	 "foo", KATTRX_INT, (int64_t)0, NULL);
puts(url);

This outputs the following

/path/page.html?foo=0

These may be made relative to the current page by omitting the leading slash or passing NULL for the path component entirely, such as:

url1 = kutil_urlpart(NULL, "rel/path", "html", "page", NULL);
puts(url1);
url2 = kutil_urlpart(NULL, NULL, "html", "page", NULL);
puts(url2);

These output the following:

rel/path/page.html
page.html

These functions were written by Kristaps Dzonsons <kristaps@bsd.lv>.

The kutil_urlabs() function accepts scheme arguments that aren't valid in URLs.

The req argument is not used and should be removed.

March 4, 2020 OpenBSD 6.5