/** * Utility functions for users and internal use of the HTTP server */ #pragma once #include #include #include "httpd-types.h" // Custom helpers /// Test string equality #define streq(a, b) (strcmp((const char*)(a), (const char*)(b)) == 0) /// Test string equality, case-insensitive #define strcaseeq(a, b) (strcasecmp((const char*)(a), (const char*)(b)) == 0) /// Test string equality up to N chars #define strneq(a, b, n) (strncmp((const char*)(a), (const char*)(b), (n)) == 0) /// Test if string A starts with string B #define strstarts(a, b) strneq((a), (b), strlen((b))) /// Get nth char from the end of string (1 = last) #define last_char_n(str, n) ((str))[strlen((str)) - (n)] /// Get last char of string #define last_char(str) last_char_n((str), 1) /// The container_of macro from the linux kernel #ifndef container_of #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #endif /// Get length of a static or stack array #define array_len(a) (sizeof((a)) / sizeof((a)[0])) /** * Strstr up to N chars into the searched string * * @param str - haystack * @param substr - needle * @param n - haystack len to search * @return pointer to the matching substring or NULL */ const char *strnstr(const char *str, const char *substr, size_t n); /** * Turn a nibble (0-15) to a hex char. * * Only the bottom 4 bits are considered. * * @param val * @return hex char, uppercase */ char httpdHexNibble(uint8_t val); /** * Turn a hex char into integer * * @param c - char to convert, [0-9a-fA-F] * @return integer value 0-15 */ uint8_t httpdHexVal(char c); /** * Decode a percent-encoded value. * Takes the valLen bytes stored in val, and converts it into at most retLen bytes that * are stored in the ret buffer. Returns the actual amount of bytes used in ret. Also * zero-terminates the ret buffer. * * @param val - the encoded value * @param valLen - length of the encoded value field * @param buff - output buffer, the string will be zero-terminated * @param buffLen - output buffer size * @return Decoded len */ size_t httpdUrlDecode(const char *val, size_t valLen, char *buff, size_t buffLen); /** * Find a specific arg in a string of get- or post-data. * Line is the string of post/get-data, arg is the name of the value to find. The * zero-terminated result is written in buff, with at most buffLen bytes used. The * function returns the length of the result, or -1 if the value wasn't found. The * returned string will be urldecoded already. * * @param line - line to parse * @param arg - name of the argument to retrieve * @param[out] buff - output buffer, the string will be zero-terminated * @param buffLen - output buffer size * @return length of the result, or -1 */ int httpdFindArg(const char *line, const char *arg, char *buff, size_t buffLen); /** * Returns a static char* to a mime type for a given url to a file. * * @param url - URL or filename to parse * @return mime type string; NULL if unknown. */ const char *httpdGetMimetype(const char *url); /** * Get mimetype or default * * @param url - URL or filename to parse * @param fallback - fallback mime if none was resolved * @return mime string */ static inline const char *httpdGetMimetypeOr(const char *url, const char *fallback) { const char *mime = httpdGetMimetype(url); return mime ? mime : fallback; } /** * Turn HTTP method to text * * @param m - method enum * @return text, e.g. GET */ const char *httpdMethodName(httpd_method m); /** * Get text version of a HTTP status code * * @param code - code * @return text, e.g OK or Forbidden */ const char *httpdStatusName(int code);