From 8acbd33a82d2c13e70eb17447bc6abfd86cf9512 Mon Sep 17 00:00:00 2001 From: Aleksey Veresov Date: Fri, 20 Mar 2020 23:06:46 +0300 Subject: [magi] --- Makefile | 114 +++++++++++++++++++++++++---------------------- examples/fastcgi.c | 33 ++++++++++++++ examples/fastcgi.todo | 34 -------------- examples/upload.c | 4 +- include/magi.h | 2 +- include/magi/cookie.h | 3 +- include/magi/fastcgi.h | 7 ++- include/magi/file.h | 2 +- include/magi/loadfile.h | 48 -------------------- include/magi/loadfiles.h | 48 ++++++++++++++++++++ include/magi/param.h | 2 +- include/magi/request.h | 13 +++--- include/magi/response.h | 2 +- include/magi/session.h | 17 +++++++ man/magi.3 | 2 +- src/cgi.c | 7 ++- src/cookie.c | 5 ++- src/fastcgi.c | 22 +++++++++ src/file.c | 2 +- src/loadfile.c | 78 -------------------------------- src/loadfiles.c | 78 ++++++++++++++++++++++++++++++++ src/multipart.c | 8 ++-- src/param.c | 2 +- src/request.c | 15 ++++--- src/session.c | 40 +++++++++++++++++ 25 files changed, 339 insertions(+), 249 deletions(-) create mode 100644 examples/fastcgi.c delete mode 100644 examples/fastcgi.todo delete mode 100644 include/magi/loadfile.h create mode 100644 include/magi/loadfiles.h create mode 100644 include/magi/session.h delete mode 100644 src/loadfile.c create mode 100644 src/loadfiles.c create mode 100644 src/session.c diff --git a/Makefile b/Makefile index df3856d..fc0cdac 100644 --- a/Makefile +++ b/Makefile @@ -2,91 +2,97 @@ # Compilation Options # 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 +MODULES ?= cgi fastcgi loadfiles urlenc # Specify your favourite C compiler here: CC ?= gcc # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Preparations -LIB = libmagi.a - # Compile under the most strict conditions: -CFLAGS = -xc -ansi -pedantic -Wall -Wextra +CFLAGS = -xc -ansi -pedantic -Wall -Wextra -MMD # Debug and optimisation are not compatible: ifeq '$(DEBUG)' 'yes' CFLAGS += -g -O0 else -CFLAGS += -O3 -static +CFLAGS += -O3 endif -# Interfacial files to compile: -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) -NAMES = $(notdir $(SRC:.c=)) -OBJ = $(foreach name,$(NAMES),$(BUILD)/$(SRC_DIR)/$(name).o) - -EXDIR = examples -EXSRC = $(wildcard $(EXDIR)/*.c) -EXNAMES = $(notdir $(EXSRC:.c=)) -EXAMPLES = $(foreach ex,$(EXNAMES),$(BUILD)/$(EXDIR)/$(ex)) +# Directories definitions: +INCLUDE = include +BUILD = build +SRCDIR = src +EXADIR = examples +# Library itself: +LIB = libmagi.a +# Modules: +EXTERNAL = cookie error file param request response session $(MODULES) +INTERNAL = cookies multipart tools urlencoded + +# Default target is library: +TARGET = $(BUILD)/$(LIB) +# Determing needed object files: +EXTER_H = $(foreach x,$(EXTERNAL:=.h),$(INCLUDE)/magi/$(x)) +EXTER_C = $(foreach x,$(EXTERNAL:=.c),$(SRCDIR)/$(x)) +INTER_H = $(foreach i,$(INTERNAL:=.h),$(SRCDIR)/$(i)) +INTER_C = $(INTER_H:.h=.c) +SRC = $(INTER_C) $(EXTER_C) +OBJ = $(foreach o,$(SRC:.c=.o),$(BUILD)/$(o)) +# Example executables: +EXASRC = $(wildcard $(EXADIR)/*.c) +EXAMPLES = $(foreach x,$(EXASRC:.c=),$(BUILD)/$(x)) +# Dependency files: +DEPS = $(OBJ:.o=.d) $(EXAMPLES:=.d) + +# Flags collections: +SRCFLAGS = $(CFLAGS) -I$(INCLUDE)/magi +EXAFLAGS = $(CFLAGS) -I$(INCLUDE) +LFLAGS = -static -L$(BUILD) -lmagi + +# Build directories: +BUILDIRS = $(BUILD) $(BUILD)/$(SRCDIR) $(BUILD)/$(EXADIR) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Targets -.PHONY: default clean examples +.PHONY: default examples clean clean-nontarget clean-deps clean-all -# 'make' produces library by default: -default: $(BUILD)/$(LIB) +default: $(TARGET) examples: $(EXAMPLES) -# Cleaning means removing everything automatically produced: -clean: +clean: clean-nontarget + rm -f $(TARGET) +clean-nontarget: clean-deps + rm -f $(OBJ) $(EXAMPLES) +clean-deps: + rm -f $(DEPS) +clean-all: rm -rf $(BUILD) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Compilation -# Compile object files from corresponding source and header: -$(BUILD)/$(SRC_DIR)/%.o: $(SRC_DIR)/%.c - $(CC) $(CFLAGS) -I $(INC_DIR) -c $< -o $@ +# No product should be in case of cleaning: +ifneq (clean,$(MAKECMDGOAL)) # Packing object files into library: -$(BUILD)/$(LIB): $(OBJ) - ar rcs $@ $^ +$(TARGET): $(OBJ) + ar -rcs $@ $^ + +# Compile object files from corresponding source: +$(BUILD)/%.o: %.c $(BUILDIRS) + $(CC) $(SRCFLAGS) -c $< -o $@ # Compile executables from corresponding sources and library: -$(BUILD)/$(EXDIR)/%: $(EXDIR)/%.c $(BUILD)/$(LIB) - $(CC) $(CFLAGS) -I include $< -L$(BUILD) -lmagi -o $@ +$(BUILD)/%: %.c $(TARGET) $(BUILDIRS) + $(CC) $(EXAFLAGS) $< $(LFLAGS) -o $@ +$(BUILDIRS): + mkdir -p $@ -# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -# Dependencies -$(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 $(BUILD)/deps.mk + +# Including dependency files: +-include $(DEPS) endif diff --git a/examples/fastcgi.c b/examples/fastcgi.c new file mode 100644 index 0000000..16668f3 --- /dev/null +++ b/examples/fastcgi.c @@ -0,0 +1,33 @@ +#include + + +void response(magi_request *r) +{ + magi_response(r, + "" + "" + "Fast CGI" + "Hi!" + ""); +} + +int main() +{ + magi_session session; + magi_request request; + magi_request_init(&request); + magi_session_init(&session); + magi_session_unix(&session, "unix.sock"); + while (magi_fastcgi(&session, &request)) { + if (request.error) { + magi_response_error(&request); + } else { + response(&request); + } + magi_request_free(&request); + } + magi_request_free(&request); + magi_session_free(&session); + return 0; +} diff --git a/examples/fastcgi.todo b/examples/fastcgi.todo deleted file mode 100644 index 5d3c4b1..0000000 --- a/examples/fastcgi.todo +++ /dev/null @@ -1,34 +0,0 @@ -#include - - -void response(magi_request *r) -{ - magi_response(r, - "" - "" - "Fast CGI" - "Hi!" - ""); -} - -int main(int argc, char const *argv[]) -{ - magi_session session; - magi_request request; - magi_request_init(&request); - magi_session_init(&session); - magi_session_inet(&session, "localhost", "9973"); - magi_session_unix(&session, "unix.sock"); - while (magi_fastcgi(&session, &request)) { - if (request.error) { - magi_response_error(&request); - } else { - response(&request); - } - magi_request_free(&request); - } - magi_request_free(&request); - magi_session_free(&session); - return 0; -} diff --git a/examples/upload.c b/examples/upload.c index 9a16dd1..bf8eed1 100644 --- a/examples/upload.c +++ b/examples/upload.c @@ -4,8 +4,8 @@ void response(magi_request *r) { - char *name = magi_request_param(r, "name"); - magi_file *data = magi_request_file(r, "data"); + char *name = magi_request_param(r, "name"); + const magi_file *data = magi_request_file(r, "data"); magi_response(r, "" diff --git a/include/magi.h b/include/magi.h index a5b047d..d8e1245 100644 --- a/include/magi.h +++ b/include/magi.h @@ -8,7 +8,7 @@ #include "magi/error.h" #include "magi/fastcgi.h" #include "magi/file.h" -#include "magi/loadfile.h" +#include "magi/loadfiles.h" #include "magi/param.h" #include "magi/request.h" #include "magi/response.h" diff --git a/include/magi/cookie.h b/include/magi/cookie.h index 96e4273..4760b75 100644 --- a/include/magi/cookie.h +++ b/include/magi/cookie.h @@ -30,7 +30,8 @@ void magi_cookies_add(magi_cookies **cookies, magi_cookie *newitem); /* 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); +const magi_cookie *magi_cookies_get(const magi_cookies *cookies, + const char *name); #endif diff --git a/include/magi/fastcgi.h b/include/magi/fastcgi.h index fb1f2e5..3d91b7b 100644 --- a/include/magi/fastcgi.h +++ b/include/magi/fastcgi.h @@ -2,10 +2,13 @@ #define MAGI_INCLUDED_FASTCGI /* Fast CGI implementation */ -/* * * TODO * * */ +#include "session.h" +#include "request.h" -enum { magi_to_avoid_warning }; +int magi_fastcgi_head(magi_session *s, magi_request *r); +int magi_fastcgi_body(magi_session *s, magi_request *r); +int magi_fastcgi(magi_session *s, magi_request *r); #endif diff --git a/include/magi/file.h b/include/magi/file.h index d4c5e98..cd3d675 100644 --- a/include/magi/file.h +++ b/include/magi/file.h @@ -25,7 +25,7 @@ void magi_files_free(magi_files *files); void magi_files_add(magi_files **files, magi_file *newitem); /* 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); +const magi_file *magi_files_get(const magi_files *files, const char *name); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/include/magi/loadfile.h b/include/magi/loadfile.h deleted file mode 100644 index bf3421c..0000000 --- a/include/magi/loadfile.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef MAGI_INCLUDED_LOADFILE -#define MAGI_INCLUDED_LOADFILE -/* 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_loadfiles_set. - * - * This module is optional. - */ -#include "request.h" - - -/* 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. */ -} magi_loadfile; - -/* Table of rules for loading files. - * Set count and files as null to initialize. */ -typedef struct magi_loadfiles { - int count; /* Size of files array.*/ - magi_loadfile *files; /* Dynamic array of rules to load files. */ -} magi_loadfiles; - - -/* 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); - - -/* Setup request to use loadfiles callback with table. */ -void magi_loadfiles_set(magi_request *request, magi_loadfiles *table); - - -#endif diff --git a/include/magi/loadfiles.h b/include/magi/loadfiles.h new file mode 100644 index 0000000..bf3421c --- /dev/null +++ b/include/magi/loadfiles.h @@ -0,0 +1,48 @@ +#ifndef MAGI_INCLUDED_LOADFILE +#define MAGI_INCLUDED_LOADFILE +/* 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_loadfiles_set. + * + * This module is optional. + */ +#include "request.h" + + +/* 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. */ +} magi_loadfile; + +/* Table of rules for loading files. + * Set count and files as null to initialize. */ +typedef struct magi_loadfiles { + int count; /* Size of files array.*/ + magi_loadfile *files; /* Dynamic array of rules to load files. */ +} magi_loadfiles; + + +/* 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); + + +/* Setup request to use loadfiles callback with table. */ +void magi_loadfiles_set(magi_request *request, magi_loadfiles *table); + + +#endif diff --git a/include/magi/param.h b/include/magi/param.h index 589db9f..c0879a9 100644 --- a/include/magi/param.h +++ b/include/magi/param.h @@ -29,7 +29,7 @@ void magi_params_set(magi_params **params, magi_param *newitem); /* 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); +char *magi_params_get(const magi_params *params, const char *name); #endif diff --git a/include/magi/request.h b/include/magi/request.h index 3d0d48a..7245feb 100644 --- a/include/magi/request.h +++ b/include/magi/request.h @@ -60,20 +60,21 @@ void magi_request_free(magi_request *r); /* Get value of meta-param with name. */ -char *magi_request_meta(magi_request *r, const char *name); +char *magi_request_meta(const 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); +char *magi_request_param(const 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); +char *magi_request_urlparam(const 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); +const magi_file *magi_request_file(const magi_request *r, const char *name); /* Get value of cookie with name. */ -char *magi_request_cookie(magi_request *r, const char *name); +char *magi_request_cookie(const magi_request *r, const char *name); /* Get cookie with name. */ -magi_cookie *magi_request_cookie_complex(magi_request *r, const char *name); +const magi_cookie *magi_request_cookie_complex(const magi_request *r, + const char *name); #endif diff --git a/include/magi/response.h b/include/magi/response.h index 4b71ef5..11acf75 100644 --- a/include/magi/response.h +++ b/include/magi/response.h @@ -4,7 +4,7 @@ * * 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). + * Defult content-type is HTML, status is 200 (OK). * * Use body related functions only after dealing with headers. * (Since storing possibly large body in memory is a bad idea, diff --git a/include/magi/session.h b/include/magi/session.h new file mode 100644 index 0000000..c1c5903 --- /dev/null +++ b/include/magi/session.h @@ -0,0 +1,17 @@ +#ifndef MAGI_INCLUDED_SESSION +#define MAGI_INCLUDED_SESSION + + +typedef struct magi_session { + int socket; +} magi_session; + + +void magi_session_init(magi_session *s); +void magi_session_free(magi_session *s); + +int magi_session_inet(magi_session *s, const char *address, int port); +int magi_session_unix(magi_session *s, const char *path); + + +#endif diff --git a/man/magi.3 b/man/magi.3 index f7d64b8..0c7ed1a 100644 --- a/man/magi.3 +++ b/man/magi.3 @@ -1,4 +1,4 @@ -.TH MAGI 3 "2020.03.14" "0.1" "Magi Library" +.TH MAGI 3 "2020-03-18" "0.1" "Magi Library" .SH NAME magi \- ANSI C dependency-free CGI and FastCGI library .SH LIBRARY diff --git a/src/cgi.c b/src/cgi.c index 0fd258e..7b0551d 100644 --- a/src/cgi.c +++ b/src/cgi.c @@ -161,9 +161,8 @@ static void mhead(void *any, magi_param *header) fputs("\r\n", stdout); } -static void mstart_body(void *any) +static void mstart_body() { - (void)any; fputs("\r\n", stdout); } @@ -189,7 +188,7 @@ static void mfile(void *any, FILE *file) } } -static void mclose(void *any) { (void)any; } +static void mclose() {} static void setup_response(magi_request *r) { @@ -208,7 +207,7 @@ static void setup_response(magi_request *r) r->response->head_general = 0; r->response->head_entity = 0; r->response->head_done = 0; - magi_response_content_type(r, "application/xhtml+xml"); + magi_response_content_type(r, "text/html"); magi_response_status(r, 200, "OK"); } diff --git a/src/cookie.c b/src/cookie.c index 7b40f1a..a64f5cb 100644 --- a/src/cookie.c +++ b/src/cookie.c @@ -14,9 +14,10 @@ void magi_cookies_add(magi_cookies **cookies, magi_cookie *newitem) } } -magi_cookie *magi_cookies_get(magi_cookies *cookies, const char *name) +const magi_cookie *magi_cookies_get(const magi_cookies *cookies, + const char *name) { - magi_cookie *res = 0; + const magi_cookie *res = 0; if (!cookies || !name) { return 0; } diff --git a/src/fastcgi.c b/src/fastcgi.c index 39c57ca..8959c14 100644 --- a/src/fastcgi.c +++ b/src/fastcgi.c @@ -1 +1,23 @@ #include "fastcgi.h" + + +int magi_fastcgi_head(magi_session *s, magi_request *r) +{ + (void)s; + (void)r; + return 1; +} + + +int magi_fastcgi_body(magi_session *s, magi_request *r) +{ + (void)s; + (void)r; + return 1; +} + + +int magi_fastcgi(magi_session *s, magi_request *r) +{ + return magi_fastcgi_head(s, r) && magi_fastcgi_body(s, r); +} diff --git a/src/file.c b/src/file.c index dd4802a..7e3d2f8 100644 --- a/src/file.c +++ b/src/file.c @@ -14,7 +14,7 @@ void magi_files_add(magi_files **files, magi_file *newitem) } } -magi_file *magi_files_get(magi_files *files, const char *name) +const magi_file *magi_files_get(const magi_files *files, const char *name) { if (!files || !name) { return 0; diff --git a/src/loadfile.c b/src/loadfile.c deleted file mode 100644 index d76f562..0000000 --- a/src/loadfile.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "loadfile.h" - -#include -#include -#include - - -void magi_loadfiles_add(magi_loadfiles *table, - const char *name, - const char *path, - int max) -{ - static const int size = sizeof(*table->files); - if (!table) { - return; - } - if (table->count) { - table->files = realloc(table->files, size * table->count + size); - } else { - table->files = malloc(size); - } - table->files[table->count].name = name; - table->files[table->count].path = path; - table->files[table->count].max = max; - table->count++; -} - -void magi_loadfiles_free(magi_loadfiles *table) -{ - if (!table) { - return; - } - free(table->files); - table->count = 0; -} - -static void loadfiles(void *userdata, - magi_file *file, - char *addon, - int addon_len) -{ - magi_loadfiles *table = userdata; - int pos; - if (!file->filename || !strcmp(file->filename, "")) { - return; - } - for (pos = 0; pos != table->count; ++pos) { - if (!strcmp(table->files[pos].name, file->field)) { - static FILE *f = 0; - static int unlimited; - static int left; - if (!f) { - const char *path = table->files[pos].path; - f = fopen(path, "wb"); - left = table->files[pos].max; - unlimited = !left; - } - if (unlimited) { - fwrite(addon, 1, addon_len, f); - } else { - int min = left < addon_len ? left : addon_len; - fwrite(addon, 1, min, f); - left -= min; - } - if (!addon_len) { - fclose(f); - f = 0; - } - return; - } - } -} - -void magi_loadfiles_set(magi_request *request, magi_loadfiles *table) -{ - request->callback.act = loadfiles; - request->callback.userdata = table; -} diff --git a/src/loadfiles.c b/src/loadfiles.c new file mode 100644 index 0000000..b3efff7 --- /dev/null +++ b/src/loadfiles.c @@ -0,0 +1,78 @@ +#include "loadfiles.h" + +#include +#include +#include + + +void magi_loadfiles_add(magi_loadfiles *table, + const char *name, + const char *path, + int max) +{ + static const int size = sizeof(*table->files); + if (!table) { + return; + } + if (table->count) { + table->files = realloc(table->files, size * table->count + size); + } else { + table->files = malloc(size); + } + table->files[table->count].name = name; + table->files[table->count].path = path; + table->files[table->count].max = max; + table->count++; +} + +void magi_loadfiles_free(magi_loadfiles *table) +{ + if (!table) { + return; + } + free(table->files); + table->count = 0; +} + +static void loadfiles(void *userdata, + magi_file *file, + char *addon, + int addon_len) +{ + magi_loadfiles *table = userdata; + int pos; + if (!file->filename || !strcmp(file->filename, "")) { + return; + } + for (pos = 0; pos != table->count; ++pos) { + if (!strcmp(table->files[pos].name, file->field)) { + static FILE *f = 0; + static int unlimited; + static int left; + if (!f) { + const char *path = table->files[pos].path; + f = fopen(path, "wb"); + left = table->files[pos].max; + unlimited = !left; + } + if (unlimited) { + fwrite(addon, 1, addon_len, f); + } else { + int min = left < addon_len ? left : addon_len; + fwrite(addon, 1, min, f); + left -= min; + } + if (!addon_len) { + fclose(f); + f = 0; + } + return; + } + } +} + +void magi_loadfiles_set(magi_request *request, magi_loadfiles *table) +{ + request->callback.act = loadfiles; + request->callback.userdata = table; +} diff --git a/src/multipart.c b/src/multipart.c index 2284ced..d2a1c7f 100644 --- a/src/multipart.c +++ b/src/multipart.c @@ -63,10 +63,10 @@ static char *extract_filename(char *n) if (!n) { return 0; } - n += strspn(n, " \t") + 1; + n += strspn(n + 1, " \t") + 1; if (*n == '"') { ++n; - return magi_str_create_copy(n, n - strchr(n, '"')); + return magi_str_create_copy(n, strchr(n, '"') - n); } else { return magi_str_create_copy(n, strcspn(n, " \t")); } @@ -78,10 +78,10 @@ static int content_disposition(automata *a) if (!n) { return 0; } - n += strspn(n, " \t") + 1; + n += strspn(n + 1, " \t") + 1; if (*n == '"') { ++n; - a->param.name = magi_str_create_copy(n, n - strchr(n, '"')); + a->param.name = magi_str_create_copy(n, strchr(n, '"') - n); if (!a->param.name || !*a->param.name) { return 0; } diff --git a/src/param.c b/src/param.c index 9c94555..dcf33d4 100644 --- a/src/param.c +++ b/src/param.c @@ -28,7 +28,7 @@ void magi_params_set(magi_params **params, magi_param *newitem) } } -char *magi_params_get(magi_params *params, const char *name) +char *magi_params_get(const magi_params *params, const char *name) { if (!params || !name) { return 0; diff --git a/src/request.c b/src/request.c index ce0f84f..d80bf20 100644 --- a/src/request.c +++ b/src/request.c @@ -69,12 +69,12 @@ void magi_request_free(magi_request *request) } -char *magi_request_meta(magi_request *r, const char *name) +char *magi_request_meta(const magi_request *r, const char *name) { return magi_params_get(r->meta, name); } -char *magi_request_param(magi_request *r, const char *name) +char *magi_request_param(const magi_request *r, const char *name) { char *res = magi_params_get(r->body, name); if (!res) { @@ -83,26 +83,27 @@ char *magi_request_param(magi_request *r, const char *name) return res; } -char *magi_request_urlparam(magi_request *r, const char *name) +char *magi_request_urlparam(const magi_request *r, const char *name) { return magi_params_get(r->head, name); } -magi_file *magi_request_file(magi_request *r, const char *name) +const magi_file *magi_request_file(const magi_request *r, const char *name) { return magi_files_get(r->files, name); } -char *magi_request_cookie(magi_request *r, const char *name) +char *magi_request_cookie(const magi_request *r, const char *name) { - magi_cookie *res = magi_cookies_get(r->cookies, name); + const magi_cookie *res = magi_cookies_get(r->cookies, name); if (!res) { return 0; } return res->data; } -magi_cookie *magi_request_cookie_complex(magi_request *r, const char *name) +const magi_cookie *magi_request_cookie_complex(const magi_request *r, + const char *name) { return magi_cookies_get(r->cookies, name); } diff --git a/src/session.c b/src/session.c new file mode 100644 index 0000000..35e9200 --- /dev/null +++ b/src/session.c @@ -0,0 +1,40 @@ +#include "session.h" + +#include +#include +#include +#include + + +void magi_session_init(magi_session *s) +{ + s->socket = 0; +} + +void magi_session_free(magi_session *s) +{ + if (s->socket) { + shutdown(s->socket, SHUT_RDWR); + s->socket = 0; + } +} + + +int magi_session_inet(magi_session *s, const char *address, int port) +{ + struct sockaddr_in addr; + s->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = inet_addr(address); + return !connect(s->socket, (struct sockaddr *)&addr, sizeof(addr)); +} + +int magi_session_unix(magi_session *s, const char *path) +{ + struct sockaddr_un addr; + s->socket = socket(AF_UNIX, SOCK_STREAM, IPPROTO_TCP); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); + return !connect(s->socket, (struct sockaddr *)&addr, sizeof(addr)); +} -- cgit v1.2.3