kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit ae5da79f619f34871ad61981ee63638dd3bc8dae
parent c9f5bb82c9ae27d06b437a6aa8e79c1f134348a4
Author: Joris Vink <joris@coders.se>
Date:   Mon, 24 Jun 2013 18:22:35 +0200

new build script for modules, which should be used as a base for
all new modules written by others.

Diffstat:
README | 2+-
docs/TODO | 2--
example.conf | 59-----------------------------------------------------------
example/Makefile | 49-------------------------------------------------
example/css/style.css | 16----------------
example/html/index.html | 14--------------
example/html/profile.html | 14--------------
example/src/example.c | 99-------------------------------------------------------------------------------
example/tools/html_inject.c | 83-------------------------------------------------------------------------------
modules/example/build.sh | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/example/media/index.html | 15+++++++++++++++
modules/example/media/style.css | 16++++++++++++++++
modules/example/module.conf | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/example/src/example.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/example/static.h | 18++++++++++++++++++
modules/example/tools/inject.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16 files changed, 363 insertions(+), 337 deletions(-)

diff --git a/README b/README @@ -30,6 +30,6 @@ Platforms support Any other BSD might function, but is untested. Right now Kore development is a moving process, so expect bugs. -If you run into said bugs please contact me at patches@coders.se. +If you run into said bugs please contact me at joris@coders.se. More information can be found on https://kore.io/ diff --git a/docs/TODO b/docs/TODO @@ -1,6 +1,4 @@ -*BSD support Auxiliary library framework -Better logging facilities Ability to load one module per domain GET arguments (only POST supported) POST multiform/form-data support diff --git a/example.conf b/example.conf @@ -1,59 +0,0 @@ -# Example Kore configuration - -# Server configuration. -bind 10.211.55.3 443 - -# The path worker processes will chroot too after starting. -chroot /home/joris/src/kore - -# Worker processes will run as the specified user. -runas joris - -# Set workers to the amount of CPU's available in your system, -# kore will automatically distribute all workers on them. -workers 2 - -# Store the main process its pid in this file. -#pidfile /var/run/kore.pid - -# The onload function is called everytime the module is loaded or reloaded. -#onload myinit - -# Specifies what module to be loaded. -load example/example.module - -# Domain configuration -# -# Each domain configuration starts with listing what domain -# the directives that follow are to be applied upon. -# -# Additionally you can specify the following in a domain configuration: -# -# accesslog: File where all requests are logged. -# -# Handlers -# -# Handlers are either static (for fixed paths) or dynamic. -# Dynamic handlers take a POSIX regular expression as its path. -# -# Syntax: -# handler path module_callback - -# Example domain that responds to 10.211.55.33. -domain 10.211.55.3 { - certfile cert/server.crt - certkey cert/server.key - accesslog /var/log/kore_access.log - static /css/style.css serve_style_css - static / serve_index - dynamic ^/[a-z0-9_]*$ serve_profile -} - -#domain domain.com { -# certfile cert/other/server.crt -# certkey cert/other/server.key -# accesslog /var/log/other_kore_access.log -# static /css/style.css serve_style_css -# static / serve_index -# dynamic ^/[a-z0-9_]*$ serve_profile -#} diff --git a/example/Makefile b/example/Makefile @@ -1,49 +0,0 @@ -# Example Kore module - -.SUFFIXES: .html .css - -CC=gcc -BIN=example.module - -HTML= html/index.html html/profile.html -H_SRCS= $(HTML:.html=.c) - -CSS= css/style.css -C_SRCS= $(CSS:.css=.c) - -S_SRC= src/example.c $(H_SRCS) $(C_SRCS) -S_OBJS= $(S_SRC:.c=.o) - -CFLAGS+=-I. -I../includes -CFLAGS+=-Wall -Wstrict-prototypes -Wmissing-prototypes -CFLAGS+=-Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual -CFLAGS+=-Wsign-compare -g -LDFLAGS+=-shared - -all: - make clean - make example.module - -example.module: html_inject $(H_SRCS) $(C_SRCS) $(S_OBJS) - $(CC) $(LDFLAGS) $(S_OBJS) -o $(BIN) - make clean_o - -html_inject: tools/html_inject.c - $(CC) $(CFLAGS) tools/html_inject.c -o tools/html_inject - -.html.c: - tools/html_inject $< `basename $<` > $@ - -.css.c: - tools/html_inject $< `basename $<` > $@ - -.c.o: - $(CC) -fPIC $(CFLAGS) -c $< -o $@ - -clean: - make clean_o - rm -f css/*.c html/*.c tools/html_inject $(BIN) - rm -f static.h - -clean_o: - rm -f css/*.o html/*.o src/*.o diff --git a/example/css/style.css b/example/css/style.css @@ -1,16 +0,0 @@ -body { - width: 100%; - margin: 0px; - color: #000; - overflow: hidden; - background-color: #fff; -} - -.content { - width: 800px; - margin-left: auto; - margin-right: auto; - margin-top: 100px; - font-size: 60px; - text-align: center; -} diff --git a/example/html/index.html b/example/html/index.html @@ -1,14 +0,0 @@ -<!DOCTYPE> -<head> - <link rel="stylesheet" href="/css/style.css" type="text/css"> - <title>Your KORE module worked!</title> -</head> - -<body> - -<div class="content"> - <p>Your first Kore module worked.</p> -</div> - -</body> -</html> diff --git a/example/html/profile.html b/example/html/profile.html @@ -1,14 +0,0 @@ -<!DOCTYPE> -<head> - <link rel="stylesheet" href="/css/style.css" type="text/css"> - <title>Your KORE module worked!</title> -</head> - -<body> - -<div class="content"> - <p>This is a dynamic (regex) path example</p> -</div> - -</body> -</html> diff --git a/example/src/example.c b/example/src/example.c @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013 Joris Vink <joris@coders.se> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/queue.h> - -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <openssl/err.h> -#include <openssl/ssl.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <regex.h> -#include <unistd.h> -#include <zlib.h> - -#include "spdy.h" -#include "kore.h" -#include "http.h" - -#include "static.h" - -int serve_style_css(struct http_request *); -int serve_index(struct http_request *); -int serve_profile(struct http_request *); - -int -serve_style_css(struct http_request *req) -{ - int ret; - char *date; - time_t tstamp; - - if (http_request_header_get(req, "if-modified-since", &date)) { - tstamp = kore_date_to_time(date); - free(date); - - kore_debug("header was present with %ld", tstamp); - } - - tstamp = 0; - if (tstamp != 0 && tstamp <= static_mtime_css_style) { - ret = http_response(req, 304, NULL, 0); - } else { - date = kore_time_to_date(static_mtime_css_style); - if (date != NULL) - http_response_header_add(req, "last-modified", date); - - http_response_header_add(req, "content-type", "text/css"); - ret = http_response(req, 200, static_css_style, - static_len_css_style); - } - - return (ret); -} - -int -serve_index(struct http_request *req) -{ - int ret; - - http_response_header_add(req, "content-type", "text/html"); - ret = http_response(req, 200, static_html_index, - static_len_html_index); - - return (ret); -} - -int -serve_profile(struct http_request *req) -{ - int ret; - - http_response_header_add(req, "content-type", "text/html"); - ret = http_response(req, 200, static_html_profile, - static_len_html_profile); - - return (ret); -} diff --git a/example/tools/html_inject.c b/example/tools/html_inject.c @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2013 Joris Vink <joris@coders.se> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/param.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -int -main(int argc, char *argv[]) -{ - struct stat st; - size_t len; - FILE *fp, *hdr; - char *ext, *p, *c, buf[1024]; - - if (argc != 3) - err(1, "arguments"); - if ((fp = fopen(argv[1], "r")) == NULL) - err(1, "fopen() %d", errno); - if ((hdr = fopen("static.h", "a+")) == NULL) - err(1, "fopen() %d", errno); - if ((ext = strchr(argv[2], '.')) != NULL) - *(ext)++ = '\0'; - - if (stat(argv[1], &st) == -1) { - printf("stat(%s) failed: %d\n", argv[1], errno); - exit(99); - } - - printf("/**** AUTO GENERATED BY MAKEFILE - DO NOT TOUCH ****/\n"); - printf("#include <sys/param.h>\n\n"); - printf("u_int8_t *static_%s_%s = (u_int8_t *)", ext, argv[2]); - - len = 0; - while (fgets(buf, sizeof(buf), fp)) { - if ((p = strchr(buf, '\n')) != NULL) - *p = '\0'; - - printf("\n\t\""); - for (c = buf; *c != '\0'; c++) { - if (*c == '"' || *c == '\\') - printf("\\"); - printf("%c", *c); - len++; - } - - printf("\\n\""); - len++; - } - - fclose(fp); - - printf(";\n\n"); - printf("u_int32_t static_len_%s_%s = %ld;\n", ext, argv[2], len); - printf("time_t static_mtime_%s_%s = %ld;\n", ext, argv[2], st.st_mtime); - - fprintf(hdr, "extern u_int8_t *static_%s_%s;\n", ext, argv[2]); - fprintf(hdr, "extern u_int32_t static_len_%s_%s;\n", ext, argv[2]); - fprintf(hdr, "extern time_t static_mtime_%s_%s;\n", ext, argv[2]); - fclose(hdr); - - return (0); -} diff --git a/modules/example/build.sh b/modules/example/build.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# +# Copyright (c) 2013 Joris Vink <joris@coders.se> +# +# Kore module build script, use this as a base for building +# your own modules for kore. + +# The name of the module you will be building +MODULE=example.module + +# The directory containing all your media files (HTML, CSS, ...). +# These files will be compiled into the module and symbols will +# be exported for you to use in your code (see static.h after building). +MEDIA_DIR=media + +# The directory containing your module source. +SOURCE_DIR=src + +# The directory containing the Kore source code. +KORE_DIR=../../ + +# Compiler settings. +CC=gcc +CFLAGS="-I. -I${KORE_DIR}includes -Wall -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations -Wshadow \ + -Wpointer-arith -Wcast-qual -Wsign-compare -g" +LDFLAGS+=-shared + +# Functions used in the build process. +function create_and_empty_dir { + if [ ! -d $1 ]; then + mkdir $1; + fi + + rm -f $1/* +} + +### Begin building #### +echo "Building module ${MODULE}..." +rm -f ${MODULE} + +${CC} ${CFLAGS} tools/inject.c -o tools/inject + +create_and_empty_dir ${SOURCE_DIR}/${MEDIA_DIR} +create_and_empty_dir .objs + +for file in `find ${MEDIA_DIR} -type f`; do + echo "Injecting $file"; + base=`basename $file`; + ./tools/inject $file $base > ${SOURCE_DIR}/${MEDIA_DIR}/${base}.c; + if [ $? -ne 0 ]; then + echo "Injection error, check above messages for clues."; + exit 1; + fi +done + +for src in `find ${SOURCE_DIR} -type f`; do + base=`basename $src`; + ${CC} ${CFLAGS} -fPIC -c $src -o .objs/${base}.o + if [ $? -ne 0 ]; then + echo "Build error, check above messages for clues."; + exit 1; + fi +done + +${CC} ${LDFLAGS} `find .objs -name \*.o -type f` -o ${MODULE} +echo "Building completed!" + +rm -rf ${SOURCE_DIR}/${MEDIA_DIR} +rm -rf .objs +rm -f tools/inject diff --git a/modules/example/media/index.html b/modules/example/media/index.html @@ -0,0 +1,15 @@ +<!DOCTYPE> +<html> +<head> + <link rel="stylesheet" href="/css/style.css" type="text/css"> + <title>Your KORE module worked!</title> +</head> + +<body> + +<div class="content"> + <p>Your first Kore module worked.</p> +</div> + +</body> +</html> diff --git a/modules/example/media/style.css b/modules/example/media/style.css @@ -0,0 +1,16 @@ +body { + width: 100%; + margin: 0px; + color: #000; + overflow: hidden; + background-color: #fff; +} + +.content { + width: 800px; + margin-left: auto; + margin-right: auto; + margin-top: 100px; + font-size: 60px; + text-align: center; +} diff --git a/modules/example/module.conf b/modules/example/module.conf @@ -0,0 +1,58 @@ +# Example Kore configuration + +# Server configuration. +bind 10.211.55.3 443 + +# The path worker processes will chroot too after starting. +chroot /home/joris/src/kore + +# Worker processes will run as the specified user. +runas joris + +# Set workers to the amount of CPU's available in your system, +# kore will automatically distribute all workers on them. +workers 2 + +# Store the main process its pid in this file. +#pidfile /var/run/kore.pid + +# The onload function is called everytime the module is loaded or reloaded. +#onload myinit + +# Specifies what module to be loaded. +load ./example.module + +# Domain configuration +# +# Each domain configuration starts with listing what domain +# the directives that follow are to be applied upon. +# +# Additionally you can specify the following in a domain configuration: +# +# accesslog: File where all requests are logged. +# +# Handlers +# +# Handlers are either static (for fixed paths) or dynamic. +# Dynamic handlers take a POSIX regular expression as its path. +# +# Syntax: +# handler path module_callback + +# Example domain that responds to 10.211.55.33. +domain 10.211.55.3 { + certfile cert/server.crt + certkey cert/server.key + accesslog /var/log/kore_access.log + static /css/style.css serve_style_css + static / serve_index +} + +#domain domain.com { +# certfile cert/other/server.crt +# certkey cert/other/server.key +# accesslog /var/log/other_kore_access.log +# static /css/style.css serve_style_css +# static / serve_index +# dynamic ^/[a-z0-9_]*$ serve_profile +#} diff --git a/modules/example/src/example.c b/modules/example/src/example.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013 Joris Vink <joris@coders.se> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/queue.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <openssl/err.h> +#include <openssl/ssl.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <regex.h> +#include <unistd.h> +#include <zlib.h> + +#include "spdy.h" +#include "kore.h" +#include "http.h" + +#include "static.h" + +int serve_style_css(struct http_request *); +int serve_index(struct http_request *); + +int +serve_style_css(struct http_request *req) +{ + int ret; + char *date; + time_t tstamp; + + if (http_request_header_get(req, "if-modified-since", &date)) { + tstamp = kore_date_to_time(date); + free(date); + + kore_debug("header was present with %ld", tstamp); + } + + tstamp = 0; + if (tstamp != 0 && tstamp <= static_mtime_css_style) { + ret = http_response(req, 304, NULL, 0); + } else { + date = kore_time_to_date(static_mtime_css_style); + if (date != NULL) + http_response_header_add(req, "last-modified", date); + + http_response_header_add(req, "content-type", "text/css"); + ret = http_response(req, 200, static_css_style, + static_len_css_style); + } + + return (ret); +} + +int +serve_index(struct http_request *req) +{ + int ret; + + http_response_header_add(req, "content-type", "text/html"); + ret = http_response(req, 200, static_html_index, + static_len_html_index); + + return (ret); +} diff --git a/modules/example/static.h b/modules/example/static.h @@ -0,0 +1,18 @@ +extern u_int8_t static_css_style[]; +extern u_int32_t static_len_css_style; +extern time_t static_mtime_css_style; +extern u_int8_t static_html_index[]; +extern u_int32_t static_len_html_index; +extern time_t static_mtime_html_index; +extern u_int8_t static_css_style[]; +extern u_int32_t static_len_css_style; +extern time_t static_mtime_css_style; +extern u_int8_t static_html_index[]; +extern u_int32_t static_len_html_index; +extern time_t static_mtime_html_index; +extern u_int8_t static_css_style[]; +extern u_int32_t static_len_css_style; +extern time_t static_mtime_css_style; +extern u_int8_t static_html_index[]; +extern u_int32_t static_len_html_index; +extern time_t static_mtime_html_index; diff --git a/modules/example/tools/inject.c b/modules/example/tools/inject.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013 Joris Vink <joris@coders.se> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/stat.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int +main(int argc, char *argv[]) +{ + struct stat st; + ssize_t len; + FILE *hdr; + char *ext, c[1]; + int fd, newline, count; + + if (argc != 3) + exit(1); + + if ((fd = open(argv[1], O_RDONLY)) == -1) + err(1, "open() %d", errno); + if ((hdr = fopen("static.h", "a+")) == NULL) + err(1, "fopen() %d", errno); + if ((ext = strchr(argv[2], '.')) != NULL) + *(ext)++ = '\0'; + else + ext = ""; + + if (stat(argv[1], &st) == -1) { + printf("stat(%s) failed: %d\n", argv[1], errno); + exit(1); + } + + printf("/**** AUTO GENERATED BY MAKEFILE - DO NOT TOUCH ****/\n"); + printf("#include <sys/param.h>\n\n"); + printf("u_int8_t static_%s_%s[] = {", ext, argv[2]); + + len = 0; + count = 0; + newline = 1; + for (;;) { + if (newline) { + printf("\n\t"); + count = 0; + newline = 0; + } + + len = read(fd, c, 1); + if (len == 0) + break; + + if (len == -1) { + printf("read(): %d\n", errno); + exit(1); + } + + if (len != 1) + exit(1); + + printf("0x%02x, ", c[0]); + if (count++ == 10) + newline = 1; + } + + close(fd); + + printf("};\n\n"); + printf("u_int32_t static_len_%s_%s = %ld;\n", ext, argv[2], st.st_size); + printf("time_t static_mtime_%s_%s = %ld;\n", ext, argv[2], st.st_mtime); + + fprintf(hdr, "extern u_int8_t static_%s_%s[];\n", ext, argv[2]); + fprintf(hdr, "extern u_int32_t static_len_%s_%s;\n", ext, argv[2]); + fprintf(hdr, "extern time_t static_mtime_%s_%s;\n", ext, argv[2]); + fclose(hdr); + + return (0); +}