aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Veresov <aleksey@veresov.pro>2020-03-17 23:27:44 +0300
committerAleksey Veresov <aleksey@veresov.pro>2020-03-17 23:27:44 +0300
commit1d8e7d8ef36de7bae2c62f63bec0e9914f18e77d (patch)
tree79e049c3204216d99199e5d4f299b79c0547037c
parentd9f19275d0549c4b9c3402e1fd28c71627507557 (diff)
downloadmagi-1d8e7d8ef36de7bae2c62f63bec0e9914f18e77d.tar
magi-1d8e7d8ef36de7bae2c62f63bec0e9914f18e77d.tar.xz
magi-1d8e7d8ef36de7bae2c62f63bec0e9914f18e77d.zip
[magi]
-rw-r--r--Makefile57
-rw-r--r--examples/fastcgi.todo (renamed from examples/fastcgi.c)0
-rw-r--r--include/magi/response.h5
-rw-r--r--src/cgi.c17
-rw-r--r--src/cookies.c4
-rw-r--r--src/multipart.c4
-rw-r--r--src/response.c53
7 files changed, 98 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index fd2fc64..df3856d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,15 +1,13 @@
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Compilation Options
-# Debug mode (allowing to debug the library via gdb):
-# DEBUG = yes
-# Specify directory to store object files:
-OBJ_DIR = build
+# Debug mode [yes/no] (allowing to debug the library via gdb):
+DEBUG ?= no
+# Specify build directory:
+BUILD ?= build
# Optional modules (remove unwanted ones):
-MODULES = cgi fastcgi loadfile urlenc
-# Examples to build with 'examples' target:
-EXAMPLES = append cookie echo upload
+MODULES ?= cgi fastcgi loadfile urlenc
# Specify your favourite C compiler here:
-CC = gcc
+CC ?= gcc
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -37,10 +35,12 @@ 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)
+OBJ = $(foreach name,$(NAMES),$(BUILD)/$(SRC_DIR)/$(name).o)
EXDIR = examples
-EXSRC = $(foreach ex,$(EXAMPLES),$(EXDIR)/$(ex).c)
+EXSRC = $(wildcard $(EXDIR)/*.c)
+EXNAMES = $(notdir $(EXSRC:.c=))
+EXAMPLES = $(foreach ex,$(EXNAMES),$(BUILD)/$(EXDIR)/$(ex))
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -48,42 +48,45 @@ EXSRC = $(foreach ex,$(EXAMPLES),$(EXDIR)/$(ex).c)
.PHONY: default clean examples
# 'make' produces library by default:
-default: $(OBJ_DIR) $(LIB)
+default: $(BUILD)/$(LIB)
+
+examples: $(EXAMPLES)
# Cleaning means removing everything automatically produced:
clean:
- rm -rf $(OBJ_DIR) $(LIB) $(EXAMPLES) deps.mk
-
-examples: default $(EXAMPLES)
+ rm -rf $(BUILD)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Compilation
# Compile object files from corresponding source and header:
-$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
+$(BUILD)/$(SRC_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -I $(INC_DIR) -c $< -o $@
# Packing object files into library:
-$(LIB): $(OBJ)
+$(BUILD)/$(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 $@
+$(BUILD)/$(EXDIR)/%: $(EXDIR)/%.c $(BUILD)/$(LIB)
+ $(CC) $(CFLAGS) -I include $< -L$(BUILD) -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 >> $@; \
+$(BUILD)/deps.mk: $(SRC) $(EXSRC)
+ mkdir $(BUILD) $(BUILD)/$(SRC_DIR) $(BUILD)/$(EXDIR); echo '' > $@
+ for t in $(NAMES); do \
+ $(CC) -I $(INC_DIR) \
+ -MT $(BUILD)/$(SRC_DIR)/$${t}.o \
+ -MM $(SRC_DIR)/$${t}.c >> $@; \
+ done
+ for t in $(EXNAMES); do \
+ $(CC) -I include \
+ -MT $(BUILD)/$(EXDIR)/$${t}.o \
+ -MM $(EXDIR)/$${t}.c >> $@; \
done
ifneq (clean, $(MAKECMDGOALS))
--include deps.mk
+-include $(BUILD)/deps.mk
endif
diff --git a/examples/fastcgi.c b/examples/fastcgi.todo
index 5d3c4b1..5d3c4b1 100644
--- a/examples/fastcgi.c
+++ b/examples/fastcgi.todo
diff --git a/include/magi/response.h b/include/magi/response.h
index 756e2bd..4b71ef5 100644
--- a/include/magi/response.h
+++ b/include/magi/response.h
@@ -12,12 +12,14 @@
*/
#include "request.h"
#include <stdio.h>
+#include <stdarg.h>
-/* * * TODO * * */
+/* * * TODO: Comments * * */
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);
+typedef void (*magi_response_method_fmt)(void *ud, const char *f, va_list a);
typedef void (*magi_response_method_file)(void *ud, FILE *file);
typedef void (*magi_response_method_close)(void *ud);
@@ -25,6 +27,7 @@ typedef struct magi_response_methods {
magi_response_method_head head;
magi_response_method_start_body start_body;
magi_response_method_body body;
+ magi_response_method_fmt format;
magi_response_method_file file;
magi_response_method_close close;
} magi_response_methods;
diff --git a/src/cgi.c b/src/cgi.c
index 810d85e..0fd258e 100644
--- a/src/cgi.c
+++ b/src/cgi.c
@@ -85,7 +85,7 @@ static void cgi_cookies(magi_request *r)
r->cookies = 0;
return;
}
- if (strlen(env) > r->limits.cookies && r->limits.cookies) {
+ if ((int)strlen(env) > r->limits.cookies && r->limits.cookies) {
r->error = magi_error_limit;
return;
}
@@ -127,7 +127,7 @@ static void cgi_input_post(magi_error *e, char **input, int max)
return;
}
*input = magi_str_create(input_len);
- if (fread(*input, 1, input_len, stdin) != input_len) {
+ if ((int)fread(*input, 1, input_len, stdin) != input_len) {
*e = magi_error_length;
return;
}
@@ -154,6 +154,7 @@ static int next()
static void mhead(void *any, magi_param *header)
{
+ (void)any;
fputs(header->name, stdout);
fputs(": ", stdout);
fputs(header->data, stdout);
@@ -162,16 +163,25 @@ static void mhead(void *any, magi_param *header)
static void mstart_body(void *any)
{
+ (void)any;
fputs("\r\n", stdout);
}
static void mbody(void *any, const char *data, int len)
{
+ (void)any;
fwrite(data, 1, len, stdout);
}
+static void mformat(void *any, const char *format, va_list args)
+{
+ (void)any;
+ vprintf(format, args);
+}
+
static void mfile(void *any, FILE *file)
{
+ (void)any;
while (!feof(file)) {
char buf[64];
int len = fread(buf, 1, 64, file);
@@ -179,7 +189,7 @@ static void mfile(void *any, FILE *file)
}
}
-static void mclose(void *any) {}
+static void mclose(void *any) { (void)any; }
static void setup_response(magi_request *r)
{
@@ -187,6 +197,7 @@ static void setup_response(magi_request *r)
mhead,
mstart_body,
mbody,
+ mformat,
mfile,
mclose
};
diff --git a/src/cookies.c b/src/cookies.c
index 7e8248b..f5b030e 100644
--- a/src/cookies.c
+++ b/src/cookies.c
@@ -124,7 +124,7 @@ static st parse_name(automata *a, char c)
return state;
}
-static st parse_post_name(automata *a, char c)
+static st parse_post_name(char c)
{
st state;
if (c == '=') {
@@ -239,7 +239,7 @@ void magi_parse_cookies(magi_request *request, const char *data)
switch (state) {
case st_pre_name: state = parse_pre_name(&a, *data); break;
case st_name: state = parse_name(&a, *data); break;
- case st_post_name: state = parse_post_name(&a, *data); break;
+ case st_post_name: state = parse_post_name(*data); break;
case st_pre_data: state = parse_pre_data(&a, *data); break;
case st_data: state = parse_data(&a, *data); break;
case st_post_data: state = parse_post_data(&a, *data); break;
diff --git a/src/multipart.c b/src/multipart.c
index 72fe607..ef988b1 100644
--- a/src/multipart.c
+++ b/src/multipart.c
@@ -383,7 +383,7 @@ static st parse_data(automata *a, char c)
return data_add(a, c);
}
-static st parse_end(automata *a, char c) { return st_end; }
+static st parse_end() { return st_end; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -405,7 +405,7 @@ static void run_automata(automata *a,
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); break;
+ case st_end: state = parse_end(); break;
default: break;
}
c = next(next_userdata);
diff --git a/src/response.c b/src/response.c
index 400080a..dc36bb0 100644
--- a/src/response.c
+++ b/src/response.c
@@ -29,7 +29,7 @@ void magi_response_cookie(magi_request *r, const char *name, const char *data)
magi_param addon;
int nlen;
int dlen;
- if (r->response->head_done) {
+ if (r->response->head_done || !name || !data) {
return;
}
nlen = strlen(name);
@@ -45,22 +45,59 @@ void magi_response_cookie(magi_request *r, const char *name, const char *data)
void magi_response_cookie_complex(magi_request *r, magi_cookie *c)
{
magi_param addon;
- if (r->response->head_done) {
+ char *pointer;
+ int nlen, dlen, dsize, psize, msize;
+ const int cdsize = 9;
+ const int cpsize = 7;
+ const int cmsize = 10;
+ if (r->response->head_done || !c->name) {
return;
}
+ nlen = strlen(c->name);
+ dlen = c->data ? strlen(c->data) : 0;
+ dsize = c->domain ? strlen(c->domain) + cdsize : 0;
+ psize = c->path ? strlen(c->path) + cpsize : 0;
+ msize = c->max_age ? strlen(c->max_age) + cmsize : 0;
addon.name = magi_str_create_copy("Set-Cookie", 10);
- /* TODO */
+ addon.data = magi_str_create(nlen + dlen + dsize + psize + msize + 1);
+ pointer = addon.data;
+ memcpy(pointer, c->name, nlen);
+ pointer += nlen;
+ *pointer = '=';
+ ++pointer;
+ if (dlen) {
+ memcpy(pointer, c->data, dlen);
+ pointer += dlen;
+ }
+ if (dsize) {
+ memcpy(pointer, "; Domain=", cdsize);
+ memcpy(pointer + cdsize, c->domain, dsize - cdsize);
+ pointer += dsize;
+ }
+ if (psize) {
+ memcpy(pointer, "; Path=", cpsize);
+ memcpy(pointer + cpsize, c->path, psize - cpsize);
+ pointer += psize;
+ }
+ if (msize) {
+ memcpy(pointer, "; Max-Age=", cmsize);
+ memcpy(pointer + cmsize, c->max_age, msize - cmsize);
+ }
magi_params_add(&r->response->head_general, &addon);
}
void magi_response_cookie_discard(magi_request *r, const char *name)
{
magi_param addon;
- if (r->response->head_done) {
+ int len;
+ if (r->response->head_done || !name) {
return;
}
+ len = strlen(name);
addon.name = magi_str_create_copy("Set-Cookie", 10);
- /* TODO */
+ addon.data = malloc(len + 13);
+ memcpy(addon.data, name, len);
+ memcpy(addon.data + len, "=; Max-Age=1", 13);
magi_params_add(&r->response->head_general, &addon);
}
@@ -136,8 +173,11 @@ void magi_response(magi_request *r, const char *addon)
void magi_response_format(magi_request *r, const char *format, ...)
{
+ va_list args;
magi_response_head(r);
- /* TODO */
+ va_start(args, format);
+ r->response->methods->format(r->response->userdata, format, args);
+ va_end(args);
}
void magi_response_file(magi_request *r, FILE *file)
@@ -149,7 +189,6 @@ void magi_response_file(magi_request *r, FILE *file)
void magi_response_error(magi_request *r)
{
- /* TODO */
magi_response_status(r, 400, "Bad Request");
magi_response(r,
"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "