aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doxyfile11
-rw-r--r--LICENSE (renamed from license)0
-rw-r--r--Makefile71
-rw-r--r--README34
-rw-r--r--examples/Makefile43
-rw-r--r--include/magi/cgi.h14
-rw-r--r--include/magi/cookie.h44
-rw-r--r--include/magi/error.h5
-rw-r--r--include/magi/fastcgi.h5
-rw-r--r--include/magi/file.h40
-rw-r--r--include/magi/loadfile.h49
-rw-r--r--include/magi/param.h40
-rw-r--r--include/magi/request.h67
-rw-r--r--include/magi/response.h10
-rw-r--r--include/magi/urlenc.h19
-rw-r--r--man/magi.37
-rw-r--r--readme52
17 files changed, 219 insertions, 292 deletions
diff --git a/Doxyfile b/Doxyfile
deleted file mode 100644
index df94fc8..0000000
--- a/Doxyfile
+++ /dev/null
@@ -1,11 +0,0 @@
-PROJECT_NAME = "Magi"
-PROJECT_BRIEF = "Magi Gateway Interfaces Library"
-OUTPUT_DIRECTORY = docs
-JAVADOC_AUTOBRIEF = YES
-INLINE_SIMPLE_STRUCTS = YES
-OPTIMIZE_OUTPUT_FOR_C = YES
-TYPEDEF_HIDES_STRUCT = YES
-INPUT = include/magi
-STRIP_FROM_PATH = include/magi
-STRIP_FROM_INC_PATH = include
-GENERATE_MAN = YES
diff --git a/license b/LICENSE
index d89e508..d89e508 100644
--- a/license
+++ b/LICENSE
diff --git a/Makefile b/Makefile
index ef0a20c..fd2fc64 100644
--- a/Makefile
+++ b/Makefile
@@ -1,56 +1,89 @@
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Compilation Options
# Debug mode (allowing to debug the library via gdb):
-# DEBUG = yes
+# DEBUG = yes
+# Specify directory to store object files:
+OBJ_DIR = build
# Optional modules (remove unwanted ones):
-MODULES = cgi fastcgi loadfile urlenc
+MODULES = cgi fastcgi loadfile urlenc
+# Examples to build with 'examples' target:
+EXAMPLES = append cookie echo upload
# Specify your favourite C compiler here:
-CC = gcc
+CC = gcc
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Preparations
-LIB = libmagi.a
+LIB = libmagi.a
# Compile under the most strict conditions:
-CFLAGS = -xc -ansi -pedantic -Wall -Wextra
+CFLAGS = -xc -ansi -pedantic -Wall -Wextra
# Debug and optimisation are not compatible:
ifeq '$(DEBUG)' 'yes'
-CFLAGS += -g -O0
+CFLAGS += -g -O0
else
-CFLAGS += -O3 -static
+CFLAGS += -O3 -static
endif
# Interfacial files to compile:
-INTER = cookie error file param request response $(MODULES)
+INTER = cookie error file param request response $(MODULES)
# Object files listing:
-INC_DIR = include/magi
-SRC_DIR = src
-INTER_H = $(foreach name,$(INTER),$(INC_DIR)/$(name).h)
-INTER_C = $(foreach name,$(INTER),$(SRC_DIR)/$(name).c)
-INNER_H = $(wildcard $(SRC_DIR)/*.h)
-INNER_C = $(INNER_H:.h=.c)
-SRC = $(INTER_C) $(INNER_C)
-OBJ = $(SRC:.c=.o)
+INC_DIR = include/magi
+SRC_DIR = src
+INTER_H = $(foreach name,$(INTER),$(INC_DIR)/$(name).h)
+INTER_C = $(foreach name,$(INTER),$(SRC_DIR)/$(name).c)
+INNER_H = $(wildcard $(SRC_DIR)/*.h)
+INNER_C = $(INNER_H:.h=.c)
+SRC = $(INTER_C) $(INNER_C)
+NAMES = $(notdir $(SRC:.c=))
+OBJ = $(foreach name,$(NAMES),$(OBJ_DIR)/$(name).o)
+
+EXDIR = examples
+EXSRC = $(foreach ex,$(EXAMPLES),$(EXDIR)/$(ex).c)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Targets
+.PHONY: default clean examples
+
# 'make' produces library by default:
-default: $(LIB)
+default: $(OBJ_DIR) $(LIB)
# Cleaning means removing everything automatically produced:
clean:
- rm -f $(OBJ) $(LIB)
+ rm -rf $(OBJ_DIR) $(LIB) $(EXAMPLES) deps.mk
+
+examples: default $(EXAMPLES)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Compilation
# Compile object files from corresponding source and header:
-%.o: %.c
+$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -I $(INC_DIR) -c $< -o $@
# Packing object files into library:
$(LIB): $(OBJ)
ar rcs $@ $^
+
+# Making directory for object files:
+$(OBJ_DIR):
+ mkdir $@
+
+# Compile executables from corresponding sources and library:
+%: $(EXDIR)/%.c
+ $(CC) $(CFLAGS) -I include $< -L. -lmagi -o $@
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Dependencies
+deps.mk: $(SRC)
+ echo '' > deps.mk
+ for t in $(NAMES); do \
+ $(CC) -I $(INC_DIR) -MT $(OBJ_DIR)/$${t}.o -MM $(SRC_DIR)/$${t}.c >> $@; \
+ done
+
+ifneq (clean, $(MAKECMDGOALS))
+-include deps.mk
+endif
diff --git a/README b/README
new file mode 100644
index 0000000..a0dd498
--- /dev/null
+++ b/README
@@ -0,0 +1,34 @@
+ Description
+Magi Library (libmagi) implements Gateway Interfaces, namely CGI and FastCGI.
+
+ Overview
+Magi are free and open-source software: legal info is in the 'LICENSE' file.
+They are written in ANSI C, without any dependecies, except for C standard
+library. All source and inner header files are located in the 'src' directory.
+The 'include' directory is intended to be used in your include environment.
+Headers in it contain library interface and its description in comments.
+They are in subdirectory 'include/magi', due to their short and simple names.
+If you are not about choosing which header to include and just want everything
+to be included you can '#include <magi.h>'.
+For detailed documentation look into 'man' directory.
+
+ Compiling
+Compilation and its options are described in the Makefile.
+Running make produces libmagi.a file, which is precompiled library itself,
+ready to be statically linked into your project.
+
+ Examples
+Running 'make examples' produces executable for each example in 'examples'.
+Descriptions and details are in corresponding source files.
+
+ Usage
+magi_request handles incoming request, general workflow for CGI is to:
+1. prepare request for analysis, setup defaults via magi_request_init;
+2. analyse CGI request via magi_cgi;
+4. do your work, and response request:
+ 1. specify headers (e.g. magi_response_cookie),
+ 2. fill response body (e.g. magi_response);
+5. finally, free memory via magi_request_free.
+
+ Motivation
+Web must be fun.
diff --git a/examples/Makefile b/examples/Makefile
deleted file mode 100644
index 4bf9eac..0000000
--- a/examples/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Compilation Options
-# Debug mode (allowing to debug the examples via gdb):
-# DEBUG = yes
-# Examples to build by default:
-EXAMPLES = append cookie echo upload
-# Specify your favourite C compiler here (e.g. tcc):
-CC = gcc
-
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Preparations
-# Compile under the most strict conditions:
-CFLAGS = -xc -ansi -pedantic -Wall -Wextra
-# Debug and optimisation are not compatible:
-ifeq '$(DEBUG)' 'yes'
-CFLAGS += -g -O0
-else
-CFLAGS += -O3 -static
-endif
-
-# Including magi library headers and setting linker to use it:
-INCLUDE = -I ../include
-LFLAGS = -L.. -lmagi
-# Specify library file to set it as a prerequisite for compilation:
-MAGI = ../libmagi.a
-
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Targets
-# 'make' produces all examples by default:
-default: $(EXAMPLES)
-
-# Cleaning means removing everything automatically produced:
-clean:
- rm -f $(EXAMPLES)
-
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Compilation
-# Compile executables from corresponding sources and library:
-%: %.c $(MAGI)
- $(CC) $(CFLAGS) $(INCLUDE) $< $(LFLAGS) -o $@
diff --git a/include/magi/cgi.h b/include/magi/cgi.h
index 8a13240..0de637e 100644
--- a/include/magi/cgi.h
+++ b/include/magi/cgi.h
@@ -1,23 +1,17 @@
#ifndef MAGI_INCLUDED_CGI
#define MAGI_INCLUDED_CGI
-/** @file cgi.h
- * @brief blah...
- *
- * blah-blah...
+/* Common Gateway Interface implementation
*/
#include "request.h"
-/** Analyses non-post part of request from environment.
- * @return 1 if ok, 0 if error. */
+/* Analyses non-post part of request from environment. True if ok. */
int magi_cgi_head(magi_request *request);
-/** Complete request with post body from standard input.
- * @return 1 if ok, 0 if error. */
+/* Complete request with post body from standard input. True if ok. */
int magi_cgi_body(magi_request *request);
-/** Shortcut for analysing both head and body of request.
- * @return 1 if ok, 0 if error. */
+/* Shortcut for analysing both head and body of request. True if ok. */
int magi_cgi(magi_request *request);
diff --git a/include/magi/cookie.h b/include/magi/cookie.h
index 8e1c6fc..96e4273 100644
--- a/include/magi/cookie.h
+++ b/include/magi/cookie.h
@@ -1,48 +1,36 @@
#ifndef MAGI_INCLUDED_COOKIE
#define MAGI_INCLUDED_COOKIE
-/** @file cookie.h
- * @brief HTTP Cookie.
- *
+/* HTTP Cookie
* Described in RFC 6265.
*/
-/** HTTP Cookie. */
typedef struct magi_cookie {
- char *name; /**< Cookie name. */
- char *data; /**< Cookie value. */
- char *path; /**< Path on wich cookie is set.
- * Without '/' at the end. */
- char *domain; /**< Domain in wich cookie is set.
+ char *name; /* Cookie name. */
+ char *data; /* Cookie value. */
+ char *path; /* Path on which cookie is set. Without '/' at the end. */
+ char *domain; /* Domain in wich cookie is set.
* With dot at the begining. */
- char *max_age; /**< In seconds until discard (response only). */
+ char *max_age; /* In seconds until discard (response only). */
} magi_cookie;
-/** HTTP cookies collection.
- * Implemented as a linked list. */
+/* HTTP cookies collection, implemented as a linked list. */
typedef struct magi_cookies {
- struct magi_cookies *next; /**< Pointer to next cookies. */
- magi_cookie item; /**< Cookie on top. */
+ struct magi_cookies *next; /* Pointer to next cookies. */
+ magi_cookie item; /* Cookie on top. */
} magi_cookies;
-/** Add @p newitem to @p cookies.
- * @param[in,out] cookies to add into.
- * @param[in] newitem to add onto top of @p cookies. */
+/* Free memory used by cookies. */
+void magi_cookies_free(magi_cookies *cookies);
+
+/* Add newitem onto top of cookies. */
void magi_cookies_add(magi_cookies **cookies, magi_cookie *newitem);
-/** Get cookie from @p cookies with @p name.
- * @note Cookies in @p cookies are in reverse request order, and first cookie
- * from request is the most accurate in terms of domain and path.
- * @param[in] cookies to search in.
- * @param[in] name of needed cookie.
- * @return the last from top of @p cookies cookie with @p name,
- * null only if no such cookie. */
+/* Get last from top of cookies cookie with name, null if no such cookie.
+ * Cookies are in reversed request order, and first cookie from request is
+ * the most accurate in terms of domain and path. */
magi_cookie *magi_cookies_get(magi_cookies *cookies, const char *name);
-/** Free memory used by @p cookies.
- * @param[in,out] cookies to be destructed. */
-void magi_cookies_free(magi_cookies *cookies);
-
#endif
diff --git a/include/magi/error.h b/include/magi/error.h
index 31e2c26..e928ed2 100644
--- a/include/magi/error.h
+++ b/include/magi/error.h
@@ -1,9 +1,6 @@
#ifndef MAGI_INCLUDED_ERROR
#define MAGI_INCLUDED_ERROR
-/** @file error.h
- * @brief blah...
- *
- * blah-blah...
+/* Error codes and messages
*/
diff --git a/include/magi/fastcgi.h b/include/magi/fastcgi.h
index ee7114c..fb1f2e5 100644
--- a/include/magi/fastcgi.h
+++ b/include/magi/fastcgi.h
@@ -1,9 +1,6 @@
#ifndef MAGI_INCLUDED_FASTCGI
#define MAGI_INCLUDED_FASTCGI
-/** @file fastcgi.h
- * @brief blah...
- *
- * blah-blah...
+/* Fast CGI implementation
*/
/* * * TODO * * */
diff --git a/include/magi/file.h b/include/magi/file.h
index 1b1fb35..d4c5e98 100644
--- a/include/magi/file.h
+++ b/include/magi/file.h
@@ -1,47 +1,43 @@
#ifndef MAGI_INCLUDED_FILE
#define MAGI_INCLUDED_FILE
-/** @file file.h
- * @brief Form field of file with its parameters.
+/* Form field of file with its parameters.
*/
#include "param.h"
-/** Form field of file with its parameters. */
typedef struct magi_file {
- char *field; /**< Name of form field. */
- char *filename; /**< File name on user's computer. */
- magi_params *params; /**< Multipart params (e.g. type). */
+ char *field; /* Name of form field. */
+ char *filename; /* File name on user's computer. */
+ magi_params *params; /* Multipart params (e.g. type). */
} magi_file;
-/** Form files collection.
- * Implemented as a linked list. */
+/* Form files collection, implemented as a linked list. */
typedef struct magi_files {
- struct magi_files *next; /**< Pointer to next files. */
- magi_file item; /**< File on top. */
+ struct magi_files *next; /* Pointer to next files. */
+ magi_file item; /* File on top. */
} magi_files;
-/** Add @p newitem to @p files.
- * @param[in,out] files to add into.
- * @param[in] newitem to add onto top of @p files. */
+/* Free memory used by files. */
+void magi_files_free(magi_files *files);
+
+/* Add newitem onto top of files. */
void magi_files_add(magi_files **files, magi_file *newitem);
-/** Get file with @p name from @p files.
- * @param[in] files to search in.
- * @param[in] name of needed file.
- * @return first from top of @p files file with @p name,
- * null only if no such file. */
+/* Get first from top of files file with name, null if no such file. */
magi_file *magi_files_get(magi_files *files, const char *name);
-/** Free memory used by @p files.
- * @param[in,out] files to be destructed. */
-void magi_files_free(magi_files *files);
-
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Callback to load files while analysing request.
+ * addon_len is not null if something to add is in addon
+ * and null if file_to_add_into is ended.
+ * Files are passed sequentialy, one by one. */
typedef void (*magi_file_callback_act)(void *userdata,
magi_file *file_to_add_into,
char *addon,
int addon_len);
+
typedef struct magi_file_callback {
magi_file_callback_act act;
void *userdata;
diff --git a/include/magi/loadfile.h b/include/magi/loadfile.h
index 04e5c2c..bf3421c 100644
--- a/include/magi/loadfile.h
+++ b/include/magi/loadfile.h
@@ -1,52 +1,47 @@
#ifndef MAGI_INCLUDED_LOADFILE
#define MAGI_INCLUDED_LOADFILE
-/** @file loadfile.h
- * @brief Simple callback to load files.
+/* Simple callback to load files.
*
- * Generally satisfies task of receiving files. Fill #magi_loadfiles table
- * via #magi_loadfiles_add, specifying which file-parameter to load into which
- * path, and what are size limitations for it. When table is complete setup
- * your request to use this callback with #magi_request_setup_loadfiles.
+ * Generally satisfies task of receiving files. Fill magi_loadfiles table
+ * via magi_loadfiles_add, specifying which file-parameter to load into which
+ * path, and what are size limitations for it. When table is complete, setup
+ * your request to use this callback with magi_loadfiles_set.
*
- * @note This module is optional.
+ * This module is optional.
*/
#include "request.h"
-/** Rule of loading single file.
+/* Rule of loading single file.
* There is no need to form or edit it directly. */
typedef struct magi_loadfile {
- const char *name; /**< Form field to load file from. */
- const char *path; /**< Path to load file in. */
- int max; /**< Limit in bytes. Null means unlimited. */
+ const char *name; /* Form field to load file from. */
+ const char *path; /* Path to load file in. */
+ int max; /* Limit in bytes. Null means unlimited. */
} magi_loadfile;
-/** Table of rules for loading files.
- * Set @c count and @c files as null to initialize. */
+/* Table of rules for loading files.
+ * Set count and files as null to initialize. */
typedef struct magi_loadfiles {
- int count; /**< Size of @c files.*/
- magi_loadfile *files; /**< Dynamic array of rules to load files. */
+ int count; /* Size of files array.*/
+ magi_loadfile *files; /* Dynamic array of rules to load files. */
} magi_loadfiles;
-/** Add entity into @p table.
- * @param[in,out] table is the table to add into.
- * @param[in] name is the form field name to load file from.
- * @param[in] path to load file in.
- * @param[in] max is limit in bytes (give null to unlimit). */
+/* Free memory used by table. Request using table will become invalid. */
+void magi_loadfiles_free(magi_loadfiles *table);
+
+/* Add entity into table.
+ * Specify form field to load file from with name,
+ * wnated loaction to load file with path,
+ * and file size limit in bytes with max (pass null to unlimit). */
void magi_loadfiles_add(magi_loadfiles *table,
const char *name,
const char *path,
int max);
-/** Free memmory used by @p table.
- * @warning Request using @p table will become invalid.
- * @param[in,out] table to be destructed. */
-void magi_loadfiles_free(magi_loadfiles *table);
-/** Setup @p request to use loadfiles callback with @p table.
- * @param[in,out] request to setup using loadfiles callback.
- * @param[in] table to use in loadfiles callback. */
+/* Setup request to use loadfiles callback with table. */
void magi_loadfiles_set(magi_request *request, magi_loadfiles *table);
diff --git a/include/magi/param.h b/include/magi/param.h
index b9dbde1..589db9f 100644
--- a/include/magi/param.h
+++ b/include/magi/param.h
@@ -1,45 +1,35 @@
#ifndef MAGI_INCLUDED_PARAM
#define MAGI_INCLUDED_PARAM
-/** @file param.h
- * @brief Parameter as name-value pair.
+/* Parameter as name-value pair.
*/
-/** Parameter as name-value pair. */
typedef struct magi_param {
- char *name; /**< Cannot be null. */
- char *data; /**< Cannot be null. */
+ char *name; /* Cannot be null. */
+ char *data; /* Cannot be null. */
} magi_param;
-/** Parameters collection.
- * Implemented as a linked list. */
+/* Parameters collection, implemented as a linked list. */
typedef struct magi_params {
- struct magi_params *next; /**< Pointer to next parameters. */
- magi_param item; /**< Parameter on top. */
+ struct magi_params *next; /* Pointer to next parameters. */
+ magi_param item; /* Parameter on top. */
} magi_params;
-/** Add @p newitem to @p params.
- * @param[in,out] params to add into.
- * @param[in] newitem to add onto top of @p params. */
+/* Free memory used by params. */
+void magi_params_free(magi_params *params);
+
+/* Add newitem onto top of params. */
void magi_params_add(magi_params **params, magi_param *newitem);
-/** Set @p newitem in @p params.
- * @param[in,out] params to add into.
- * @param[in] newitem to replace item in @p params with same name
- or to add, if no param with same name is in @p params. */
+/* Set newitem in params.
+ * If param with name of newitem is in params it will be replaced with newitem,
+ * otherwise newitem will be added into the end of params. */
void magi_params_set(magi_params **params, magi_param *newitem);
-/** Get data of parameter from @p params with @p name.
- * @param[in] params to search in.
- * @param[in] name of needed parameter.
- * @return data of the first from top of @p params parameter with @p name,
- * null only if no such parameter. */
+/* Get data of the first from top of params parameter with name,
+ * null if no such parameter. */
char *magi_params_get(magi_params *params, const char *name);
-/** Free memory used by @p params.
- * @param[in,out] params to be destructed. */
-void magi_params_free(magi_params *params);
-
#endif
diff --git a/include/magi/request.h b/include/magi/request.h
index 64e688d..3d0d48a 100644
--- a/include/magi/request.h
+++ b/include/magi/request.h
@@ -1,9 +1,14 @@
#ifndef MAGI_INCLUDED_REQUEST
#define MAGI_INCLUDED_REQUEST
-/** @file request.h
- * @brief blah...
+/* Request handler
*
- * blah-blah...
+ * Can be created via magi_{gateway interface name}_head, but will have
+ * nullified POST-related fields (params & files). Reason is unlimited
+ * POST body size, with possible dependence of wanted limits from data of
+ * headers (e.g. session id from cookies, enabling some users to load more).
+ * To proceed POST use magi_{gateway interface name}_body, specifying
+ * settings if necessary.
+ * Or just use shortcut magi_{gateway interface name} to do both parts.
*/
#include "cookie.h"
#include "error.h"
@@ -11,6 +16,7 @@
#include "param.h"
+/* Limits on possibly enormous structures. Null means unlimited. */
typedef struct magi_request_limits {
int cookies;
int params_meta;
@@ -18,54 +24,55 @@ typedef struct magi_request_limits {
int params_body;
} magi_request_limits;
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /**
- * Request handler.
- *
- * Can be created via 'magi_{gateway interface name}_head', but will have
- * nullified 'POST'-related fields ('params' & 'files'). Reason is unlimited
- * 'POST' body size, with possible dependence of wanted limits from data of
- * headers (e.g. session id from cookies, enabling some users to load more).
- * To proceed 'post' use 'magi_{gateway interface name}_body', specifying
- * settings if necessary.
- *
- * Or just use shortcut 'magi_{gateway interface_name}' to do both parts. */
typedef struct magi_request {
magi_error error;
- magi_cookies *cookies;
- magi_params *meta;
- magi_params *head;
- magi_params *body;
- magi_files *files;
-
- char *document_root;
- char *method;
- int is_secure;
- char *host;
- int port;
- char *script;
- char *path;
-
- magi_file_callback callback;
+ magi_cookies *cookies; /* Passed HTTP cookies. */
+ magi_params *meta; /* Request parameters. */
+ magi_params *head; /* Form field values from URL. */
+ magi_params *body; /* Form field values from body. */
+ magi_files *files; /* Form field files metadatas. */
+
+ char *document_root; /* Server's document root (e.g. /var/www/htdocs). */
+ char *method; /* Request method (GET, HEAD, POST, etc...). */
+ int is_secure; /* Means requested via HTTPS standard port (443). */
+ char *host; /* Host name (e.g. example.com). */
+ int port; /* Port (e.g. 80 or 443). */
+ char *script; /* Script path in URL (e.g. /cgi-bin/script). */
+ char *path; /* Path requested for the script (e.g. /login). */
+ /* URL has form 'http[s]://{host}:{port}{script}{path}'. */
+
+ magi_file_callback callback; /* Callback to actually load files. */
magi_request_limits limits;
+ /* Implementation of response for this request.
+ * Especially helpful in case of FastCGI,
+ * when you can handle many requests simultaniously,
+ * and need to know how to response each of them. */
struct magi_response_implementation *response;
} magi_request;
+/* Request initialiser, setup defaults. */
void magi_request_init(magi_request *r);
+/* Free memory used by request. */
void magi_request_free(magi_request *r);
+/* Get value of meta-param with name. */
char *magi_request_meta(magi_request *r, const char *name);
+/* Get value of form field param (prioritising body) with name. */
char *magi_request_param(magi_request *r, const char *name);
+/* Get value of form field param with name from url. */
char *magi_request_urlparam(magi_request *r, const char *name);
+/* Get metadata structure of file from file field with name. */
magi_file *magi_request_file(magi_request *r, const char *name);
+/* Get value of cookie with name. */
char *magi_request_cookie(magi_request *r, const char *name);
+/* Get cookie with name. */
magi_cookie *magi_request_cookie_complex(magi_request *r, const char *name);
diff --git a/include/magi/response.h b/include/magi/response.h
index a9854d4..756e2bd 100644
--- a/include/magi/response.h
+++ b/include/magi/response.h
@@ -1,20 +1,20 @@
#ifndef MAGI_INCLUDED_RESPONSE
#define MAGI_INCLUDED_RESPONSE
-/** @file response.h
- * @brief General response functionality for magi_request.
+/* General response functionality for magi_request.
*
* There are two parts of response, namely header and body.
* You can directly dive into filling the body, since default headers are set.
* Defult content-type is XHTML, status is 200 (Ok).
*
- * @warning Use body related functions only after dealing with headers.
- * (Since storing possibly large body in memory is a bad idea,
- * all headers should be sent before anything from the body.)
+ * Use body related functions only after dealing with headers.
+ * (Since storing possibly large body in memory is a bad idea,
+ * all headers should be sent before anything from the body.)
*/
#include "request.h"
#include <stdio.h>
+/* * * TODO * * */
typedef void (*magi_response_method_head)(void *ud, magi_param *header);
typedef void (*magi_response_method_start_body)(void *ud);
typedef void (*magi_response_method_body)(void *ud, const char *data, int len);
diff --git a/include/magi/urlenc.h b/include/magi/urlenc.h
index 0eff58b..dadebe7 100644
--- a/include/magi/urlenc.h
+++ b/include/magi/urlenc.h
@@ -1,29 +1,24 @@
#ifndef MAGI_INCLUDED_URLENC
#define MAGI_INCLUDED_URLENC
-/** @file urlenc.h
- * @brief Realisation of URL-encoding.
+/* Realisation of URL-encoding.
*
- * Can be helpful in forming urls in response. Use #magi_urlenc for
- * encoding itself and #magi_urlenc_size to find what the size of code
+ * Can be helpful in forming urls in response. Use magi_urlenc for
+ * encoding itself and magi_urlenc_size to find what the size of code
* will be.
*
* RFC 3986 describes URL-encoding. Briefly it is changing every space into
* plus sign and every not alpha-numerical and not @c "~-._" character into
* percent sign followed by hexadecimal representation of given character.
*
- * @note This module is optional.
+ * This module is optional.
*/
-/** Count URL-code size for @p plain.
- * @param[in] plain is a text to count code size for.
- * @return size of URL-code of @p plain. */
+/* Count URL-code size for plain. */
int magi_urlenc_size(const char *plain);
-/** Encode @p plain to url-code @p code.
- * @warning @p code must be at least size of #magi_urlenc_size(@p plain).
- * @param[in] plain is a text to be encoded.
- * @param[out] code will be filled with URL-code of @p plain. */
+/* Encode plain to url-code code.
+ * code must be at least size of magi_urlenc_size(plain). */
void magi_urlenc(const char *plain, char *code);
diff --git a/man/magi.3 b/man/magi.3
new file mode 100644
index 0000000..f7d64b8
--- /dev/null
+++ b/man/magi.3
@@ -0,0 +1,7 @@
+.TH MAGI 3 "2020.03.14" "0.1" "Magi Library"
+.SH NAME
+magi \- ANSI C dependency-free CGI and FastCGI library
+.SH LIBRARY
+library "libmagi"
+.SH SYNOPSIS
+.In #include <magi.h>
diff --git a/readme b/readme
deleted file mode 100644
index cf90f06..0000000
--- a/readme
+++ /dev/null
@@ -1,52 +0,0 @@
- Description
-Magi Library (libmagi) implements Gateway Interfaces, namely CGI and FastCGI.
-
- Overview
-Magi are free and open-source software: legal info is in the 'license' file.
-They are written in ANSI C, without any dependecies, except for C standard
-library. All source and inner header files are located in the 'src' directory.
-The 'include' directory is intended to be used in your include environment.
-Headers in it contain library interface and its documentation in comments.
-They are in subdirectory 'include/magi', due to their short and simple names.
-If you are not about choosing which header to include and just want everything
-to be included you can '#include <magi.h>'.
-
- Compiling
-Compilation and its options are described in the 'Makefile'.
-Running 'make' produces 'libmagi.a' file, which is precompiled library itself,
-ready to be statically linked into your project.
-
- Examples
-Compilation and its options are described in the local 'examples/Makefile'.
-Running 'make' in the 'examples' directory produces 'append', 'cookie',
-'upload', and 'echo' CGI executables. Descriptions and details are in
-corresponding source files.
-
- Usage
-magi_request analyses incoming request, general workflow is to:
-1. Prepare request for analysis, setup defaults via 'magi_request_setup';
-2. Process non-post part of the CGI request via 'magi_request_cgi';
- (The division of post and non-post analysis comes from the fact that
- post body can be really huge, so you probably will want to specify
- some constraints on it, based on non-post info. For example session id
- from non-post part allowes some users (e.g. admins) to load more in post.)
-3. Process post part of the CGI request via 'magi_request_resume_cgi';
-4. Now you have the full request analysed, so do your work;
-5. And finally, free memory via 'magi_request_destroy'.
-For more see 'include/magi/request.h'.
-
-magi_response provides output capabilities. You can form the response with
-'magi_response_setup' used to setup defaults, and the following functions to
-fill in your data ('...' means 'magi_response_'):
- ...content_type: set Content Type (by default XHTML);
- ...cookie: set HTTP Cookie;
-...cookie_discard: discard HTTP Cookie;
- ...http: setup arbitarary HTTP header;
- ...add: add something to the body;
- ...add_format: add comething to the body, using format (similar to printf);
-Outputting itself can be done with 'magi_response_cgi'.
-To correctly free all occupied memory call 'magi_response_destroy'.
-For more see 'include/magi/response.h'.
-
- Motivation
-Web must be fun.