aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Veresov <aleksey@veresov.pro>2020-03-20 23:06:46 +0300
committerAleksey Veresov <aleksey@veresov.pro>2020-03-20 23:06:46 +0300
commit8acbd33a82d2c13e70eb17447bc6abfd86cf9512 (patch)
treef89d1c6ec04e3ba418b63c37202d6abc4f08138e
parentfcffb003f36a4357b6ba88e6b5e2239d7d111a6a (diff)
downloadmagi-8acbd33a82d2c13e70eb17447bc6abfd86cf9512.tar
magi-8acbd33a82d2c13e70eb17447bc6abfd86cf9512.tar.xz
magi-8acbd33a82d2c13e70eb17447bc6abfd86cf9512.zip
[magi]
-rw-r--r--Makefile114
-rw-r--r--examples/fastcgi.c (renamed from examples/fastcgi.todo)3
-rw-r--r--examples/upload.c4
-rw-r--r--include/magi.h2
-rw-r--r--include/magi/cookie.h3
-rw-r--r--include/magi/fastcgi.h7
-rw-r--r--include/magi/file.h2
-rw-r--r--include/magi/loadfiles.h (renamed from include/magi/loadfile.h)0
-rw-r--r--include/magi/param.h2
-rw-r--r--include/magi/request.h13
-rw-r--r--include/magi/response.h2
-rw-r--r--include/magi/session.h17
-rw-r--r--man/magi.32
-rw-r--r--src/cgi.c7
-rw-r--r--src/cookie.c5
-rw-r--r--src/fastcgi.c22
-rw-r--r--src/file.c2
-rw-r--r--src/loadfiles.c (renamed from src/loadfile.c)2
-rw-r--r--src/multipart.c8
-rw-r--r--src/param.c2
-rw-r--r--src/request.c15
-rw-r--r--src/session.c40
22 files changed, 182 insertions, 92 deletions
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.todo b/examples/fastcgi.c
index 5d3c4b1..16668f3 100644
--- a/examples/fastcgi.todo
+++ b/examples/fastcgi.c
@@ -12,13 +12,12 @@ void response(magi_request *r)
"</html>");
}
-int main(int argc, char const *argv[])
+int main()
{
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) {
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,
"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
"'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>"
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/loadfiles.h
index bf3421c..bf3421c 100644
--- a/include/magi/loadfile.h
+++ b/include/magi/loadfiles.h
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/loadfiles.c
index d76f562..b3efff7 100644
--- a/src/loadfile.c
+++ b/src/loadfiles.c
@@ -1,4 +1,4 @@
-#include "loadfile.h"
+#include "loadfiles.h"
#include <stdio.h>
#include <stdlib.h>
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 <arpa/inet.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+
+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));
+}