Overview
38-Moths
- Macros
-
Type Definitions
- Enums
- Structures
-
Functions
- m38_get_header_value_raw
- m38_get_header_value_raw
- m38_parse_request
- m38_mmap_file
- m38_render_file
- m38_heap_cleanup
- m38_mmap_cleanup
- m38_generate_response
- m38_send_response
- gshkl_init_context
- gshkl_free_context
- gshkl_add_string
- gshkl_add_int
- gshkl_add_array
- gshkl_add_string_to_loop
- gshkl_add_int_to_loop
- gshkl_add_sub_context_to_loop
- gshkl_add_sub_context
- gshkl_add_filter
- gshkl_filter_cleanup
- endswith
- strnstr
- get_file_creation_date
- get_file_size
- vector_new
- vector_append
- vector_append_ptr
- vector_get
- vector_reverse
- vector_free
38-Moths
Macros ¶
VERSION ¶
#define VERSION "0.2"
The current version of the 38-Moths.
MAX_READ_LEN ¶
#define MAX_READ_LEN 1024
The maximum amount of bytes to be read when receiving a request.
VERB_SIZE ¶
#define VERB_SIZE 16
The maximum size of an HTTP verb.
MAX_MATCHES ¶
#define MAX_MATCHES 4
The maximum number of matches one can have on a given url.
RESPONSE_OK ¶
#define RESPONSE_OK(status_code) (status_code >= 200 && status_code < 400)
Macro used to check whether a status code is 'good'.
WISDOM_OF_WORDS ¶
#define WISDOM_OF_WORDS 32
The maximum size of a greshunkel variable name.
MAX_GSHKL_STR_SIZE ¶
#define MAX_GSHKL_STR_SIZE 512
The maximum size of a greshunkel string.
INT_LEN(x) ¶
#define INT_LEN(x) x == 0 ? 1 : floor(log10(abs(x))) + 1
Returns the length of an integer if it were rendered as a string.
UINT_LEN(x) ¶
#define UINT_LEN(x) x == 0 ? 1 : floor(log10(x)) + 1
Returns the length of an unsigned integer if it were rendered as a string.
UNUSED(x) ¶
#define UNUSED(x) (void)x
If an argument is unused, use this to avoid compiler warnings. Use with care.
HASH_STR_SIZE ¶
#define HASH_STR_SIZE 65
The length of a 64-character hash string + NULL terminator. Used for the fnv1a function.
Type Definitions ¶
Enums ¶
greshunkel_type ¶
typedef enum {
GSHKL_ARR,
GSHKL_STR,
GSHKL_SUBCTEXT
} greshunkel_type;
Used to tell greshunkel_var
s apart.
GSHKL_ARR: A greshunkel array.
GSHKL_STR: A greshunkel string.
Structures ¶
m38_http_request ¶
typedef struct {
char verb[VERB_SIZE];
char resource[512];
regmatch_t matches[MAX_MATCHES];
char *full_header;
size_t header_len;
unsigned char *full_body;
size_t body_len;
} m38_http_request;
A representation of an HTTP request object. This will be passed to views.
verb: The HTTP verb for the given request.
resource[128]: The path for this request. (eg. '/articles/182')
matches: Any REGEX matches from your path are stored here.
header_len: The length of the header, or 0.
full_header: The full header text of the request.
body_len: The length of the POST body, or 0.
full_body: The full body.
m38_http_response ¶
typedef struct {
unsigned char *out;
size_t outsize;
char mimetype[32];
void *extra_data;
struct vector *extra_headers;
} m38_http_response;
Fill this out and return it, signed by your parents. Only *out
and outsize
are really necessary.
*out: A buffer of characters that will be written back to the requester.
outsize: The size of out
.
mimetype[32]: Optional, will be inferred from the m38_http_request's file extension if left blank.
*extra_data: Optional, use this to pass things to the clean up function. For instance, mmap_file() uses extra_data
to store the size of the file allocated.
*extra_headers: A vector containing extra headers. Use `insert_custom_header` to manage this parameter.
m38_header_pair ¶
typedef struct {
const char *header;
const size_t header_len;
const char *value;
const size_t value_len;
} m38_header_pair;
Object used to hold extra header information in an m38_http_request object.
*header: The actual header, eg. "Content-Length"
header_len: Length of the header, in bytes.
*value: The value of the header, eg. "1762"
value_len: Length of the value, in bytes.
m38_route ¶
typedef struct {
char verb[VERB_SIZE];
char name[64];
char route_match[256];
size_t expected_matches;
int (*handler)(const m38_http_request *request, m38_http_response *response);
void (*cleanup)(const int status_code, m38_http_response *response);
} m38_route;
An array of these is how 38-Moths knows how to route requests.
verb[VERB_SIZE]: The verb that this route will handle.
name[64]: The name of the route. Used only logging.
route_match[256]: The POSIX regular expression used to match the route to your handler.
(*handler): A function pointer to your route handler.
(*cleanup): If your route needs to do any cleanup (eg. de-allocating memory), this function will becalled when 38-Moths is done with it.
greshunkel_ctext ¶
typedef struct greshunkel_ctext {
vector *values;
vector *filter_functions;
const struct greshunkel_ctext *parent;
} greshunkel_ctext;
The context is a collection of variables, filters and other stuff that will be used to render a file.
*values: The values stored in this context. Strings, arrays, etc.
*filter_functions: The filter functions stored in this context.
*parent: Used internally, this is used to recurse back up to the parent context if a variable is unavailable in the current one.
greshunkel_named_item ¶
typedef struct greshunkel_named_item {
char name[WISDOM_OF_WORDS];
} greshunkel_named_item;
Dirty fucking hack to have a generic baseclass-like thing for both greshunkel_tuple
and greshunkel_filter
objects.
name[WISDOM_OF_WORDS]: The name of this thing. Somehow works. C is fucking scary.
greshunkel_tuple ¶
typedef struct greshunkel_tuple {
char name[WISDOM_OF_WORDS];
const greshunkel_type type;
greshunkel_var value;
} greshunkel_tuple;
Basically the representation of a GRESHUNKEL variable inside of a context.
name[WISDOM_OF_WORDS]: The name of this thing.
type: The type of this thing.
value: The actual value of this thing.
greshunkel_filter ¶
typedef struct greshunkel_filter {
char name[WISDOM_OF_WORDS];
char *(*filter_func)(const char *argument);
void (*clean_up)(char *result);
} greshunkel_filter;
A function that can be applied during template rendering.
name[WISDOM_OF_WORDS]: The name of this thing.
*(*filter_func): Function pointer to the C function you want to have access to in the template.
(*clean_up): If your filter needs any kind of cleanup, set this to a function other than null and you can do whatever.
vector ¶
typedef struct vector {
const size_t item_size;
size_t max_size;
size_t count;
void *items;
} vector;
A simple vector object. Auto-expands and whatever.
item_size: The maximum size of each item.
max_size: Used internally to track the current vector's maximum number of elements.
count: Used internally to track the current vector's current count of items.
*items: The actual memory used for the items stored.
Functions ¶
m38_get_header_value_raw ¶
char *m38_get_header_value_request(const m38_http_request *req, const char header[static 1]);
Gets the value of `header` (eg. Content-Length) from an http_request object. Wraps get_header_value_raw.
Returns: The char string representing the header value, or NULL. Must be free'd.
m38_get_header_value_raw ¶
char *m38_get_header_value_raw(const char *request, const size_t request_siz, const char header[static 1]);
Gets the value of `header` (eg. Content-Length) from a raw http request string.
Returns: The char string representing the header value, or NULL. Must be free'd.
m38_parse_request ¶
int m38_parse_request(const unsigned char *, const size_t, m38_http_request *);
Turns a raw string buffer into an http_request object.
Returns: 0 on sucess, -1 on failure.
m38_mmap_file ¶
int m38_mmap_file(const char *file_path, m38_http_response *response);
The primary way of serving static assets in 38-Moths. mmap()'s a file into memory and writes it to the requester.
*file_path: The file to mmap().
*response: The m38_http_response
object your handler was passed.
Returns: An HTTP status code. 200 on success, 404 on not found, etc.
m38_render_file ¶
int m38_render_file(const struct greshunkel_ctext *ctext, const char *file_path, m38_http_response *response);
The easiest way to render a file with GRESHUNKEL.
*ctext: The context you want your file to have. This should contain all variables, loops, etc.
*file_path: The template to render.
*response: The m38_http_response
object your handler was passed.
Returns: An HTTP status code. 200 on success, 404 on not found, etc.
m38_heap_cleanup ¶
void m38_heap_cleanup(const int status_code, m38_http_response *response);
Simple function that free()
's memory in out
.
status_code: The status code returned from the handler.
*response: The m38_http_response
object returned from the handler.
Returns: Nothing.
m38_mmap_cleanup ¶
void m38_mmap_cleanup(const int status_code, m38_http_response *response);
The cleanup handler for mmap_file
. Expects *extradata
to be a struct stat
object.
status_code: The status code returned from the handler.
*response: The m38_http_response
object returned from the handler.
Returns: Nothing.
m38_generate_response ¶
m38_handled_request *m38_generate_response(const int accept_fd, const m38_route *all_routes, const size_t route_num_elements);
Generates and HTTP response from an accepted connection
accept_fd: The successfully accept(2)
'd file descriptor for the requester's socket.
*all_routes: The array of all routes for your application.
route_num_elements: The number of routes in *all_routes
.
Returns: A fully formatted HTTP response, NULL otherwise.
m38_send_response ¶
m38_handled_request *m38_send_response(m38_handled_request *hreq);
Takes a handled_request object rom generate_response and sends chunks of it down the wire.
*hreq: A handled_request object either from send_response or generate_response.
Returns: If there is anything left to send, an updated handled_request will be returned. NULL will be reutnred when the object has either been fully sent, or errored out.
gshkl_init_context ¶
greshunkel_ctext *gshkl_init_context();
Used to create a new, empty GRESHUNKEL context.
Returns: A new greshunkel context.
gshkl_free_context ¶
void gshkl_free_context(greshunkel_ctext *ctext);
Frees an cleans up a previously created context.
Returns: Nothing.
gshkl_add_string ¶
int gshkl_add_string(greshunkel_ctext *ctext, const char name[WISDOM_OF_WORDS], const char *value);
Adds a string with the given name to a context.
*ctext: The context to add the string to.
name[WISDOM_OF_WORDS]: The name used to reference this variable later.
*value: The NULL terminated string that will be returned later.
Returns: 0 on success, 1 otherwise.
gshkl_add_int ¶
int gshkl_add_int(greshunkel_ctext *ctext, const char name[WISDOM_OF_WORDS], const int value);
Adds an integer with the given name to a context.
*ctext: The context to add the integer to.
name[WISDOM_OF_WORDS]: The name used to reference this variable later.
value: The integer that will be added to this context.
Returns: 0 on success, 1 otherwise.
gshkl_add_array ¶
greshunkel_var gshkl_add_array(greshunkel_ctext *ctext, const char name[WISDOM_OF_WORDS]);
Creates a new array object inside of the given context.
*ctext: The context to add the array to.
name[WISDOM_OF_WORDS]: The name used to reference this variable later.
Returns: The newly created loop object.
gshkl_add_string_to_loop ¶
int gshkl_add_string_to_loop(greshunkel_var *loop, const char *value);
Adds a string to a greshunkel array.
*loop: A pointer to a loop created with gshkl_add_array
.
*value: The NULL terminated string to be added.
Returns: 0 on success, 1 otherwise.
gshkl_add_int_to_loop ¶
int gshkl_add_int_to_loop(greshunkel_var *loop, const int value);
Adds an integer to a greshunkel array.
*loop: A pointer to a loop created with gshkl_add_array
.
value: The integer to be added.
Returns: 0 on success, 1 otherwise.
gshkl_add_sub_context_to_loop ¶
int gshkl_add_sub_context_to_loop(greshunkel_var *loop, const greshunkel_ctext *child);
Adds a name sub-context to a loop.
*loop: The loop to add the context to.
*child: The pre-built child context.
Returns: 0 on success, 1 otherwise.
gshkl_add_sub_context ¶
int gshkl_add_sub_context(greshunkel_ctext *parent, const char name[WISDOM_OF_WORDS], const greshunkel_ctext *child);
Adds a name sub-context to a parent context. Sub-context values can be references via the '
*parent: The parent context to add the child to.
name: The name of the child context.
*child: The pre-built child context.
Returns: 0 on success, 1 otherwise.
gshkl_add_filter ¶
int gshkl_add_filter(greshunkel_ctext *ctext,
const char name[WISDOM_OF_WORDS],
char *(*filter_func)(const char *argument),
void (*clean_up)(char *filter_result));
Adds a filter function to the given context.
*ctext: The context that the filter will be added to.
name[WISDOM_OF_WORDS]: The name used to reference this filter function.
(*filter_func): The function that will be called from the template.
(*clean_up): The clean up function that will be called after GRESHUNKEL is done calling filter_func
.
Returns: 0 on success, 1 otherwise.
gshkl_filter_cleanup ¶
void gshkl_filter_cleanup(char *result);
Commonly used helper clean-up function that just calls free on the result.
*result: The value obtained from calling your filter function.
Returns: Nothing.
endswith ¶
int endswith(const char *string, const char *suffix);
Helper function determine if a string ends with another string.
*string: The source string to test.
*suffix: The suffix to check for.
Returns: 1 if string
ends with suffix
.
strnstr ¶
char *strnstr(const char *haystack, const char *needle, size_t len);
Like strstr, but only checks up to n chars.
*haystack: Go look at strstr().
*needle: Go look at strstr().
len: Maximum number of characters to look through.
Returns: Whatever the hell strstr() returns.
get_file_creation_date ¶
time_t get_file_creation_date(const char *file_path);
Gets the file creation date.
*file_path: The path of the file to get the creation date of.
Returns: The file creation date.
get_file_size ¶
size_t get_file_size(const char *file_path);
Gets the file size.
*file_path: The path of the file to get the size of.
Returns: The file size.
vector_new ¶
vector *vector_new(const size_t item_size, const size_t initial_element_count);
Creates a new vector object.
item_size: The maximum size of each item.
initial_element_count: If you know your amount of objects ahead of time, set this accordingly. Otherwise just guess. The closer you get the fewer mallocs will happen.
Returns: A new vector object.
vector_append ¶
int vector_append(vector *vec, const void *item, const size_t item_size);
Adds a new element to a vector.
*vec: The vector to add the new item to.
*item: The item to add to the vector.
item_size: The size of the item to be added.
Returns: 1 on success.
vector_append_ptr ¶
int vector_append_ptr(vector *vec, const void *pointer);
Similar to vector_append but copies just the pointer value, not what it points to.
*vec: The vector to add the pointer to.
*pointer: The item to add to the vector.
Returns: 1 on success.
vector_get ¶
const void *vector_get(const vector *vec, const unsigned int i);
Gets the nth element of the given vector.
*vec: The vector to get the item from.
i: The item you want to retrieve.
Returns: A constant pointer to the nth item in the vector.
vector_reverse ¶
int vector_reverse(vector *vec);
Reverses the vector, from beginning to end.
*vec: The vector to be reversed.
Returns: 1 on success.
vector_free ¶
void vector_free(vector *to_free);
Cleans up and removes a vector's allocated memory.
*to_free: The vector to free.
Returns: Nothing.