aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/append.c30
-rw-r--r--examples/cookie.c34
-rw-r--r--examples/echo.c22
-rw-r--r--examples/upload.c44
-rw-r--r--src/cgi.c112
-rw-r--r--src/cgi.h8
-rw-r--r--src/cookie.c147
-rw-r--r--src/cookie.h24
-rw-r--r--src/fastcgi.h21
-rw-r--r--src/field.c19
-rw-r--r--src/field.h24
-rw-r--r--src/log.c9
-rw-r--r--src/log.h2
-rw-r--r--src/multipart.c234
-rw-r--r--src/multipart.h14
-rw-r--r--src/param.c19
-rw-r--r--src/param.h20
-rw-r--r--src/request.c4
-rw-r--r--src/request.h45
-rw-r--r--src/urlencoded.c84
-rw-r--r--src/urlencoded.h2
-rw-r--r--src/utils.h62
22 files changed, 473 insertions, 507 deletions
diff --git a/examples/append.c b/examples/append.c
index b8aa1cf..b6ee217 100644
--- a/examples/append.c
+++ b/examples/append.c
@@ -8,9 +8,9 @@ void handle_request()
{
struct magi_request request;
if (magi_cgi(&request, 0, 0)) {
- struct magi_field *a = magi_field_list_get(request.fields, "addon");
+ struct magi_field * a = magi_field_list_get(request.fields, "addon");
if (a && a->data) {
- FILE *file = fopen("file_to_append", "a");
+ FILE * file = fopen("file_to_append", "a");
fputs(a->data, file);
fclose(file);
}
@@ -25,22 +25,20 @@ void print_preamble()
void print_webpage()
{
- puts(
- "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
- "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
- "<html xmlns='http://www.w3.org/1999/xhtml'>"
- "<head><title>Append to File</title></head>"
- "<body>"
- "<form action='/cgi-bin/append' method='get'><fieldset>"
- "<input type='text' name='addon' value='Whatever you want to add.'/>"
- "<input type='submit' value='Append'/>"
- "</fieldset></form>"
- "</body>"
- "</html>"
- );
+ puts("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
+ "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
+ "<html xmlns='http://www.w3.org/1999/xhtml'>"
+ "<head><title>Append to File</title></head>"
+ "<body>"
+ "<form action='/cgi-bin/append' method='get'><fieldset>"
+ "<input type='text' name='addon' value='Whatever you want to add.'/>"
+ "<input type='submit' value='Append'/>"
+ "</fieldset></form>"
+ "</body>"
+ "</html>");
}
-int main(int argc, char const *argv[])
+int main(int argc, char const * argv[])
{
handle_request();
print_preamble();
diff --git a/examples/cookie.c b/examples/cookie.c
index dd18cc6..5ef56ac 100644
--- a/examples/cookie.c
+++ b/examples/cookie.c
@@ -7,34 +7,26 @@
void print_preamble()
{
- puts(
- "Set-Cookie:cookie=monstre\r\n" /* Important to set cookies before: */
- "Content-Type: application/xhtml+xml\r\n\r\n"
- );
+ puts("Set-Cookie:cookie=monstre\r\n" /* Important to set cookies before: */
+ "Content-Type: application/xhtml+xml\r\n\r\n");
}
void print_webpage_top()
{
- puts(
- "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
- "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
- "<html xmlns='http://www.w3.org/1999/xhtml'>"
- "<head><title>Cookie Listing and Setting</title></head>"
- "<body>"
- );
+ puts("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
+ "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
+ "<html xmlns='http://www.w3.org/1999/xhtml'>"
+ "<head><title>Cookie Listing and Setting</title></head>"
+ "<body>");
}
void read_and_print_cookies()
{
struct magi_request request;
if (magi_cgi(&request, 0, 0)) {
- struct magi_cookie_list *cookie;
+ struct magi_cookie_list * cookie;
for (cookie = request.cookies; cookie; cookie = cookie->next) {
- printf(
- "[%s] = [%s]<br/>",
- cookie->item.name,
- cookie->item.data
- );
+ printf("[%s] = [%s]<br/>", cookie->item.name, cookie->item.data);
}
magi_request_destroy(&request);
}
@@ -42,13 +34,11 @@ void read_and_print_cookies()
void print_webpage_bottom()
{
- puts(
- "</body>"
- "</html>"
- );
+ puts("</body>"
+ "</html>");
}
-int main(int argc, char const *argv[])
+int main(int argc, char const * argv[])
{
print_preamble();
/* Following probably will be much more pleasant with use of templates. */
diff --git a/examples/echo.c b/examples/echo.c
index ff037a6..0345b8c 100644
--- a/examples/echo.c
+++ b/examples/echo.c
@@ -8,17 +8,15 @@
void print_preamble()
{
- puts(
- "Content-type: application/xhtml+xml\r\n\r\n"
- "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
- "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
- "<html xmlns='http://www.w3.org/1999/xhtml'>"
- "<head><title>Echo</title></head>"
- "<body>"
- );
+ puts("Content-type: application/xhtml+xml\r\n\r\n"
+ "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
+ "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
+ "<html xmlns='http://www.w3.org/1999/xhtml'>"
+ "<head><title>Echo</title></head>"
+ "<body>");
}
-void proceed_cookies(struct magi_cookie_list *cookies)
+void proceed_cookies(struct magi_cookie_list * cookies)
{
puts("<h2>Cookies:</h2>");
while (cookies) {
@@ -46,7 +44,7 @@ void proceed_cookies(struct magi_cookie_list *cookies)
puts("<hr/>");
}
-void proceed_fields(struct magi_field_list *fields)
+void proceed_fields(struct magi_field_list * fields)
{
puts("<h2>Feilds:</h2>");
while (fields) {
@@ -60,7 +58,7 @@ void proceed_fields(struct magi_field_list *fields)
puts("<hr/>");
}
-void proceed_params(struct magi_param_list *params)
+void proceed_params(struct magi_param_list * params)
{
puts("<h2>HTTP Parameters:</h2>");
while (params) {
@@ -114,7 +112,7 @@ void print_footer()
puts("</body></html>");
}
-int main(int argc, char const *argv[])
+int main(int argc, char const * argv[])
{
print_preamble();
handle_request();
diff --git a/examples/upload.c b/examples/upload.c
index 59dd020..1cf6f5f 100644
--- a/examples/upload.c
+++ b/examples/upload.c
@@ -1,13 +1,13 @@
+#include <cgi.h>
+#include <multipart.h>
+#include <request.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <request.h>
-#include <multipart.h>
-#include <cgi.h>
-void tempfile_callback(struct magi_field *field, char *buffer, int len)
+void tempfile_callback(struct magi_field * field, char * buffer, int len)
{
- static FILE *file = 0;
+ static FILE * file = 0;
if (!strcmp(field->name, "data")) {
if (!file) {
remove(field->name);
@@ -32,8 +32,8 @@ void handle_request()
{
struct magi_request request;
if (magi_cgi(&request, tempfile_callback, 0)) {
- struct magi_field *name = magi_field_list_get(request.fields, "name");
- struct magi_field *data = magi_field_list_get(request.fields, "data");
+ struct magi_field * name = magi_field_list_get(request.fields, "name");
+ struct magi_field * data = magi_field_list_get(request.fields, "data");
if (name && name->data && data) {
rename("data", name->data);
}
@@ -48,24 +48,22 @@ void print_preamble()
void print_webpage()
{
- puts(
- "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
- "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
- "<html xmlns='http://www.w3.org/1999/xhtml'>"
- "<head><title>Upload File</title></head>"
- "<body>"
- "<form action='/cgi-bin/upload' method='post' "
- "enctype='multipart/form-data'><fieldset>"
- "<input type='text' name='name' value='filename'/>"
- "<input type='file' name='data'/>"
- "<input type='submit' value='Upload'/>"
- "</fieldset></form>"
- "</body>"
- "</html>"
- );
+ puts("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
+ "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
+ "<html xmlns='http://www.w3.org/1999/xhtml'>"
+ "<head><title>Upload File</title></head>"
+ "<body>"
+ "<form action='/cgi-bin/upload' method='post' "
+ "enctype='multipart/form-data'><fieldset>"
+ "<input type='text' name='name' value='filename'/>"
+ "<input type='file' name='data'/>"
+ "<input type='submit' value='Upload'/>"
+ "</fieldset></form>"
+ "</body>"
+ "</html>");
}
-int main(int argc, char const *argv[])
+int main(int argc, char const * argv[])
{
handle_request();
print_preamble();
diff --git a/src/cgi.c b/src/cgi.c
index 1a318a1..222c2ee 100644
--- a/src/cgi.c
+++ b/src/cgi.c
@@ -12,18 +12,16 @@
#include <stdlib.h>
#include <string.h>
-
-extern char **environ;
-
+extern char ** environ;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* CGI Request Handling
*/
/* Helpers for CGI Request Handling */
-static int plain_env(char **dest, char *env_name)
+static int plain_env(char ** dest, char * env_name)
{
- int ok = 1;
- const char *env = getenv(env_name);
+ int ok = 1;
+ const char * env = getenv(env_name);
if (env) {
*dest = str_alloc(strlen(env));
if (*dest) {
@@ -37,24 +35,24 @@ static int plain_env(char **dest, char *env_name)
return ok;
}
-static int lower_env(char **dest, char *env_name)
+static int lower_env(char ** dest, char * env_name)
{
int ok = plain_env(dest, env_name);
lowercase(*dest);
return ok;
}
-static int cgi_http_env(struct magi_request *r)
+static int cgi_http_env(struct magi_request * r)
{
- int ok = 1;
- char **env = environ;
+ int ok = 1;
+ char ** env = environ;
r->http_params = 0;
while (*env) {
if (!strncmp(*env, "HTTP_", 5) && strncmp(*env, "HTTP_COOKIE=", 12)) {
struct magi_param param;
/* At least one '=' must be in *env, according to format. */
- char *name_end = strchr(*env, '=');
- param.name = str_alloc(name_end - *env - 5);
+ char * name_end = strchr(*env, '=');
+ param.name = str_alloc(name_end - *env - 5);
if (param.name) {
memcpy(param.name, *env + 5, name_end - *env - 5);
param.data = str_alloc(strlen(name_end + 1));
@@ -75,31 +73,31 @@ static int cgi_http_env(struct magi_request *r)
return ok;
}
-static int cgi_env(struct magi_request *r)
+static int cgi_env(struct magi_request * r)
{
int ok = cgi_http_env(r);
- ok = ok && lower_env(&r->method, "REQUEST_METHOD");
- ok = ok && plain_env(&r->uri, "REQUEST_URI");
- ok = ok && plain_env(&r->document_root, "DOCUMENT_ROOT");
- ok = ok && plain_env(&r->document_uri, "DOCUMENT_URI");
- ok = ok && plain_env(&r->script_name, "SCRIPT_NAME");
- ok = ok && plain_env(&r->script_filename, "SCRIPT_FILENAME");
- ok = ok && plain_env(&r->remote_addr, "REMOTE_ADDR");
- ok = ok && plain_env(&r->remote_port, "REMOTE_PORT");
- ok = ok && plain_env(&r->server_addr, "SERVER_ADDR");
- ok = ok && lower_env(&r->server_name, "SERVER_NAME");
- ok = ok && plain_env(&r->server_port, "SERVER_PORT");
- ok = ok && lower_env(&r->server_protocol, "SERVER_PROTOCOL");
- ok = ok && plain_env(&r->server_software, "SERVER_SOFTWARE");
- ok = ok && plain_env(&r->path_info, "PATH_INFO");
+ ok = ok && lower_env(&r->method, "REQUEST_METHOD");
+ ok = ok && plain_env(&r->uri, "REQUEST_URI");
+ ok = ok && plain_env(&r->document_root, "DOCUMENT_ROOT");
+ ok = ok && plain_env(&r->document_uri, "DOCUMENT_URI");
+ ok = ok && plain_env(&r->script_name, "SCRIPT_NAME");
+ ok = ok && plain_env(&r->script_filename, "SCRIPT_FILENAME");
+ ok = ok && plain_env(&r->remote_addr, "REMOTE_ADDR");
+ ok = ok && plain_env(&r->remote_port, "REMOTE_PORT");
+ ok = ok && plain_env(&r->server_addr, "SERVER_ADDR");
+ ok = ok && lower_env(&r->server_name, "SERVER_NAME");
+ ok = ok && plain_env(&r->server_port, "SERVER_PORT");
+ ok = ok && lower_env(&r->server_protocol, "SERVER_PROTOCOL");
+ ok = ok && plain_env(&r->server_software, "SERVER_SOFTWARE");
+ ok = ok && plain_env(&r->path_info, "PATH_INFO");
return ok;
}
-static int cgi_cookies(struct magi_cookie_list **list)
+static int cgi_cookies(struct magi_cookie_list ** list)
{
- int ok = 1;
- const char *env = getenv("HTTP_COOKIE");
- *list = 0;
+ int ok = 1;
+ const char * env = getenv("HTTP_COOKIE");
+ *list = 0;
if (env && *env) {
ok = magi_parse_cookie(list, env);
} else {
@@ -108,10 +106,10 @@ static int cgi_cookies(struct magi_cookie_list **list)
return ok;
}
-static int cgi_input_get(char **input)
+static int cgi_input_get(char ** input)
{
- int ok = 1;
- const char *env_input = getenv("QUERY_STRING");
+ int ok = 1;
+ const char * env_input = getenv("QUERY_STRING");
if (env_input) {
*input = str_alloc(strlen(env_input));
if (*input) {
@@ -123,7 +121,7 @@ static int cgi_input_get(char **input)
return ok;
}
-static int cgi_input_post(char **input, int max)
+static int cgi_input_post(char ** input, int max)
{
int ok = 1;
int input_len = strtoul(getenv("CONTENT_LENGTH"), 0, 10);
@@ -141,10 +139,10 @@ static int cgi_input_post(char **input, int max)
return ok;
}
-static char *bound(const char *type)
+static char * bound(const char * type)
{
- char *res = 0;
- type = strchr(type, '=');
+ char * res = 0;
+ type = strchr(type, '=');
if (type) {
type += strspn(type, " \t") + 1;
if (*type == '"') {
@@ -157,44 +155,38 @@ static char *bound(const char *type)
return res;
}
-static int intput_getter(void *any)
+static int intput_getter(void * any)
{
return getchar();
}
-
/* Interfacial CGI Request Handling */
-int magi_cgi_request(
- struct magi_request *request,
- void (*callback)(struct magi_field *field, char *buffer, int len),
- int max_post
-)
+int magi_cgi_request(struct magi_request * request,
+ void (*callback)(struct magi_field * field, char * buffer, int len),
+ int max_post)
{
int ok = cgi_env(request) && cgi_cookies(&request->cookies);
request->fields = 0;
if (request->method) {
if (!strcmp(request->method, "post")) {
- const char *t = getenv("CONTENT_TYPE");
+ const char * t = getenv("CONTENT_TYPE");
if (t) {
if (!strncmp(t, "multipart/form-data", 19)) {
- char *boundary = bound(t);
+ char * boundary = bound(t);
if (boundary && *boundary) {
- ok = magi_parse_multipart(
- &request->fields,
- intput_getter,
- 0,
- boundary,
- callback
- );
+ ok = magi_parse_multipart(&request->fields,
+ intput_getter, 0, boundary, callback);
} else {
ok = 0;
magi_log("[request:cgi] Multipart bound is not set.");
}
free(boundary);
} else if (!strcmp(t, "application/x-www-form-urlencoded")) {
- char *in = 0;
- ok = cgi_input_post(&in, max_post);
- ok = ok && magi_parse_urlencoded(&request->fields, in);
+ char * in = 0;
+ ok = cgi_input_post(&in, max_post);
+ if (ok) {
+ ok = magi_parse_urlencoded(&request->fields, in);
+ }
free(in);
} else {
ok = 0;
@@ -205,9 +197,9 @@ int magi_cgi_request(
magi_log("[request:cgi] Content-type is not set.");
}
} else if (!strcmp(request->method, "get")) {
- char *in = 0;
- ok = cgi_input_get(&in);
- ok = ok && magi_parse_urlencoded(&request->fields, in);
+ char * in = 0;
+ ok = cgi_input_get(&in);
+ ok = ok && magi_parse_urlencoded(&request->fields, in);
free(in);
}
}
diff --git a/src/cgi.h b/src/cgi.h
index c7b173c..85e5b2a 100644
--- a/src/cgi.h
+++ b/src/cgi.h
@@ -9,13 +9,11 @@
* Constructs request using environment variables and standart I/O;
* Returns null if succeed, otherwise error code.
*/
-int magi_cgi_request(
- struct magi_request *request,
+int magi_cgi_request(struct magi_request * request,
/* Callback will be used only for fields loaded via multipart. */
/* Null callback disables callback system. */
- void (*callback)(struct magi_field *field, char *buffer, int len),
- int max_post
-);
+ void (*callback)(struct magi_field * field, char * buffer, int len),
+ int max_post);
#endif
diff --git a/src/cookie.c b/src/cookie.c
index 4e757e6..8926d40 100644
--- a/src/cookie.c
+++ b/src/cookie.c
@@ -18,27 +18,21 @@ enum st {
st_post_data
};
-enum data_type {
- dt_plain = 0,
- dt_version,
- dt_path,
- dt_domain,
- dt_port
-};
+enum data_type { dt_plain = 0, dt_version, dt_path, dt_domain, dt_port };
struct automata {
- struct magi_cookie_list **list;
- struct magi_cookie cookie;
- char *buf;
- int buf_len;
- int buf_size;
- int is_first;
- int is_cookie2;
- int is_quoted;
- enum data_type data_t;
+ struct magi_cookie_list ** list;
+ struct magi_cookie cookie;
+ char * buf;
+ int buf_len;
+ int buf_size;
+ int is_first;
+ int is_cookie2;
+ int is_quoted;
+ enum data_type data_t;
};
-static void nulify_cookie(struct automata *a)
+static void nulify_cookie(struct automata * a)
{
a->cookie.name = 0;
a->cookie.data = 0;
@@ -47,24 +41,24 @@ static void nulify_cookie(struct automata *a)
a->cookie.port = 0;
}
-static void buf_new(struct automata *a)
+static void buf_new(struct automata * a)
{
a->buf = 0;
a->buf_len = 0;
a->buf_size = 1;
}
-static int buf_add(struct automata *a, char c)
+static int buf_add(struct automata * a, char c)
{
int ok = 1;
if (a->buf_len == a->buf_size - 1) {
a->buf_size *= 2;
- a->buf = realloc(a->buf, a->buf_size);
+ a->buf = realloc(a->buf, a->buf_size);
}
if (a->buf) {
a->buf_len++;
a->buf[a->buf_len - 1] = c;
- a->buf[a->buf_len] = 0;
+ a->buf[a->buf_len] = 0;
} else {
ok = 0;
magi_log("[cookie] Cannot allocate automata buffer.");
@@ -72,7 +66,7 @@ static int buf_add(struct automata *a, char c)
return ok;
}
-static enum data_type what_is_name(const struct automata *a)
+static enum data_type what_is_name(const struct automata * a)
{
enum data_type data_t = dt_plain;
if (a->is_first && !strcmp(a->buf, "$Version")) {
@@ -89,7 +83,7 @@ static enum data_type what_is_name(const struct automata *a)
return data_t;
}
-static int end_name(struct automata *a)
+static int end_name(struct automata * a)
{
int ok = 1;
a->data_t = what_is_name(a);
@@ -106,14 +100,22 @@ static int end_name(struct automata *a)
return ok;
}
-static int end_data(struct automata *a)
+static int end_data(struct automata * a)
{
int ok = 1;
switch (a->data_t) {
- case dt_plain: a->cookie.data = a->buf; break;
- case dt_path: a->cookie.path = a->buf; break;
- case dt_domain: a->cookie.domain = a->buf; break;
- case dt_port: a->cookie.port = a->buf; break;
+ case dt_plain:
+ a->cookie.data = a->buf;
+ break;
+ case dt_path:
+ a->cookie.path = a->buf;
+ break;
+ case dt_domain:
+ a->cookie.domain = a->buf;
+ break;
+ case dt_port:
+ a->cookie.port = a->buf;
+ break;
case dt_version:
if (strcmp(a->buf, "1")) {
ok = 0;
@@ -124,7 +126,7 @@ static int end_data(struct automata *a)
return ok;
}
-static enum st parse_pre_name(struct automata *a, char c)
+static enum st parse_pre_name(struct automata * a, char c)
{
enum st state;
if (c == ' ' || c == '\t') {
@@ -141,7 +143,7 @@ static enum st parse_pre_name(struct automata *a, char c)
return state;
}
-static enum st parse_name(struct automata *a, char c)
+static enum st parse_name(struct automata * a, char c)
{
enum st state;
if (c == '=') {
@@ -166,7 +168,7 @@ static enum st parse_name(struct automata *a, char c)
return state;
}
-static enum st parse_post_name(struct automata *a, char c)
+static enum st parse_post_name(struct automata * a, char c)
{
enum st state;
if (c == '=') {
@@ -175,21 +177,20 @@ static enum st parse_post_name(struct automata *a, char c)
state = st_post_name;
} else {
state = st_error;
- magi_log(
- "[cookie] Waiting for name-value separator, "
- "readed: \\%o (render: %c).", c, c
- );
+ magi_log("[cookie] Waiting for name-value separator, "
+ "readed: \\%o (render: %c).",
+ c, c);
}
return state;
}
-static enum st parse_pre_data(struct automata *a, char c)
+static enum st parse_pre_data(struct automata * a, char c)
{
enum st state;
if (c == ' ' || c == '\t') {
state = st_pre_data;
} else if (c == '"') {
- state = st_data;
+ state = st_data;
a->is_quoted = 1;
} else if (32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={}", c)) {
state = st_data;
@@ -203,7 +204,7 @@ static enum st parse_pre_data(struct automata *a, char c)
return state;
}
-static enum st parse_not_quoted_data(struct automata *a, char c)
+static enum st parse_not_quoted_data(struct automata * a, char c)
{
enum st state;
if (c == ';' || (c == ',' && a->is_first)) {
@@ -218,21 +219,20 @@ static enum st parse_not_quoted_data(struct automata *a, char c)
state = st_error;
}
} else if (32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={}", c)) {
- state = st_data;
+ state = st_data;
if (!buf_add(a, c)) {
state = st_error;
}
} else {
state = st_error;
- magi_log(
- "[cookie] Reading not-quoted value, "
- "readed: \\%o (render: %c).", c, c
- );
+ magi_log("[cookie] Reading not-quoted value, "
+ "readed: \\%o (render: %c).",
+ c, c);
}
return state;
}
-static enum st parse_data(struct automata *a, char c)
+static enum st parse_data(struct automata * a, char c)
{
enum st state;
if (a->is_quoted) {
@@ -251,7 +251,7 @@ static enum st parse_data(struct automata *a, char c)
return state;
}
-static enum st parse_post_data(struct automata *a, char c)
+static enum st parse_post_data(struct automata * a, char c)
{
enum st state;
if (c == ';' || (c == ',' && a->is_first)) {
@@ -260,15 +260,14 @@ static enum st parse_post_data(struct automata *a, char c)
state = st_post_data;
} else {
state = st_error;
- magi_log(
- "[cookie] Waiting for separator between name-value pairs, "
- "readed: \\%o (render: %c).", c, c
- );
+ magi_log("[cookie] Waiting for separator between name-value pairs, "
+ "readed: \\%o (render: %c).",
+ c, c);
}
return state;
}
-static int parse_end(struct automata *a, enum st s)
+static int parse_end(struct automata * a, enum st s)
{
int ok = 0;
if (s == st_post_data) {
@@ -299,21 +298,33 @@ static int parse_end(struct automata *a, enum st s)
return ok;
}
-int magi_parse_cookie(struct magi_cookie_list **list, const char *input)
+int magi_parse_cookie(struct magi_cookie_list ** list, const char * input)
{
- struct automata a = { 0, { 0, 0, 0, 0, 0}, 0, 0, 1, 1, 0, 0, 0 };
+ struct automata a = { 0, { 0, 0, 0, 0, 0 }, 0, 0, 1, 1, 0, 0, 0 };
enum st state = st_pre_name;
- a.list = list;
+ a.list = list;
while (*input && state) {
char c = *input++;
switch (state) {
- case st_pre_name: state = parse_pre_name(&a, c); break;
- case st_name: state = parse_name(&a, c); break;
- case st_post_name: state = parse_post_name(&a, c); break;
- case st_pre_data: state = parse_pre_data(&a, c); break;
- case st_data: state = parse_data(&a, c); break;
- case st_post_data: state = parse_post_data(&a, c);
- default: break;
+ case st_pre_name:
+ state = parse_pre_name(&a, c);
+ break;
+ case st_name:
+ state = parse_name(&a, c);
+ break;
+ case st_post_name:
+ state = parse_post_name(&a, c);
+ break;
+ case st_pre_data:
+ state = parse_pre_data(&a, c);
+ break;
+ case st_data:
+ state = parse_data(&a, c);
+ break;
+ case st_post_data:
+ state = parse_post_data(&a, c);
+ default:
+ break;
}
}
return parse_end(&a, state);
@@ -324,13 +335,11 @@ int magi_parse_cookie(struct magi_cookie_list **list, const char *input)
* Cookie List
*/
int magi_cookie_list_add(
- struct magi_cookie_list **list,
- struct magi_cookie *item
-)
+ struct magi_cookie_list ** list, struct magi_cookie * item)
{
- struct magi_cookie_list *old = *list;
- int ok = 1;
- *list = malloc(sizeof(**list));
+ struct magi_cookie_list * old = *list;
+ int ok = 1;
+ *list = malloc(sizeof(**list));
if (*list) {
(*list)->next = old;
(*list)->item = *item;
@@ -342,9 +351,9 @@ int magi_cookie_list_add(
return ok;
}
-char *magi_cookie_list_get(struct magi_cookie_list *list, const char *name)
+char * magi_cookie_list_get(struct magi_cookie_list * list, const char * name)
{
- char *data = 0;
+ char * data = 0;
if (list && name) {
if (!strcmp(list->item.name, name)) {
data = list->item.data;
@@ -355,7 +364,7 @@ char *magi_cookie_list_get(struct magi_cookie_list *list, const char *name)
return data;
}
-void magi_cookie_list_destroy(struct magi_cookie_list *list)
+void magi_cookie_list_destroy(struct magi_cookie_list * list)
{
if (list) {
magi_cookie_list_destroy(list->next);
diff --git a/src/cookie.h b/src/cookie.h
index b0a7fb0..f72736b 100644
--- a/src/cookie.h
+++ b/src/cookie.h
@@ -6,42 +6,40 @@
* Cookie
*/
struct magi_cookie {
- char *name; /* name: free(name) is valid. */
- char *data; /* data: free(data) is valid. */
+ char * name; /* name: free(name) is valid. */
+ char * data; /* data: free(data) is valid. */
/* Following is used in Cookie2: */
- char *path; /* path: free(path) is valid. */
- char *domain; /* domain: free(domain) is valid. */
- char *port; /* port: free(port) is valid. */
+ char * path; /* path: free(path) is valid. */
+ char * domain; /* domain: free(domain) is valid. */
+ char * port; /* port: free(port) is valid. */
};
/* Null is valid "struct magi_cookie_list *" object. */
struct magi_cookie_list {
- struct magi_cookie_list *next;
- struct magi_cookie item;
+ struct magi_cookie_list * next;
+ struct magi_cookie item;
};
/* Returns null in case of error. */
-int magi_parse_cookie(struct magi_cookie_list **list, const char *input);
+int magi_parse_cookie(struct magi_cookie_list ** list, const char * input);
/*
* Adds *item to the begining of *list, item and list are dereferencable;
* Returns null in case of error.
*/
int magi_cookie_list_add(
- struct magi_cookie_list **list,
- struct magi_cookie *item
-);
+ struct magi_cookie_list ** list, struct magi_cookie * item);
/*
* Searchs for first node in list: node.name == name, name is C-string;
* Returns node.data if succeed, otherwise result is null.
*/
-char *magi_cookie_list_get(struct magi_cookie_list *list, const char *name);
+char * magi_cookie_list_get(struct magi_cookie_list * list, const char * name);
/*
* Destroys list; list is not valid after destruction.
*/
-void magi_cookie_list_destroy(struct magi_cookie_list *list);
+void magi_cookie_list_destroy(struct magi_cookie_list * list);
#endif
diff --git a/src/fastcgi.h b/src/fastcgi.h
index e69de29..9213c3c 100644
--- a/src/fastcgi.h
+++ b/src/fastcgi.h
@@ -0,0 +1,21 @@
+#ifndef MAGI_INCLUDED_FASTCGI
+#define MAGI_INCLUDED_FASTCGI
+
+#include "field.h"
+#include "request.h"
+
+
+struct magi_session {
+ void (*callback)(struct magi_field * field, char * buffer, int len);
+ int max_post;
+ struct magi_socket_list * sockets;
+};
+
+/*
+ * Returns null if succeed, otherwise error code.
+ */
+int magi_fast_cgi_request(
+ struct magi_request * request, struct magi_session * session);
+
+
+#endif
diff --git a/src/field.c b/src/field.c
index 0fa2664..7b0b919 100644
--- a/src/field.c
+++ b/src/field.c
@@ -9,11 +9,12 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Form Field
*/
-int magi_field_list_add(struct magi_field_list **list, struct magi_field *item)
+int magi_field_list_add(
+ struct magi_field_list ** list, struct magi_field * item)
{
- struct magi_field_list *old = *list;
- int ok = 1;
- *list = malloc(sizeof(**list));
+ struct magi_field_list * old = *list;
+ int ok = 1;
+ *list = malloc(sizeof(**list));
if (*list) {
(*list)->next = old;
(*list)->item = *item;
@@ -25,12 +26,10 @@ int magi_field_list_add(struct magi_field_list **list, struct magi_field *item)
return ok;
}
-struct magi_field *magi_field_list_get(
- struct magi_field_list *list,
- const char *name
-)
+struct magi_field * magi_field_list_get(
+ struct magi_field_list * list, const char * name)
{
- struct magi_field *item = 0;
+ struct magi_field * item = 0;
if (list && name) {
if (!strcmp(list->item.name, name)) {
item = &list->item;
@@ -41,7 +40,7 @@ struct magi_field *magi_field_list_get(
return item;
}
-void magi_field_list_destroy(struct magi_field_list *list)
+void magi_field_list_destroy(struct magi_field_list * list)
{
if (list) {
magi_field_list_destroy(list->next);
diff --git a/src/field.h b/src/field.h
index a6fcff3..8387863 100644
--- a/src/field.h
+++ b/src/field.h
@@ -6,16 +6,16 @@
* Form Field
*/
struct magi_field {
- char *name; /* name: free(name) is valid. */
- char *data; /* data: free(data) is valid. */
- int len; /* Length of data. */
- struct magi_param_list *params; /* Only used if field is for file. */
+ char * name; /* name: free(name) is valid. */
+ char * data; /* data: free(data) is valid. */
+ int len; /* Length of data. */
+ struct magi_param_list * params; /* Only used if field is for file. */
};
/* Null is valid "struct magi_field_list *" object. */
struct magi_field_list {
- struct magi_field_list *next;
- struct magi_field item;
+ struct magi_field_list * next;
+ struct magi_field item;
};
/*
@@ -23,23 +23,19 @@ struct magi_field_list {
* Returns null in case of error.
*/
int magi_field_list_add(
- struct magi_field_list **list,
- struct magi_field *item
-);
+ struct magi_field_list ** list, struct magi_field * item);
/*
* Searchs for first node in list: node.name == name, name is C-string;
* Returns node itself if succeed, otherwise result is null.
*/
-struct magi_field *magi_field_list_get(
- struct magi_field_list *list,
- const char *name
-);
+struct magi_field * magi_field_list_get(
+ struct magi_field_list * list, const char * name);
/*
* Destroys list; list is not valid after destruction.
*/
-void magi_field_list_destroy(struct magi_field_list *list);
+void magi_field_list_destroy(struct magi_field_list * list);
#endif
diff --git a/src/log.c b/src/log.c
index 2dd6452..968aa54 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,16 +1,17 @@
#include "log.h"
-#include <stdio.h>
#include <stdarg.h>
+#include <stdio.h>
+
-void magi_log(const char *format, ...)
+void magi_log(const char * format, ...)
{
- #ifdef ERRLOG
+#ifdef ERRLOG
va_list args;
va_start(args, format);
fputs("MAGI ERROR: ", stderr);
vfprintf(stderr, format, args);
fputc('\n', stderr);
va_end(args);
- #endif
+#endif
}
diff --git a/src/log.h b/src/log.h
index 0cf165f..e8f7221 100644
--- a/src/log.h
+++ b/src/log.h
@@ -2,7 +2,7 @@
#define MAGI_INCLUDED_LOG
-void magi_log(const char *format, ...);
+void magi_log(const char * format, ...);
#endif
diff --git a/src/multipart.c b/src/multipart.c
index 94a37cb..c49be9b 100644
--- a/src/multipart.c
+++ b/src/multipart.c
@@ -4,72 +4,12 @@
#include "log.h"
#include "param.h"
#include <ctype.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Local Shortcuts
- */
-static int add(char **dest, int *len, int *size, char c)
-{
- int ok = 1;
- if (*len + 1 == *size) {
- *size *= 2;
- *dest = realloc(*dest, *size);
- }
- if (*dest == 0) {
- ok = 0;
- magi_log("[multipart] Cannot allocate string.");
- } else {
- (*dest)[*len] = c;
- ++*len;
- (*dest)[*len] = 0;
- }
- return ok;
-}
-
-static void lowercase(char *str)
-{
- if (str) {
- while (*str) {
- *str = tolower(*str);
- ++str;
- }
- }
-}
-
-static char *create_str(char *begin, char *end)
-{
- char *res;
- res = malloc(end - begin + 1);
- if (res) {
- memcpy(res, begin, end - begin);
- res[end - begin] = 0;
- } else {
- magi_log("[multipart] Cannot allocate string.");
- }
- return res;
-}
-
-static int is_token(char c)
-{
- return 32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={} \t", c);
-}
-
-static int is_str_token(char *str)
-{
- int is = str && *str; /* Empty string is not valid. */
- while (is && *str) {
- is = is_token(*str);
- ++str;
- }
- return is;
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Automata for multipart/form-data
*/
enum st {
@@ -84,30 +24,30 @@ enum st {
};
struct automata {
- struct magi_field_list **list;
- struct magi_field field;
- struct magi_param param;
- char *buf;
- int buf_size;
- int size;
- int len;
- char *boundary;
- int boundary_pos;
- int boundary_len;
- int is_end_suspected;
- int is_CR_readed;
- int is_quoted;
- void (*callback)(struct magi_field *field, char *buffer, int size);
+ struct magi_field_list ** list;
+ struct magi_field field;
+ struct magi_param param;
+ char * buf;
+ int buf_size;
+ int size;
+ int len;
+ char * boundary;
+ int boundary_pos;
+ int boundary_len;
+ int is_end_suspected;
+ int is_CR_readed;
+ int is_quoted;
+ void (*callback)(struct magi_field * field, char * buffer, int size);
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Automata Shortcuts
*/
-static int content_disposition(struct automata *a)
+static int content_disposition(struct automata * a)
{
- int ok = 1;
- char *name = strchr(a->param.data, '=');
+ int ok = 1;
+ char * name = strchr(a->param.data, '=');
if (name) {
name += strspn(name, " \t") + 1;
if (*name == '"') {
@@ -125,10 +65,9 @@ static int content_disposition(struct automata *a)
ok = 0;
} else if (!is_str_token(a->field.name)) {
ok = 0;
- magi_log(
- "[multipart] Content-disposition value is not valid, "
- "readed: %s.", a->field.name
- );
+ magi_log("[multipart] Content-disposition value is not valid, "
+ "readed: %s.",
+ a->field.name);
}
}
if (ok) {
@@ -144,14 +83,14 @@ static int content_disposition(struct automata *a)
return ok;
}
-static int param_end(struct automata *a)
+static int param_end(struct automata * a)
{
int ok = 1;
lowercase(a->param.name);
if (!strcmp(a->param.name, "content-disposition")) {
ok = content_disposition(a);
} else {
- ok = magi_param_list_add(&a->field.params, &a->param);
+ ok = magi_param_list_add(&a->field.params, &a->param);
a->param.name = 0;
a->param.data = 0;
}
@@ -160,7 +99,7 @@ static int param_end(struct automata *a)
return ok;
}
-static int field_end(struct automata *a)
+static int field_end(struct automata * a)
{
int ok;
if (a->field.name == 0) {
@@ -172,7 +111,7 @@ static int field_end(struct automata *a)
a->buf_size = 0;
}
a->field.len = a->len;
- ok = magi_field_list_add(a->list, &a->field);
+ ok = magi_field_list_add(a->list, &a->field);
if (!ok) {
free(a->field.name);
free(a->field.data);
@@ -192,9 +131,9 @@ static int field_end(struct automata *a)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Boundary interfaces
*/
-static char sepget(const struct automata *a)
+static char sepget(const struct automata * a)
{
- char c;
+ char c;
const int pos_after = a->boundary_pos - 4 - a->boundary_len;
if (a->boundary_pos == 0) {
c = '\r';
@@ -214,14 +153,14 @@ static char sepget(const struct automata *a)
return c;
}
-static int seplen(const struct automata *a)
+static int seplen(const struct automata * a)
{
return a->boundary_len + 6;
}
-static char endget(const struct automata *a)
+static char endget(const struct automata * a)
{
- char c;
+ char c;
const int pos_after = a->boundary_pos - 4 - a->boundary_len;
if (a->boundary_pos == 0) {
c = '\r';
@@ -243,13 +182,13 @@ static char endget(const struct automata *a)
return c;
}
-static int endlen(const struct automata *a)
+static int endlen(const struct automata * a)
{
return a->boundary_len + 8;
}
-static int is_semiend(const struct automata *a)
-{ /* Is end readed, expect last two chars, which are CR LF? */
+static int is_semiend(const struct automata * a)
+{ /* Is end readed, expect last two chars, which are CR LF? */
return a->is_end_suspected && (a->boundary_pos == endlen(a) - 2);
}
@@ -257,7 +196,7 @@ static int is_semiend(const struct automata *a)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* State analysers
*/
-static enum st parse_begin(struct automata *a, char c)
+static enum st parse_begin(struct automata * a, char c)
{
enum st state;
if (sepget(a) == c) {
@@ -268,26 +207,26 @@ static enum st parse_begin(struct automata *a, char c)
state = st_begin;
}
} else {
- state = st_begin;
+ state = st_begin;
a->boundary_pos = 0;
}
return state;
}
-static enum st parse_pname_pre(struct automata *a, char c)
+static enum st parse_pname_pre(struct automata * a, char c)
{
enum st state;
if (a->is_CR_readed) {
a->is_CR_readed = 0;
if (c == '\n') {
- state = st_data;
+ state = st_data;
a->boundary_pos = 0;
} else {
state = st_error;
magi_log("[multipart] Waiting for name, CR is readed alone.");
}
} else if (c == '\r') {
- state = st_pname_pre;
+ state = st_pname_pre;
a->is_CR_readed = 1;
} else if (is_token(c)) {
if (add(&a->param.name, &a->len, &a->size, c)) {
@@ -298,13 +237,12 @@ static enum st parse_pname_pre(struct automata *a, char c)
} else {
state = st_error;
magi_log(
- "[multipart] Waiting for name, readed: \\%o (render: %c).", c, c
- );
+ "[multipart] Waiting for name, readed: \\%o (render: %c).", c, c);
}
return state;
}
-static enum st parse_pname(struct automata *a, char c)
+static enum st parse_pname(struct automata * a, char c)
{
enum st state;
if (c == ':') {
@@ -321,14 +259,12 @@ static enum st parse_pname(struct automata *a, char c)
}
} else {
state = st_error;
- magi_log(
- "[multipart] Reading name, readed: \\%o (render: %c).", c, c
- );
+ magi_log("[multipart] Reading name, readed: \\%o (render: %c).", c, c);
}
return state;
}
-static enum st parse_pname_end(struct automata *a, char c)
+static enum st parse_pname_end(struct automata * a, char c)
{
enum st state;
if (c == ':') {
@@ -339,15 +275,14 @@ static enum st parse_pname_end(struct automata *a, char c)
state = st_pname_end;
} else {
state = st_error;
- magi_log(
- "[multipart] Waiting for name-value separator, "
- "readed: \\%o (render: %c).", c, c
- );
+ magi_log("[multipart] Waiting for name-value separator, "
+ "readed: \\%o (render: %c).",
+ c, c);
}
return state;
}
-static enum st parse_pdata(struct automata *a, char c)
+static enum st parse_pdata(struct automata * a, char c)
{
enum st state;
if (a->is_CR_readed) {
@@ -380,7 +315,7 @@ static enum st parse_pdata(struct automata *a, char c)
return state;
}
-static void apply_callback(struct automata *a)
+static void apply_callback(struct automata * a)
{
if (a->callback && a->buf_size == magi_parse_multipart_callback_size) {
a->callback(&a->field, a->buf, a->buf_size);
@@ -388,13 +323,13 @@ static void apply_callback(struct automata *a)
}
}
-static enum st data_add(struct automata *a, char c)
+static enum st data_add(struct automata * a, char c)
{
static int max_buf_size = magi_parse_multipart_callback_size + 1;
enum st state;
- char **dest;
- int *len;
- int *size;
+ char ** dest;
+ int * len;
+ int * size;
int pos = a->boundary_pos;
state = st_data;
a->boundary_pos = 0;
@@ -433,7 +368,7 @@ static enum st data_add(struct automata *a, char c)
return state;
}
-static enum st parse_data(struct automata *a, char c)
+static enum st parse_data(struct automata * a, char c)
{
enum st state;
if (a->is_end_suspected) {
@@ -466,7 +401,7 @@ static enum st parse_data(struct automata *a, char c)
return state;
}
-static enum st parse_end(struct automata *a, char c)
+static enum st parse_end(struct automata * a, char c)
{
return st_end;
}
@@ -475,22 +410,36 @@ static enum st parse_end(struct automata *a, char c)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Automata Runner
*/
-static int
-run_automata(struct automata *a, int (*next)(void *thing), void *thing)
+static int run_automata(
+ struct automata * a, int (*next)(void * thing), void * thing)
{
int ok = 1;
enum st state = st_begin;
- int c;
+ int c;
for (c = next(thing); state && c != EOF; c = next(thing)) {
switch (state) {
- case st_begin: state = parse_begin(a, c); break;
- case st_pname_pre: state = parse_pname_pre(a, c); break;
- case st_pname: state = parse_pname(a, c); break;
- case st_pname_end: state = parse_pname_end(a, c); break;
- case st_pdata: state = parse_pdata(a, c); break;
- case st_data: state = parse_data(a, c); break;
- case st_end: state = parse_end(a, c);
- default: break;
+ case st_begin:
+ state = parse_begin(a, c);
+ break;
+ case st_pname_pre:
+ state = parse_pname_pre(a, c);
+ break;
+ case st_pname:
+ state = parse_pname(a, c);
+ break;
+ case st_pname_end:
+ state = parse_pname_end(a, c);
+ break;
+ case st_pdata:
+ state = parse_pdata(a, c);
+ break;
+ case st_data:
+ state = parse_data(a, c);
+ break;
+ case st_end:
+ state = parse_end(a, c);
+ default:
+ break;
}
}
if (state == st_data && is_semiend(a)) {
@@ -512,23 +461,18 @@ run_automata(struct automata *a, int (*next)(void *thing), void *thing)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Automata Interfaces
*/
-int magi_parse_multipart(
- struct magi_field_list **list,
- int (*get_next)(void *),
- void *get_next_arg,
- char *boundary,
- void (*callback)(struct magi_field *field, char *buffer, int len)
-)
+int magi_parse_multipart(struct magi_field_list ** list,
+ int (*get_next)(void *), void * get_next_arg, char * boundary,
+ void (*callback)(struct magi_field * field, char * buffer, int len))
{
- struct automata a = {
- 0, { 0, 0, 0 }, { 0, 0 }, 0, 0, 1, 0, 0, 2, 0, 0, 0
- };
- int ok = 0;
- a.list = list;
- a.boundary = boundary;
- a.boundary_len = strlen(boundary);
- a.callback = callback;
- a.buf = malloc(magi_parse_multipart_callback_size + 1);
+ struct automata a
+ = { 0, { 0, 0, 0 }, { 0, 0 }, 0, 0, 1, 0, 0, 2, 0, 0, 0 };
+ int ok = 0;
+ a.list = list;
+ a.boundary = boundary;
+ a.boundary_len = strlen(boundary);
+ a.callback = callback;
+ a.buf = malloc(magi_parse_multipart_callback_size + 1);
if (a.buf) {
ok = run_automata(&a, get_next, get_next_arg);
free(a.buf);
diff --git a/src/multipart.h b/src/multipart.h
index a7437eb..e9a0004 100644
--- a/src/multipart.h
+++ b/src/multipart.h
@@ -4,20 +4,14 @@
#include "field.h"
-enum {
- magi_parse_multipart_callback_size = 64
-};
+enum { magi_parse_multipart_callback_size = 64 };
-int magi_parse_multipart(
- struct magi_field_list **list,
- int (*get_next)(void *),
- void *get_next_arg,
- char *boundary,
+int magi_parse_multipart(struct magi_field_list ** list,
+ int (*get_next)(void *), void * get_next_arg, char * boundary,
/* End if size < magi_parse_multipart_callback_size. */
/* Null callback means filling list. */
- void (*callback)(struct magi_field *field, char *buffer, int size)
-);
+ void (*callback)(struct magi_field * field, char * buffer, int size));
#endif
diff --git a/src/param.c b/src/param.c
index ebd2216..8921019 100644
--- a/src/param.c
+++ b/src/param.c
@@ -8,11 +8,12 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Parameter
*/
-int magi_param_list_add(struct magi_param_list **list, struct magi_param *item)
+int magi_param_list_add(
+ struct magi_param_list ** list, struct magi_param * item)
{
- struct magi_param_list *old = *list;
- int ok = 1;
- *list = malloc(sizeof(**list));
+ struct magi_param_list * old = *list;
+ int ok = 1;
+ *list = malloc(sizeof(**list));
if (*list) {
(*list)->next = old;
(*list)->item = *item;
@@ -24,12 +25,10 @@ int magi_param_list_add(struct magi_param_list **list, struct magi_param *item)
return ok;
}
-struct magi_param *magi_param_list_get(
- struct magi_param_list *list,
- const char *name
-)
+struct magi_param * magi_param_list_get(
+ struct magi_param_list * list, const char * name)
{
- struct magi_param *item = 0;
+ struct magi_param * item = 0;
if (list && name) {
if (!strcmp(list->item.name, name)) {
item = &list->item;
@@ -40,7 +39,7 @@ struct magi_param *magi_param_list_get(
return item;
}
-void magi_param_list_destroy(struct magi_param_list *list)
+void magi_param_list_destroy(struct magi_param_list * list)
{
if (list) {
magi_param_list_destroy(list->next);
diff --git a/src/param.h b/src/param.h
index a9a5942..ede1586 100644
--- a/src/param.h
+++ b/src/param.h
@@ -6,14 +6,14 @@
* Parameter
*/
struct magi_param {
- char *name; /* name: free(name) is valid. */
- char *data; /* data: free(data) is valid. */
+ char * name; /* name: free(name) is valid. */
+ char * data; /* data: free(data) is valid. */
};
/* Null is valid "struct magi_param_list *" object. */
struct magi_param_list {
- struct magi_param_list *next;
- struct magi_param item;
+ struct magi_param_list * next;
+ struct magi_param item;
};
/*
@@ -21,23 +21,19 @@ struct magi_param_list {
* Returns null in case of error.
*/
int magi_param_list_add(
- struct magi_param_list **list,
- struct magi_param *item
-);
+ struct magi_param_list ** list, struct magi_param * item);
/*
* Searchs for first node in list: node.name == name, name is C-string;
* Returns node itself if succeed, otherwise result is null.
*/
-struct magi_param *magi_param_list_get(
- struct magi_param_list *list,
- const char *name
-);
+struct magi_param * magi_param_list_get(
+ struct magi_param_list * list, const char * name);
/*
* Destroys list; list is not valid after destruction.
*/
-void magi_param_list_destroy(struct magi_param_list *list);
+void magi_param_list_destroy(struct magi_param_list * list);
#endif
diff --git a/src/request.c b/src/request.c
index 58eefc6..73c4730 100644
--- a/src/request.c
+++ b/src/request.c
@@ -1,7 +1,7 @@
#include "request.h"
-#include "field.h"
#include "cookie.h"
+#include "field.h"
#include "param.h"
#include <stdlib.h>
@@ -9,7 +9,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Common Request Handling
*/
-void magi_request_destroy(struct magi_request *request)
+void magi_request_destroy(struct magi_request * request)
{
if (request) {
magi_field_list_destroy(request->fields);
diff --git a/src/request.h b/src/request.h
index 6b9df6e..bd9c521 100644
--- a/src/request.h
+++ b/src/request.h
@@ -8,9 +8,11 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Request
- *
- * Example for enivronmental variables:
- * Request: http://example.com/cgi-bin/script/foo/bar?var2=url%20enc
+ *
+ * Can be generated via CGI handler (magi_cgi_request) or
+ * as session in Fast CGI (magi_fast_cgi_request).
+ *
+ * Example: http://example.com/cgi-bin/script/foo/bar?var2=url%20enc
* method: get
* uri: /cgi-bin/script/foo/bar?var2=url%20enc
* document_root: { absolute path to root directory of domain }
@@ -28,30 +30,31 @@
* path_info: /foo/bar
*/
struct magi_request {
- struct magi_field_list *fields;
- struct magi_cookie_list *cookies;
- char *method;
- char *uri;
- char *document_root;
- char *document_uri;
- char *script_name;
- char *script_filename;
- char *remote_addr;
- char *remote_port;
- char *server_addr;
- char *server_name;
- char *server_port;
- char *server_protocol;
- char *server_software;
- char *path_info;
- struct magi_param_list *http_params;
+ struct magi_field_list * fields;
+ struct magi_cookie_list * cookies;
+ char * method;
+ char * uri;
+ char * document_root;
+ char * document_uri;
+ char * script_name;
+ char * script_filename;
+ char * remote_addr;
+ char * remote_port;
+ char * server_addr;
+ char * server_name;
+ char * server_port;
+ char * server_protocol;
+ char * server_software;
+ char * path_info;
+ struct magi_param_list * http_params;
+ /* TODO: error. */
};
/*
* Destroys request; request is not valid after destruction.
*/
-void magi_request_destroy(struct magi_request *request);
+void magi_request_destroy(struct magi_request * request);
#endif
diff --git a/src/urlencoded.c b/src/urlencoded.c
index c208180..1edcf99 100644
--- a/src/urlencoded.c
+++ b/src/urlencoded.c
@@ -8,50 +8,28 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Shortcuts
- */
-/* Shouldn't be called with 'c' as not hex digit. */
-static char from_hex(char c)
-{
- char num;
- if (isdigit(c)) {
- num = c - '0';
- } else {
- num = toupper(c) - 'A' + 10;
- }
- return num;
-}
-
-static int is_hex(char c)
-{
- return isdigit(c) || strchr("ABCDEF", toupper(c));
-}
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* URL Decoding
*/
-static int deurl(char **data)
+static int deurl(char ** data)
{
int ok = 1;
if (*data) {
- char *val = *data;
- int ti = 0;
- int ci;
+ char * val = *data;
+ int ti = 0;
+ int ci;
for (ci = 0; ok && val[ci]; ++ti, ++ci) {
if (val[ci] == '%') {
if (is_hex(val[ci + 1]) && is_hex(val[ci + 2])) {
/* Since chars can be signed, arithmetics are not safe. */
- val[ti] = from_hex(val[ci + 2]); /* 00xx */
- val[ti] |= from_hex(val[ci + 1]) << 4; /* XXxx */
- ci += 2;
+ val[ti] = from_hex(val[ci + 2]); /* 00xx */
+ val[ti] |= from_hex(val[ci + 1]) << 4; /* XXxx */
+ ci += 2;
} else {
ok = 0;
magi_log(
"[urlencoded] Waiting for two hex digits after '%%', "
"readed: \\%o\\%o (render: %c%c)",
- val[ci + 1], val[ci + 2], val[ci + 1], val[ci + 2]
- );
+ val[ci + 1], val[ci + 2], val[ci + 1], val[ci + 2]);
}
} else if (val[ci] == '+') {
val[ti] = ' ';
@@ -71,21 +49,17 @@ static int deurl(char **data)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Urlencoded Automata
*/
-enum st {
- st_error = 0,
- st_name,
- st_data
-};
+enum st { st_error = 0, st_name, st_data };
struct automata {
- struct magi_field_list **list;
- struct magi_field field;
- int size;
- int len;
+ struct magi_field_list ** list;
+ struct magi_field field;
+ int size;
+ int len;
};
-static enum st parse_name(struct automata *a, char c)
+static enum st parse_name(struct automata * a, char c)
{
enum st state;
if (c != '&' && c != ';') {
@@ -95,7 +69,7 @@ static enum st parse_name(struct automata *a, char c)
a->len = 0;
} else {
if (a->len == a->size - 1) {
- a->size *= 2;
+ a->size *= 2;
a->field.name = realloc(a->field.name, a->size);
}
if (!a->field.name) {
@@ -110,12 +84,13 @@ static enum st parse_name(struct automata *a, char c)
}
} else {
state = st_error;
- magi_log("[urlencoded] Reading name, readed: \\%o (render: %c).", c, c);
+ magi_log(
+ "[urlencoded] Reading name, readed: \\%o (render: %c).", c, c);
}
return state;
}
-static enum st end_data(struct automata *a)
+static enum st end_data(struct automata * a)
{
enum st state = st_error;
if (deurl(&a->field.name) && deurl(&a->field.data)) {
@@ -131,7 +106,7 @@ static enum st end_data(struct automata *a)
return state;
}
-static enum st parse_data(struct automata *a, char c)
+static enum st parse_data(struct automata * a, char c)
{
enum st state;
if (c != '=') {
@@ -139,7 +114,7 @@ static enum st parse_data(struct automata *a, char c)
state = end_data(a);
} else {
if (a->len == a->size - 1) {
- a->size *= 2;
+ a->size *= 2;
a->field.data = realloc(a->field.data, a->size);
}
if (!a->field.data) {
@@ -154,22 +129,27 @@ static enum st parse_data(struct automata *a, char c)
}
} else {
state = st_error;
- magi_log("[urlencoded] Reading data, readed: \\%o (render: %c).", c, c);
+ magi_log(
+ "[urlencoded] Reading data, readed: \\%o (render: %c).", c, c);
}
return state;
}
-int magi_parse_urlencoded(struct magi_field_list **list, const char *input)
+int magi_parse_urlencoded(struct magi_field_list ** list, const char * input)
{
- enum st state = st_name;
- struct automata a = { 0, { 0, 0, 0 }, 1, 0 };
+ enum st state = st_name;
+ struct automata a = { 0, { 0, 0, 0 }, 1, 0 };
if (input && *input) {
a.list = list;
while (state && *input) {
switch (state) {
- case st_name: state = parse_name(&a, *input); break;
- case st_data: state = parse_data(&a, *input);
- default: break;
+ case st_name:
+ state = parse_name(&a, *input);
+ break;
+ case st_data:
+ state = parse_data(&a, *input);
+ default:
+ break;
}
++input;
}
diff --git a/src/urlencoded.h b/src/urlencoded.h
index 5902a24..838ae57 100644
--- a/src/urlencoded.h
+++ b/src/urlencoded.h
@@ -4,7 +4,7 @@
#include "field.h"
-int magi_parse_urlencoded(struct magi_field_list **list, const char *input);
+int magi_parse_urlencoded(struct magi_field_list ** list, const char * input);
#endif
diff --git a/src/utils.h b/src/utils.h
index a6c0aff..f16ea3f 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -2,7 +2,7 @@
#define MAGI_INCLUDED_UTILS
-static void lowercase(char *str)
+static void lowercase(char * str)
{
if (str) {
while (*str) {
@@ -12,20 +12,22 @@ static void lowercase(char *str)
}
}
-static char *create_str(const char *begin, const char *end)
+static char * create_str(const char * begin, const char * end)
{
- char *res;
+ char * res;
res = malloc(end - begin + 1);
if (res) {
memcpy(res, begin, end - begin);
res[end - begin] = 0;
+ } else {
+ magi_log("Cannot allocate string.");
}
return res;
}
-static char *str_alloc(int len)
+static char * str_alloc(int len)
{
- char *str = malloc(len + 1);
+ char * str = malloc(len + 1);
if (str) {
str[len] = 0;
} else {
@@ -34,5 +36,55 @@ static char *str_alloc(int len)
return str;
}
+/* Shouldn't be called with 'c' as not hex digit. */
+static char from_hex(char c)
+{
+ char num;
+ if (isdigit(c)) {
+ num = c - '0';
+ } else {
+ num = toupper(c) - 'A' + 10;
+ }
+ return num;
+}
+
+static int is_hex(char c)
+{
+ return isdigit(c) || strchr("ABCDEF", toupper(c));
+}
+
+static int add(char ** dest, int * len, int * size, char c)
+{
+ int ok = 1;
+ if (*len + 1 == *size) {
+ *size *= 2;
+ *dest = realloc(*dest, *size);
+ }
+ if (*dest == 0) {
+ ok = 0;
+ magi_log("Cannot allocate string.");
+ } else {
+ (*dest)[*len] = c;
+ ++*len;
+ (*dest)[*len] = 0;
+ }
+ return ok;
+}
+
+static int is_token(char c)
+{
+ return 32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={} \t", c);
+}
+
+static int is_str_token(char * str)
+{
+ int is = str && *str; /* Empty string is not valid. */
+ while (is && *str) {
+ is = is_token(*str);
+ ++str;
+ }
+ return is;
+}
+
#endif