From 83cd2267b309fa7411acaed356f88101196bb2ad Mon Sep 17 00:00:00 2001 From: Aleksey Veresov Date: Thu, 6 Feb 2020 19:43:57 +0300 Subject: [magi] Broken to become better. --- include/magi.h | 23 ++++++++++ include/magi/cgi.h | 35 ++++++++++++++ include/magi/cookie.h | 37 +++++++++++++++ include/magi/error.h | 26 +++++++++++ include/magi/fastcgi.h | 14 ++++++ include/magi/file.h | 34 ++++++++++++++ include/magi/param.h | 33 ++++++++++++++ include/magi/request.h | 119 ++++++++++++++++++++++++++++++++++++++++++++++++ include/magi/response.h | 47 +++++++++++++++++++ include/magi/urlenc.h | 15 ++++++ 10 files changed, 383 insertions(+) create mode 100644 include/magi.h create mode 100644 include/magi/cgi.h create mode 100644 include/magi/cookie.h create mode 100644 include/magi/error.h create mode 100644 include/magi/fastcgi.h create mode 100644 include/magi/file.h create mode 100644 include/magi/param.h create mode 100644 include/magi/request.h create mode 100644 include/magi/response.h create mode 100644 include/magi/urlenc.h (limited to 'include') diff --git a/include/magi.h b/include/magi.h new file mode 100644 index 0000000..60f0cc9 --- /dev/null +++ b/include/magi.h @@ -0,0 +1,23 @@ +#ifndef MAGI_INCLUDED +#define MAGI_INCLUDED +/** @file magi.h + * @brief All headers are included here. + * + * You can include this, if you don't want to think about headers. + */ +#include "magi/cgi.h" +#include "magi/cookie.h" +#include "magi/error.h" +#include "magi/fastcgi.h" +#include "magi/file.h" +#include "magi/param.h" +#include "magi/request.h" +#include "magi/response.h" +#include "magi/urlenc.h" + + +/** @mainpage Magi Gateway Interfaces Library + */ + + +#endif diff --git a/include/magi/cgi.h b/include/magi/cgi.h new file mode 100644 index 0000000..c365f2f --- /dev/null +++ b/include/magi/cgi.h @@ -0,0 +1,35 @@ +#ifndef MAGI_INCLUDED_CGI +#define MAGI_INCLUDED_CGI +/** @file cgi.h + * @brief blah... + * + * blah-blah... + */ +#include "error.h" +#include "request.h" +#include "response.h" + + +/** @brief Analyses non-post part of request from environment. + * @return Returns null only in case of error. */ +int magi_request_cgi_head(magi_request *request); + +/** @brief Complete request with post data from standard input. + * @return Returns null only in case of error. */ +int magi_request_cgi_body(magi_request *request); + +/** @brief Shortcut for analysing both head and body of request. */ +int magi_request_cgi(magi_request *request); + + +/** @brief Sends response to standard output and destroys it. + * @return Returns null only in case of error. */ +int magi_response_cgi(magi_response *response); + + +/** @brief Sends a standard response of Bad Request error. + * @return Returns null only in case of error. */ +int magi_error_cgi(magi_error error); + + +#endif diff --git a/include/magi/cookie.h b/include/magi/cookie.h new file mode 100644 index 0000000..485b6d9 --- /dev/null +++ b/include/magi/cookie.h @@ -0,0 +1,37 @@ +#ifndef MAGI_INCLUDED_COOKIE +#define MAGI_INCLUDED_COOKIE +/** @file cookie.h + * @brief blah... + * + * blah-blah... + */ + + +typedef struct magi_cookie { + /* All pointers must be valid as 'free' arguments. */ + char *name; + char *data; + char *path; /* Without '/' at the end. */ + char *domain; /* With dot at the begining. */ + char *max_age; /* In seconds until discard, used only in response. */ +} magi_cookie; + +typedef struct magi_cookie_list { + struct magi_cookie_list *next; /* Must be valid as 'free' arguments. */ + magi_cookie item; +} magi_cookie_list; + + +/* Addition of item to top of list. Null <=> error. */ +int magi_cookie_list_add(magi_cookie_list **list, magi_cookie *item); + +/* Data of last cookie in list: cookie.name == name, returns null if no such; + * Last cookie in list is first from request, and from RFC 2109 we know that + * first cookie is the most accurate for request's domain and path. */ +char *magi_cookie_list_get(magi_cookie_list *list, const char *name); + +/* Freeing and invalidation of list. */ +void magi_cookie_list_destroy(magi_cookie_list *list); + + +#endif diff --git a/include/magi/error.h b/include/magi/error.h new file mode 100644 index 0000000..31e2c26 --- /dev/null +++ b/include/magi/error.h @@ -0,0 +1,26 @@ +#ifndef MAGI_INCLUDED_ERROR +#define MAGI_INCLUDED_ERROR +/** @file error.h + * @brief blah... + * + * blah-blah... + */ + + +typedef enum magi_error { + magi_error_none = 0, + magi_error_nobound, + magi_error_unknown, + magi_error_notype, + magi_error_length, + magi_error_memory, + magi_error_cookies, + magi_error_urlenc, + magi_error_multipart, + magi_error_limit +} magi_error; + +const char *magi_error_message(magi_error error); + + +#endif diff --git a/include/magi/fastcgi.h b/include/magi/fastcgi.h new file mode 100644 index 0000000..ee7114c --- /dev/null +++ b/include/magi/fastcgi.h @@ -0,0 +1,14 @@ +#ifndef MAGI_INCLUDED_FASTCGI +#define MAGI_INCLUDED_FASTCGI +/** @file fastcgi.h + * @brief blah... + * + * blah-blah... + */ +/* * * TODO * * */ + + +enum { magi_to_avoid_warning }; + + +#endif diff --git a/include/magi/file.h b/include/magi/file.h new file mode 100644 index 0000000..57b88f0 --- /dev/null +++ b/include/magi/file.h @@ -0,0 +1,34 @@ +#ifndef MAGI_INCLUDED_FILE +#define MAGI_INCLUDED_FILE +/** @file file.h + * @brief blah... + * + * blah-blah... + */ +#include "param.h" + + +typedef struct magi_file { + /* All pointers must be valid as 'free' arguments. */ + char *param_name; /* Name of corresponding form field */ + char *file_name; /* File name on user's computer */ + magi_param_list *params; /* Multipart params (e.g. type) */ +} magi_file; + +typedef struct magi_file_list { + struct magi_file_list *next; /* Must be valid as 'free' argument. */ + magi_file item; +} magi_file_list; + + +/* Addition of item to top of list. Null <=> error. */ +int magi_file_list_add(magi_file_list **list, magi_file *item); + +/* First node in list: node.param_name == name; else null. */ +magi_file *magi_file_list_get(magi_file_list *list, const char *name); + +/* Freeing and invalidation of list. */ +void magi_file_list_destroy(magi_file_list *list); + + +#endif diff --git a/include/magi/param.h b/include/magi/param.h new file mode 100644 index 0000000..6fd3b67 --- /dev/null +++ b/include/magi/param.h @@ -0,0 +1,33 @@ +#ifndef MAGI_INCLUDED_PARAM +#define MAGI_INCLUDED_PARAM +/** @file param.h + * @brief blah... + * + * blah-blah... + */ + + +typedef struct magi_param { + /* All pointers must be valid as 'free' arguments. */ + char *name; + char *data; +} magi_param; + +typedef struct magi_param_list { + struct magi_param_list *next; /* Must be valid as 'free' argument. */ + magi_param item; +} magi_param_list; + + +/* Addition of item to top of list. Null <=> error. */ +int magi_param_list_add(magi_param_list **list, + magi_param *item); + +/* Data of the first node in list: node.name == name; else null. */ +char *magi_param_list_get(magi_param_list *list, const char *name); + +/* Freeing and invalidation of list. */ +void magi_param_list_destroy(magi_param_list *list); + + +#endif diff --git a/include/magi/request.h b/include/magi/request.h new file mode 100644 index 0000000..b15f085 --- /dev/null +++ b/include/magi/request.h @@ -0,0 +1,119 @@ +#ifndef MAGI_INCLUDED_REQUEST +#define MAGI_INCLUDED_REQUEST +/** @file request.h + * @brief blah... + * + * blah-blah... + */ +#include "cookie.h" +#include "error.h" +#include "file.h" +#include "param.h" + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** + * @brief Request + * + * Can be created via 'magi_request_{gateway interface name}', 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_request_resume_{gateway interface name}', + * specifying settings if necessary. + * + * + * Cheatsheet on environment: + * + * Request URL: http[s]://{server_name}[:{server_port}]{uri} + * example.com 80 + * uri: {document_uri}[?{urlencode(url_params)}] + * alfar=9973&veles=on + * document_uri: {script_name}{path_info} + * /bin/script /article/magic + */ +typedef struct magi_request { + /* * * Results * * */ + /* All pointers of this section must be valid as 'free' arguments. */ + + /* Parsed */ + magi_cookie_list *cookies; + magi_param_list *http_params; /* HTTP Header parameters */ + magi_param_list *url_params; /* Paramteres from URL */ + magi_param_list *params; /* Parameters from 'post' body */ + magi_file_list *files; /* 'Post' multipart files */ + + /* Environment Shortcuts */ + char *method; /* REQUEST_METHOD */ + char *uri; /* REQUEST_URI */ + char *document_root; /* DOCUMENT_ROOT */ + char *document_uri; /* DOCUMENT_URI */ + char *script_name; /* SCRIPT_NAME */ + char *script_filename; /* SCRIPT_FILENAME */ + char *remote_addr; /* REMOTE_ADDR */ + char *remote_port; /* REMOTE_PORT */ + char *server_addr; /* SERVER_ADDR */ + char *server_name; /* SERVER_NAME */ + char *server_port; /* SERVER_PORT */ + char *server_protocol; /* SERVER_PROTOCOL */ + char *server_software; /* SERVER_COFTWARE */ + char *path_info; /* PATH_INFO */ + + /* Request Error Code */ + magi_error error; + + + /* * * Settings * * */ + + /* Callback for processing files */ + void (*file_callback)(magi_file *file, + char *addon, + int addon_len, + int is_addon_last, + void *userdata); + void *file_callback_userdata; + int file_callback_addon_max; + + /* Limits for memory used (null <=> unlimitted) */ + int cookies_max; + int url_params_max; + int http_params_max; + int params_max; +} magi_request; + + +/* Setup request with default settings. */ +void magi_request_setup(magi_request *request); + + +/* Destroys request. */ +void magi_request_destroy(magi_request *request); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Tempfiles Callback + */ +typedef struct magi_tempfile { + const char *param_name; /* Form field name, in which file is expected. */ + const char *location; /* Location to load file in. */ + int maximum; /* Null <=> unlimited. */ +} magi_tempfile; + +typedef struct magi_tempfiles { + int count; + magi_tempfile *tmps; +} magi_tempfiles; + +void magi_tempfiles_add(magi_tempfiles *tmps, + const char *name, + const char *path, + int max); + +void magi_tempfiles_destroy(magi_tempfiles *tmps); + +/* Setup request callback with files loaded into corresponding to their + * parameter names locations; paths are in magi_tempfiles struct. */ +void magi_request_setup_tempfiles(magi_request *request, + magi_tempfiles *table); + + +#endif diff --git a/include/magi/response.h b/include/magi/response.h new file mode 100644 index 0000000..18f4b63 --- /dev/null +++ b/include/magi/response.h @@ -0,0 +1,47 @@ +#ifndef MAGI_INCLUDED_RESPONSE +#define MAGI_INCLUDED_RESPONSE +/** @file response.h + * @brief General response functionality. + * + * blah-blah-blah + */ +/* TODO: rewrite in such way, that only headers are in memory. */ +#include "cookie.h" +#include "param.h" + + +typedef struct magi_response { + magi_cookie_list *cookies; + magi_param_list *http_params; + char *content_type; + char *content; + int len; + int size; +} magi_response; + + +void magi_response_setup(magi_response *response); + + +void magi_response_content_type(magi_response *response, const char *type); + +void magi_response_add(magi_response *response, const char *addon); + +void magi_response_cookie(magi_response *response, magi_cookie *cookie); + +void magi_response_cookie_easy(magi_response *response, + const char *name, + const char *value); + +void magi_response_cookie_discard(magi_response *response, + const char *name); + +void magi_response_http(magi_response *response, + const char *name, + const char *data); + + +void magi_response_destroy(magi_response *response); + + +#endif diff --git a/include/magi/urlenc.h b/include/magi/urlenc.h new file mode 100644 index 0000000..10fee1d --- /dev/null +++ b/include/magi/urlenc.h @@ -0,0 +1,15 @@ +#ifndef MAGI_INCLUDED_URLENC +#define MAGI_INCLUDED_URLENC +/** @file urlenc.h + * @brief Realisation of url-encoding. + * + * Can be helpful in forming urls in response. + */ + + +/* 'code' from urlenc must have size of at least magi_urlenc_size(plain). */ +int magi_urlenc_size(const char *plain); +void magi_urlenc(const char *plain, char *code); + + +#endif -- cgit v1.2.3