commit 5090ebea20215fe14b5d5250eba6b7b9ddd13b8a
parent 2821eccdfa009ffcf2ede1c9f2aec1c85d69782d
Author: Joris Vink <joris@coders.se>
Date: Wed, 2 Jul 2014 12:16:31 +0200
Move contrib/modules to contrib/examples
Diffstat:
44 files changed, 1658 insertions(+), 1658 deletions(-)
diff --git a/contrib/examples/generic/build.sh b/contrib/examples/generic/build.sh
@@ -0,0 +1,82 @@
+#!/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.
+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"
+
+OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
+if [ "${OSNAME}" = "darwin" ]; then
+ LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
+else
+ LDFLAGS="-shared"
+fi
+
+MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
+
+### Begin building ####
+echo "Building module ${MODULE}..."
+rm -f ${MODULE}
+
+${CC} ${CFLAGS} tools/inject.c -o tools/inject
+
+if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
+ mkdir ${SOURCE_DIR}/${MEDIA_DIR};
+fi
+rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
+
+if [ ! -d .objs ]; then
+ mkdir .objs;
+fi
+rm -f .objs/*
+
+rm -f static.h
+
+for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; 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
+
+echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
+
+for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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
+rm -f static.h
diff --git a/contrib/examples/generic/media/index.html b/contrib/examples/generic/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/contrib/examples/generic/media/intro.jpg b/contrib/examples/generic/media/intro.jpg
Binary files differ.
diff --git a/contrib/examples/generic/media/params.html b/contrib/examples/generic/media/params.html
@@ -0,0 +1,33 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore params test</title>
+</head>
+
+<body style="overflow: auto">
+
+<div class="content" style="font-size: 12px; font-weight: normal">
+ <p>You can pass one GET parameter (arg1), any other GET parameter will
+ be filtered out</p>
+ <p>Only two out of the three input fields will be visible to Kore.</p>
+ <p>The first field accepts the input "test"</p>
+ <p>The second field accepts anything like /test/[a-z]*</p>
+ <p>The third field will be removed by Kore, as it is not in the params
+ block configured for this page.</p>
+ <form method="POST">
+ <input type="input" name="test1" value="$test1$">
+ <input type="input" name="test2" value="$test2$">
+ <input type="input" name="test3" value="$test3$">
+ <input type="submit">
+ </form>
+
+ <p style="font-size: 12px; font-weight: normal">GET param arg1: $arg1$</p>
+ <p style="font-size: 12px; font-weight: normal">GET param arg2: $arg2$</p>
+ <p style="font-size: 12px; font-weight: normal">test1: $test1$</p>
+ <p style="font-size: 12px; font-weight: normal">test2: $test2$</p>
+ <p style="font-size: 12px; font-weight: normal">test3: $test3$</p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/examples/generic/media/private.html b/contrib/examples/generic/media/private.html
@@ -0,0 +1,16 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore Authentication tests</title>
+</head>
+
+<body>
+
+<div class="content">
+ <p style="font-size: small">The cookie session_id should now be set.</p>
+ <p style="font-size: small">You can continue to <a href="/private/test">view page handler in auth block</a></p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/examples/generic/media/private_test.html b/contrib/examples/generic/media/private_test.html
@@ -0,0 +1,15 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore Authentication tests</title>
+</head>
+
+<body>
+
+<div class="content">
+ <p style="font-size: small">If you see this, the authentication worked. This page should redirect back to /private once you remove your session_id cookie.</p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/examples/generic/media/style.css b/contrib/examples/generic/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/contrib/examples/generic/media/upload.html b/contrib/examples/generic/media/upload.html
@@ -0,0 +1,22 @@
+<!DOCTYPE>
+<html>
+<head>
+ <link rel="stylesheet" href="/css/style.css" type="text/css">
+ <title>Kore upload test</title>
+</head>
+
+<body style="overflow: auto">
+
+<div class="content">
+ <form method="POST" enctype="multipart/form-data">
+ <input type="input" name="firstname">
+ <input type="file" name="file">
+ <input type="submit" value="upload">
+ </form>
+
+ <p style="font-size: 12px; font-weight: normal">$upload$</p>
+ <p style="font-size: 12px; font-weight: normal">$firstname$</p>
+</div>
+
+</body>
+</html>
diff --git a/contrib/examples/generic/module.conf b/contrib/examples/generic/module.conf
@@ -0,0 +1,193 @@
+# Example Kore configuration
+
+# Server configuration.
+bind 127.0.0.1 443
+
+# The path worker processes will chroot into 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 4
+
+# The number of active connections each worker can handle.
+# You might have to tweak this number based on your hardware.
+#worker_max_connections 250
+
+# Store the main process its pid in this file.
+#pidfile /var/run/kore.pid
+
+# You can define a callback Kore calls from its parent process or
+# workers everytime the kore_cb_interval timer (in milliseconds) is reached.
+#
+# NOTE: Remember that the parent process runs as root and is not chroot().
+# NOTE: If you want the cb to run on a worker, be sure to set kore_cb_worker.
+#kore_cb my_callback
+#kore_cb_interval 1000
+#kore_cb_worker 3
+
+# HTTP specific settings.
+# http_header_max Maximum size of HTTP headers (in bytes).
+#
+# http_postbody_max Maximum size of an HTTP POST body (in bytes).
+#
+# http_keepalive_time Maximum seconds an HTTP connection can be
+# kept alive by the browser.
+# (Set to 0 to disable keepalive completely).
+#
+# http_hsts_enable Send Strict Transport Security header in
+# all responses. Parameter is the age.
+# (Set to 0 to disable sending this header).
+#http_header_max 4096
+#http_postbody_max 10240000
+#http_keepalive_time 0
+#http_hsts_enable 31536000
+
+# Load modules (you can load multiple at the same time).
+# An additional parameter can be specified as the "onload" function
+# which Kore will call when the module is loaded/reloaded.
+load contrib/modules/example/example.module example_load
+
+# Validators
+# validator name type regex|function
+#
+validator v_example function v_example_func
+validator v_regex regex ^/test/[a-z]*$
+validator v_number regex ^[0-9]*$
+validator v_session function v_session_validate
+
+# Specify the SSL ciphers that will be used.
+#ssl_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK
+
+# If you wish to use EDH / ECDH specify a file containing
+# a generated DH key (See OpenSSL dhparam).
+#ssl_dhparam dh2048.pem
+
+# Set this if you want to disable SSL zlib compression.
+ssl_no_compression
+
+# Specify the amount of seconds a SPDY connection is kept open.
+# You can keep it open indefinately by setting this to 0.
+#spdy_idle_time 120
+
+# Authentication configuration
+#
+# Using authentication blocks you can define a standard way for
+# Kore to validate your users. In the example below we create
+# a authentication block called auth_example, which requires
+# a cookie (session_id) to be set.
+#
+# If no cookie is present or the cookie is not valid according
+# to the set validator, Kore will redirect the browser to the
+# URI set in authentication_uri.
+#
+# Page handlers can be bound to authentication by specifying
+# authentication block at the end of the page directive (see below).
+authentication auth_example {
+ # The authentication type denotes the way the user should
+ # be authenticated.
+ #
+ # Allow values:
+ # - cookie (checks for the cookie presence + pass to validator)
+ # - header (checks for header presence + pass to validator)
+ # - requuest (passes the http_request to the validator)
+ #
+ # Use cases for request could for example be IP based ACLs or
+ # any other criteria that can be extracted from a http_request.
+ #
+ # The request type does not need an authentication_validator.
+ #
+ authentication_type cookie
+
+ # The name of whatever we are looking for.
+ authentication_value session_id
+
+ # The validator that will be called to verify the cookie.
+ # Note this is YOUR validator, Kore does not have built-in
+ # session support. You must add this manually using your
+ # preferred method (Storing it in postgres, redis, ...)
+ authentication_validator v_session
+
+ # The URI Kore will redirect to if a authentication fails.
+ # If this is not set, Kore will return a simple 403.
+ authentication_uri /private
+}
+
+# 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.
+# require_client_cert
+# - Asks the client to present a certificate
+# matching the CA given to require_client_cert
+#
+# 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 [auth block]
+#
+# Note that the auth block is optional and if set will force Kore to
+# authenticate the user according to the authentication block its settings
+# before allowing access to the page.
+
+# Example domain that responds to localhost.
+domain localhost {
+ certfile cert/server.crt
+ certkey cert/server.key
+ accesslog /var/log/kore_access.log
+
+ # Page handlers with no authentication required.
+ static /css/style.css serve_style_css
+ static / serve_index
+ static /intro.jpg serve_intro
+ static /b64test serve_b64test
+ static /spdy-reset serve_spdyreset
+ static /upload serve_file_upload
+ static /lock-test serve_lock_test
+ static /validator serve_validator
+ static /params-test serve_params_test
+ static /private serve_private
+
+ # Page handlers with authentication.
+ static /private/test serve_private_test auth_example
+
+ # Configure /params-test POST to only accept the following parameters.
+ # They are automatically tested against the validator listed.
+ # If the validator would fail Kore will automatically remove the
+ # failing parameter, indicating something was wrong with it.
+ # Any parameters not present in the params block are also filtered out.
+ params post /params-test {
+ validate test1 v_example
+ validate test2 v_regex
+ }
+
+ # Configure a GET parameter that /params-test can received. As before
+ # this is validated against the validator and removed if validation
+ # fails. All extra parameters in the GET query are filtered out.
+ params get /params-test {
+ validate arg1 v_example
+ validate id v_number
+ }
+}
+
+#domain domain.com {
+# certfile cert/other/server.crt
+# certkey cert/other/server.key
+# accesslog /var/log/other_kore_access.log
+# require_client_cert cert/other/ca.crt
+
+# static /css/style.css serve_style_css
+# static / serve_index
+# dynamic ^/[a-z0-9_]*$ serve_profile
+#}
diff --git a/contrib/examples/generic/src/example.c b/contrib/examples/generic/src/example.c
@@ -0,0 +1,361 @@
+/*
+ * 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 "kore.h"
+#include "http.h"
+
+#include "static.h"
+
+void example_load(int);
+
+int serve_style_css(struct http_request *);
+int serve_index(struct http_request *);
+int serve_intro(struct http_request *);
+int serve_b64test(struct http_request *);
+int serve_spdyreset(struct http_request *);
+int serve_file_upload(struct http_request *);
+int serve_lock_test(struct http_request *);
+int serve_validator(struct http_request *);
+int serve_params_test(struct http_request *);
+int serve_private(struct http_request *);
+int serve_private_test(struct http_request *);
+
+void my_callback(void);
+int v_example_func(struct http_request *, char *);
+int v_session_validate(struct http_request *, char *);
+void test_base64(u_int8_t *, u_int32_t, struct kore_buf *);
+
+char *b64tests[] = {
+ "1234567890",
+ "One two three four five",
+ "Man",
+ "any carnal pleasure.",
+ "any carnal pleasure",
+ "any carnal pleas",
+ "I am a nobody, nobody is perfect, therefor I am.",
+ NULL
+};
+
+void
+example_load(int state)
+{
+ switch (state) {
+ case KORE_MODULE_LOAD:
+ kore_log(LOG_NOTICE, "module loading");
+ break;
+ case KORE_MODULE_UNLOAD:
+ kore_log(LOG_NOTICE, "module unloading");
+ break;
+ default:
+ kore_log(LOG_NOTICE, "state %d unknown!", state);
+ break;
+ }
+}
+
+int
+serve_style_css(struct http_request *req)
+{
+ char *date;
+ time_t tstamp;
+
+ tstamp = 0;
+ if (http_request_header_get(req, "if-modified-since", &date)) {
+ tstamp = kore_date_to_time(date);
+ kore_mem_free(date);
+
+ kore_debug("header was present with %ld", tstamp);
+ }
+
+ if (tstamp != 0 && tstamp <= static_mtime_css_style) {
+ 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");
+ http_response(req, 200, static_css_style, static_len_css_style);
+ }
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_index(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "text/html");
+ http_response(req, 200, static_html_index, static_len_html_index);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_intro(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "image/jpg");
+ http_response(req, 200, static_jpg_intro, static_len_jpg_intro);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_b64test(struct http_request *req)
+{
+ int i;
+ u_int32_t len;
+ struct kore_buf *res;
+ u_int8_t *data;
+
+ res = kore_buf_create(1024);
+ for (i = 0; b64tests[i] != NULL; i++)
+ test_base64((u_int8_t *)b64tests[i], strlen(b64tests[i]), res);
+
+ data = kore_buf_release(res, &len);
+
+ http_response_header_add(req, "content-type", "text/plain");
+ http_response(req, 200, data, len);
+ kore_mem_free(data);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_spdyreset(struct http_request *req)
+{
+ spdy_session_teardown(req->owner, SPDY_SESSION_ERROR_OK);
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_file_upload(struct http_request *req)
+{
+ int r;
+ u_int8_t *d;
+ struct kore_buf *b;
+ u_int32_t len;
+ char *name, buf[BUFSIZ];
+
+ b = kore_buf_create(static_len_html_upload);
+ kore_buf_append(b, static_html_upload, static_len_html_upload);
+
+ if (req->method == HTTP_METHOD_POST) {
+ http_populate_multipart_form(req, &r);
+ if (http_argument_get_string("firstname", &name, &len)) {
+ kore_buf_replace_string(b, "$firstname$", name, len);
+ } else {
+ kore_buf_replace_string(b, "$firstname$", NULL, 0);
+ }
+
+ if (http_file_lookup(req, "file", &name, &d, &len)) {
+ snprintf(buf, sizeof(buf), "%s is %d bytes", name, len);
+ kore_buf_replace_string(b,
+ "$upload$", buf, strlen(buf));
+ } else {
+ kore_buf_replace_string(b, "$upload$", NULL, 0);
+ }
+ } else {
+ kore_buf_replace_string(b, "$upload$", NULL, 0);
+ kore_buf_replace_string(b, "$firstname$", NULL, 0);
+ }
+
+ d = kore_buf_release(b, &len);
+
+ http_response_header_add(req, "content-type", "text/html");
+ http_response(req, 200, d, len);
+ kore_mem_free(d);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_lock_test(struct http_request *req)
+{
+ kore_log(LOG_NOTICE, "lock-test called on worker %d", worker->id);
+ kore_worker_acceptlock_release();
+
+ http_response(req, 200, "OK", 2);
+ return (KORE_RESULT_OK);
+}
+
+void
+test_base64(u_int8_t *src, u_int32_t slen, struct kore_buf *res)
+{
+ char *in;
+ u_int32_t len;
+ u_int8_t *out;
+
+ kore_buf_appendf(res, "test '%s'\n", src);
+
+ if (!kore_base64_encode(src, slen, &in)) {
+ kore_buf_appendf(res, "encoding '%s' failed\n", src);
+ } else {
+ kore_buf_appendf(res, "encoded: '%s'\n", in);
+
+ if (!kore_base64_decode(in, &out, &len)) {
+ kore_buf_appendf(res, "decoding failed\n");
+ } else {
+ kore_buf_appendf(res, "decoded: ");
+ kore_buf_append(res, out, len);
+ kore_buf_appendf(res, "\n");
+ kore_mem_free(out);
+ }
+
+ kore_mem_free(in);
+ }
+
+ kore_buf_appendf(res, "\n");
+}
+
+int
+serve_validator(struct http_request *req)
+{
+ if (kore_validator_run(NULL, "v_example", "test"))
+ kore_log(LOG_NOTICE, "v_example ok (expected)");
+ else
+ kore_log(LOG_NOTICE, "v_example failed");
+
+ if (kore_validator_run(NULL, "v_regex", "/test/123"))
+ kore_log(LOG_NOTICE, "regex #1 ok");
+ else
+ kore_log(LOG_NOTICE, "regex #1 failed (expected)");
+
+ if (kore_validator_run(NULL, "v_regex", "/test/joris"))
+ kore_log(LOG_NOTICE, "regex #2 ok (expected)");
+ else
+ kore_log(LOG_NOTICE, "regex #2 failed");
+
+ http_response(req, 200, "OK", 2);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_params_test(struct http_request *req)
+{
+ struct kore_buf *b;
+ u_int8_t *d;
+ u_int32_t len;
+ int r, i;
+ char *test, name[10];
+
+ http_populate_arguments(req);
+
+ b = kore_buf_create(static_len_html_params);
+ kore_buf_append(b, static_html_params, static_len_html_params);
+
+ /*
+ * The GET parameters will be filtered out on POST.
+ */
+ if (http_argument_get_string("arg1", &test, &len)) {
+ kore_buf_replace_string(b, "$arg1$", test, len);
+ } else {
+ kore_buf_replace_string(b, "$arg1$", NULL, 0);
+ }
+
+ if (http_argument_get_string("arg2", &test, &len)) {
+ kore_buf_replace_string(b, "$arg2$", test, len);
+ } else {
+ kore_buf_replace_string(b, "$arg2$", NULL, 0);
+ }
+
+ if (req->method == HTTP_METHOD_GET) {
+ kore_buf_replace_string(b, "$test1$", NULL, 0);
+ kore_buf_replace_string(b, "$test2$", NULL, 0);
+ kore_buf_replace_string(b, "$test3$", NULL, 0);
+
+ if (http_argument_get_uint16("id", &r))
+ kore_log(LOG_NOTICE, "id: %d", r);
+ else
+ kore_log(LOG_NOTICE, "No id set");
+
+ http_response_header_add(req, "content-type", "text/html");
+ d = kore_buf_release(b, &len);
+ http_response(req, 200, d, len);
+ kore_mem_free(d);
+
+ return (KORE_RESULT_OK);
+ }
+
+ for (i = 1; i < 4; i++) {
+ snprintf(name, sizeof(name), "test%d", i);
+ if (http_argument_get_string(name, &test, &len)) {
+ snprintf(name, sizeof(name), "$test%d$", i);
+ kore_buf_replace_string(b, name, test, len);
+ } else {
+ snprintf(name, sizeof(name), "$test%d$", i);
+ kore_buf_replace_string(b, name, NULL, 0);
+ }
+ }
+
+ http_response_header_add(req, "content-type", "text/html");
+ d = kore_buf_release(b, &len);
+ http_response(req, 200, d, len);
+ kore_mem_free(d);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_private(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "text/html");
+ http_response_header_add(req, "set-cookie", "session_id=test123");
+ http_response(req, 200, static_html_private, static_len_html_private);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+serve_private_test(struct http_request *req)
+{
+ http_response_header_add(req, "content-type", "text/html");
+
+ http_response(req, 200, static_html_private_test,
+ static_len_html_private_test);
+
+ return (KORE_RESULT_OK);
+}
+
+void
+my_callback(void)
+{
+ if (worker != NULL)
+ kore_log(LOG_NOTICE, "running on worker %d", worker->id);
+ else
+ kore_log(LOG_NOTICE, "running from parent");
+}
+
+int
+v_example_func(struct http_request *req, char *data)
+{
+ kore_log(LOG_NOTICE, "v_example_func called");
+
+ if (!strcmp(data, "test"))
+ return (KORE_RESULT_OK);
+
+ return (KORE_RESULT_ERROR);
+}
+
+int
+v_session_validate(struct http_request *req, char *data)
+{
+ kore_log(LOG_NOTICE, "v_session_validate: %s", data);
+
+ if (!strcmp(data, "test123"))
+ return (KORE_RESULT_OK);
+
+ return (KORE_RESULT_ERROR);
+}
diff --git a/contrib/examples/generic/tools/inject.c b/contrib/examples/generic/tools/inject.c
@@ -0,0 +1,119 @@
+/*
+ * 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 <inttypes.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(OpenBSD)
+#define PRI_TIME_T "d"
+#endif
+
+#if defined(linux)
+#if defined(__x86_64__)
+#define PRI_TIME_T PRIu64
+#else
+#define PRI_TIME_T "ld"
+#endif
+#endif
+
+#if defined(__MACH__)
+#define PRI_TIME_T "ld"
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ ssize_t len;
+ FILE *hdr;
+ char *ext;
+ unsigned char 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 = %" PRIu32 ";\n",
+ ext, argv[2], (u_int32_t)st.st_size);
+
+ printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\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/contrib/examples/pgsql_test/build.sh b/contrib/examples/pgsql_test/build.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# Kore pgsql test module build directives.
+#
+
+MODULE=pgsql_test.module
+MEDIA_DIR=media
+SOURCE_DIR=src
+KORE_DIR=../../..
+PGDIR=$(pg_config --includedir)
+CC=gcc
+CFLAGS="-I. -I${KORE_DIR}/includes -I${PGDIR} \
+ -Wall -Wstrict-prototypes -Wmissing-prototypes \
+ -Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual \
+ -Wsign-compare -g"
+
+OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
+if [ "${OSNAME}" = "darwin" ]; then
+ LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
+else
+ LDFLAGS="-shared"
+fi
+
+MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
+
+### Begin building ####
+echo "Building module ${MODULE}..."
+rm -f ${MODULE}
+
+${CC} ${CFLAGS} tools/inject.c -o tools/inject
+
+if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
+ mkdir ${SOURCE_DIR}/${MEDIA_DIR};
+fi
+rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
+
+if [ ! -d .objs ]; then
+ mkdir .objs;
+fi
+rm -f .objs/*
+
+rm -f static.h
+
+for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; 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
+
+echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
+
+for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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
+rm -f static.h
diff --git a/contrib/examples/pgsql_test/module.conf b/contrib/examples/pgsql_test/module.conf
@@ -0,0 +1,20 @@
+# Kore pgsql_test configuration
+# see modules/examples/module.conf for a better overview
+# of what a configuration file has to offer and what different
+# settings mean and do.
+
+bind 127.0.0.1 8080
+chroot /home/joris/src/kore
+runas joris
+workers 4
+pidfile kore.pid
+load contrib/modules/pgsql_test/pgsql_test.module pgsql_load
+ssl_no_compression
+
+domain localhost {
+ certfile cert/server.crt
+ certkey cert/server.key
+ accesslog kore_pgsql.log
+
+ static / serve_pgsql_test
+}
diff --git a/contrib/examples/pgsql_test/src/pgsql_test.c b/contrib/examples/pgsql_test/src/pgsql_test.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 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 "kore.h"
+#include "http.h"
+#include "kore_pgsql.h"
+
+#include "static.h"
+
+void pgsql_load(int);
+int serve_pgsql_test(struct http_request *);
+
+void
+pgsql_load(int state)
+{
+ switch (state) {
+ case KORE_MODULE_LOAD:
+ pgsql_conn_string = "Your connection string";
+ break;
+ default:
+ break;
+ }
+}
+
+int
+serve_pgsql_test(struct http_request *req)
+{
+ int r, i;
+ char *col1, *col2;
+
+ KORE_PGSQL(req, "SELECT * FROM test", 0, {
+ if (req->pgsql[0]->state == KORE_PGSQL_STATE_ERROR) {
+ kore_pgsql_logerror(req->pgsql[0]);
+ http_response(req, 500, "fail\n", 5);
+ return (KORE_RESULT_OK);
+ }
+
+ r = kore_pgsql_ntuples(req->pgsql[0]);
+ for (i = 0; i < r; i++) {
+ col1 = kore_pgsql_getvalue(req->pgsql[0], i, 0);
+ col2 = kore_pgsql_getvalue(req->pgsql[0], i, 1);
+
+ kore_log(LOG_NOTICE, "%s and %s", col1, col2);
+ }
+ });
+
+ KORE_PGSQL(req, "SELECT * FROM foobar", 1, {
+ if (req->pgsql[1]->state != KORE_PGSQL_STATE_ERROR) {
+ kore_log(LOG_NOTICE, "expected error, got %d",
+ req->pgsql[1]->state);
+ http_response(req, 500, "fail2\n", 6);
+ return (KORE_RESULT_OK);
+ } else {
+ kore_pgsql_logerror(req->pgsql[1]);
+ }
+ });
+
+ /* Query successfully completed */
+ http_response(req, 200, "ok\n", 3);
+
+ return (KORE_RESULT_OK);
+}
diff --git a/contrib/examples/pgsql_test/tools/inject.c b/contrib/examples/pgsql_test/tools/inject.c
@@ -0,0 +1,119 @@
+/*
+ * 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 <inttypes.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(OpenBSD)
+#define PRI_TIME_T "d"
+#endif
+
+#if defined(linux)
+#if defined(__x86_64__)
+#define PRI_TIME_T PRIu64
+#else
+#define PRI_TIME_T "ld"
+#endif
+#endif
+
+#if defined(__MACH__)
+#define PRI_TIME_T "ld"
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ ssize_t len;
+ FILE *hdr;
+ char *ext;
+ unsigned char 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 = %" PRIu32 ";\n",
+ ext, argv[2], (u_int32_t)st.st_size);
+
+ printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\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/contrib/examples/skeleton/build.sh b/contrib/examples/skeleton/build.sh
@@ -0,0 +1,86 @@
+#!/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=site.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.
+MEDIA_DIR=media
+
+# The directory containing your module source.
+SOURCE_DIR=src
+
+# The directory containing the Kore source code.
+KORE_DIR="notset"
+if [ ${KORE_DIR} = "notset" ]; then
+ echo "Please edit build.sh and set KORE_DIR properly";
+ exit;
+fi
+
+# 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"
+
+OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
+if [ "${OSNAME}" = "darwin" ]; then
+ LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
+else
+ LDFLAGS="-shared"
+fi
+
+MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
+
+### Begin building ####
+echo "Building module ${MODULE}..."
+rm -f ${MODULE}
+
+${CC} ${CFLAGS} tools/inject.c -o tools/inject
+
+if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
+ mkdir ${SOURCE_DIR}/${MEDIA_DIR};
+fi
+rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
+
+if [ ! -d .objs ]; then
+ mkdir .objs;
+fi
+rm -f .objs/*
+
+rm -f static.h
+
+for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; 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
+
+echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
+
+for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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
+rm -f static.h
diff --git a/contrib/examples/skeleton/media/.gitignore b/contrib/examples/skeleton/media/.gitignore
diff --git a/contrib/examples/skeleton/src/.gitignore b/contrib/examples/skeleton/src/.gitignore
diff --git a/contrib/examples/skeleton/tools/inject.c b/contrib/examples/skeleton/tools/inject.c
@@ -0,0 +1,119 @@
+/*
+ * 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 <inttypes.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(OpenBSD)
+#define PRI_TIME_T "d"
+#endif
+
+#if defined(linux)
+#if defined(__x86_64__)
+#define PRI_TIME_T PRIu64
+#else
+#define PRI_TIME_T "ld"
+#endif
+#endif
+
+#if defined(__MACH__)
+#define PRI_TIME_T "ld"
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ ssize_t len;
+ FILE *hdr;
+ char *ext;
+ unsigned char 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 = %" PRIu32 ";\n",
+ ext, argv[2], (u_int32_t)st.st_size);
+
+ printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\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/contrib/examples/task_curl/build.sh b/contrib/examples/task_curl/build.sh
@@ -0,0 +1,48 @@
+#!/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=task_curl.so
+
+# The directory containing your module source.
+SOURCE_DIR=.
+
+# 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 -lcurl"
+
+MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
+
+### Begin building ####
+echo "Building module ${MODULE}..."
+rm -f ${MODULE}
+
+if [ ! -d .objs ]; then
+ mkdir .objs;
+fi
+rm -f .objs/*
+
+for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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 .objs
diff --git a/contrib/examples/task_curl/example.c b/contrib/examples/task_curl/example.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*
+ * In this example, we use the background tasks available in Kore
+ * to fire off a POST to our /post_back page handler containing
+ * the user argument that was passed to us in our GET request to /.
+ *
+ * This illustrates how Kore its background tasks in effect work and
+ * how to operate on the channel in order to pass data back and forth.
+ *
+ * The page_handler() page handler is not called until the background
+ * task it fired off has completed.
+ *
+ * You need libcurl installed for this to build (including headers)
+ *
+ * Compile using build.sh, afterwards start using:
+ * # kore -nc module.conf (depending on where kore is installed)
+ *
+ * Test using:
+ * # curl -k https://127.0.0.1:4443/?user=foobar
+ *
+ * If the result echo'd back matches what you specified, its all green.
+ */
+
+#include <curl/curl.h>
+
+#include "kore.h"
+#include "http.h"
+#include "kore_tasks.h"
+
+int run_curl(struct kore_task *);
+int post_back(struct http_request *);
+int page_handler(struct http_request *);
+size_t curl_write_cb(char *, size_t, size_t, void *);
+
+int
+page_handler(struct http_request *req)
+{
+ u_int32_t len;
+ char *user, result[64];
+
+ /*
+ * Lets check if a task has been created yet, this is important
+ * as we only want to fire this off once and we will be called
+ * again once it has been created.
+ */
+ if (req->task == NULL) {
+ /* Grab the user argument */
+ http_populate_arguments(req);
+ if (!http_argument_get_string("user", &user, &len)) {
+ http_response(req, 500, "ERROR\n", 6);
+ return (KORE_RESULT_OK);
+ }
+
+ /*
+ * Create a new task that will execute the run_curl()
+ * function and bind it to our request.
+ *
+ * Binding a task to a request means Kore will reschedule
+ * the page handler for that request to refire after the
+ * task has completed.
+ */
+ kore_task_create(&req->task, run_curl);
+ kore_task_bind_request(req->task, req);
+
+ /*
+ * Start the task and write the user we received in our
+ * GET request to its channel.
+ */
+ kore_task_run(req->task);
+ kore_task_channel_write(req->task, user, len);
+
+ /*
+ * Tell Kore to retry us later.
+ */
+ return (KORE_RESULT_RETRY);
+ }
+
+ /*
+ * When we come back here, our background task is finished
+ * and we can check its result.
+ */
+ if (req->task->result != KORE_RESULT_OK) {
+ kore_task_destroy(req->task);
+ http_response(req, 500, NULL, 0);
+ return (KORE_RESULT_OK);
+ }
+
+ /*
+ * Lets read what our task has written to the channel.
+ *
+ * kore_task_channel_read() will return the amount of bytes
+ * that it received for that read. If the returned bytes is
+ * larger then the buffer you passed this is a sign of truncation
+ * and should be treated carefully.
+ */
+ len = kore_task_channel_read(req->task, result, sizeof(result));
+ if (len >= sizeof(result)) {
+ http_response(req, 500, NULL, 0);
+ } else {
+ http_response(req, 200, result, len);
+ }
+
+ /* We good, destroy the task. */
+ kore_task_destroy(req->task);
+
+ return (KORE_RESULT_OK);
+}
+
+int
+post_back(struct http_request *req)
+{
+ u_int32_t len;
+ char *user;
+
+ if (req->method != HTTP_METHOD_POST) {
+ http_response(req, 500, NULL, 0);
+ return (KORE_RESULT_OK);
+ }
+
+ http_populate_arguments(req);
+ if (!http_argument_get_string("user", &user, &len)) {
+ http_response(req, 500, NULL, 0);
+ return (KORE_RESULT_OK);
+ }
+
+ /* Simply echo the supplied user argument back. */
+ http_response(req, 200, user, len);
+
+ return (KORE_RESULT_OK);
+}
+
+/*
+ * This is the function that is executed by our task which is created
+ * in the page_handler() callback.
+ *
+ * It sets up a CURL POST request to /post_back passing along the
+ * user argument which it receives from its channel from page_handler().
+ */
+int
+run_curl(struct kore_task *t)
+{
+ int l;
+ struct kore_buf *b;
+ u_int32_t len;
+ CURLcode res;
+ u_int8_t *data;
+ CURL *curl;
+ char user[64], fields[128];
+
+ /*
+ * Read the channel in order to obtain the user argument
+ * that was written to it by page_handler().
+ */
+ len = kore_task_channel_read(t, user, sizeof(user));
+ if (len >= sizeof(user))
+ return (KORE_RESULT_ERROR);
+
+ l = snprintf(fields, sizeof(fields), "user=%.*s", len, user);
+ if (l == -1 || (size_t)l >= sizeof(fields))
+ return (KORE_RESULT_ERROR);
+
+ if ((curl = curl_easy_init()) == NULL)
+ return (KORE_RESULT_ERROR);
+
+ b = kore_buf_create(128);
+
+ /* Do CURL magic. */
+ curl_easy_setopt(curl, CURLOPT_POST, 1);
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, b);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);
+ curl_easy_setopt(curl, CURLOPT_URL, "https://127.0.0.1:4443/post_back");
+
+ res = curl_easy_perform(curl);
+ if (res != CURLE_OK) {
+ kore_buf_free(b);
+ curl_easy_cleanup(curl);
+ return (KORE_RESULT_ERROR);
+ }
+
+ /*
+ * Grab the response from the CURL request and write the
+ * result back to the task channel.
+ */
+ data = kore_buf_release(b, &len);
+ kore_task_channel_write(t, data, len);
+ kore_mem_free(data);
+
+ return (KORE_RESULT_OK);
+}
+
+size_t
+curl_write_cb(char *ptr, size_t size, size_t nmemb, void *udata)
+{
+ struct kore_buf *b = udata;
+
+ kore_buf_append(b, ptr, size * nmemb);
+ return (size * nmemb);
+}
diff --git a/contrib/examples/task_curl/module.conf b/contrib/examples/task_curl/module.conf
@@ -0,0 +1,31 @@
+# Configuration for the contrib/modules/task_curl example.
+
+bind 127.0.0.1 4443
+chroot # configure this (ex: /home/joris/src/kore)
+runas # configure this (ex: joris)
+
+workers 1
+pidfile kore.pid
+
+load ./task_curl.so
+
+ssl_no_compression
+
+validator v_user regex ^[a-z]*$
+
+domain 127.0.0.1 {
+ certfile # configure this (ex: cert/server.crt)
+ certkey # configure this (ex: cert/server.key)
+ accesslog kore_access.log
+
+ static / page_handler
+ static /post_back post_back
+
+ params get / {
+ validate user v_user
+ }
+
+ params post /post_back {
+ validate user v_user
+ }
+}
diff --git a/contrib/modules/example/build.sh b/contrib/modules/example/build.sh
@@ -1,82 +0,0 @@
-#!/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.
-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"
-
-OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
-if [ "${OSNAME}" = "darwin" ]; then
- LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
-else
- LDFLAGS="-shared"
-fi
-
-MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
-
-### Begin building ####
-echo "Building module ${MODULE}..."
-rm -f ${MODULE}
-
-${CC} ${CFLAGS} tools/inject.c -o tools/inject
-
-if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
- mkdir ${SOURCE_DIR}/${MEDIA_DIR};
-fi
-rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
-
-if [ ! -d .objs ]; then
- mkdir .objs;
-fi
-rm -f .objs/*
-
-rm -f static.h
-
-for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; 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
-
-echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
-
-for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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
-rm -f static.h
diff --git a/contrib/modules/example/media/index.html b/contrib/modules/example/media/index.html
@@ -1,15 +0,0 @@
-<!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/contrib/modules/example/media/intro.jpg b/contrib/modules/example/media/intro.jpg
Binary files differ.
diff --git a/contrib/modules/example/media/params.html b/contrib/modules/example/media/params.html
@@ -1,33 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore params test</title>
-</head>
-
-<body style="overflow: auto">
-
-<div class="content" style="font-size: 12px; font-weight: normal">
- <p>You can pass one GET parameter (arg1), any other GET parameter will
- be filtered out</p>
- <p>Only two out of the three input fields will be visible to Kore.</p>
- <p>The first field accepts the input "test"</p>
- <p>The second field accepts anything like /test/[a-z]*</p>
- <p>The third field will be removed by Kore, as it is not in the params
- block configured for this page.</p>
- <form method="POST">
- <input type="input" name="test1" value="$test1$">
- <input type="input" name="test2" value="$test2$">
- <input type="input" name="test3" value="$test3$">
- <input type="submit">
- </form>
-
- <p style="font-size: 12px; font-weight: normal">GET param arg1: $arg1$</p>
- <p style="font-size: 12px; font-weight: normal">GET param arg2: $arg2$</p>
- <p style="font-size: 12px; font-weight: normal">test1: $test1$</p>
- <p style="font-size: 12px; font-weight: normal">test2: $test2$</p>
- <p style="font-size: 12px; font-weight: normal">test3: $test3$</p>
-</div>
-
-</body>
-</html>
diff --git a/contrib/modules/example/media/private.html b/contrib/modules/example/media/private.html
@@ -1,16 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore Authentication tests</title>
-</head>
-
-<body>
-
-<div class="content">
- <p style="font-size: small">The cookie session_id should now be set.</p>
- <p style="font-size: small">You can continue to <a href="/private/test">view page handler in auth block</a></p>
-</div>
-
-</body>
-</html>
diff --git a/contrib/modules/example/media/private_test.html b/contrib/modules/example/media/private_test.html
@@ -1,15 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore Authentication tests</title>
-</head>
-
-<body>
-
-<div class="content">
- <p style="font-size: small">If you see this, the authentication worked. This page should redirect back to /private once you remove your session_id cookie.</p>
-</div>
-
-</body>
-</html>
diff --git a/contrib/modules/example/media/style.css b/contrib/modules/example/media/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/contrib/modules/example/media/upload.html b/contrib/modules/example/media/upload.html
@@ -1,22 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
- <link rel="stylesheet" href="/css/style.css" type="text/css">
- <title>Kore upload test</title>
-</head>
-
-<body style="overflow: auto">
-
-<div class="content">
- <form method="POST" enctype="multipart/form-data">
- <input type="input" name="firstname">
- <input type="file" name="file">
- <input type="submit" value="upload">
- </form>
-
- <p style="font-size: 12px; font-weight: normal">$upload$</p>
- <p style="font-size: 12px; font-weight: normal">$firstname$</p>
-</div>
-
-</body>
-</html>
diff --git a/contrib/modules/example/module.conf b/contrib/modules/example/module.conf
@@ -1,193 +0,0 @@
-# Example Kore configuration
-
-# Server configuration.
-bind 127.0.0.1 443
-
-# The path worker processes will chroot into 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 4
-
-# The number of active connections each worker can handle.
-# You might have to tweak this number based on your hardware.
-#worker_max_connections 250
-
-# Store the main process its pid in this file.
-#pidfile /var/run/kore.pid
-
-# You can define a callback Kore calls from its parent process or
-# workers everytime the kore_cb_interval timer (in milliseconds) is reached.
-#
-# NOTE: Remember that the parent process runs as root and is not chroot().
-# NOTE: If you want the cb to run on a worker, be sure to set kore_cb_worker.
-#kore_cb my_callback
-#kore_cb_interval 1000
-#kore_cb_worker 3
-
-# HTTP specific settings.
-# http_header_max Maximum size of HTTP headers (in bytes).
-#
-# http_postbody_max Maximum size of an HTTP POST body (in bytes).
-#
-# http_keepalive_time Maximum seconds an HTTP connection can be
-# kept alive by the browser.
-# (Set to 0 to disable keepalive completely).
-#
-# http_hsts_enable Send Strict Transport Security header in
-# all responses. Parameter is the age.
-# (Set to 0 to disable sending this header).
-#http_header_max 4096
-#http_postbody_max 10240000
-#http_keepalive_time 0
-#http_hsts_enable 31536000
-
-# Load modules (you can load multiple at the same time).
-# An additional parameter can be specified as the "onload" function
-# which Kore will call when the module is loaded/reloaded.
-load contrib/modules/example/example.module example_load
-
-# Validators
-# validator name type regex|function
-#
-validator v_example function v_example_func
-validator v_regex regex ^/test/[a-z]*$
-validator v_number regex ^[0-9]*$
-validator v_session function v_session_validate
-
-# Specify the SSL ciphers that will be used.
-#ssl_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK
-
-# If you wish to use EDH / ECDH specify a file containing
-# a generated DH key (See OpenSSL dhparam).
-#ssl_dhparam dh2048.pem
-
-# Set this if you want to disable SSL zlib compression.
-ssl_no_compression
-
-# Specify the amount of seconds a SPDY connection is kept open.
-# You can keep it open indefinately by setting this to 0.
-#spdy_idle_time 120
-
-# Authentication configuration
-#
-# Using authentication blocks you can define a standard way for
-# Kore to validate your users. In the example below we create
-# a authentication block called auth_example, which requires
-# a cookie (session_id) to be set.
-#
-# If no cookie is present or the cookie is not valid according
-# to the set validator, Kore will redirect the browser to the
-# URI set in authentication_uri.
-#
-# Page handlers can be bound to authentication by specifying
-# authentication block at the end of the page directive (see below).
-authentication auth_example {
- # The authentication type denotes the way the user should
- # be authenticated.
- #
- # Allow values:
- # - cookie (checks for the cookie presence + pass to validator)
- # - header (checks for header presence + pass to validator)
- # - requuest (passes the http_request to the validator)
- #
- # Use cases for request could for example be IP based ACLs or
- # any other criteria that can be extracted from a http_request.
- #
- # The request type does not need an authentication_validator.
- #
- authentication_type cookie
-
- # The name of whatever we are looking for.
- authentication_value session_id
-
- # The validator that will be called to verify the cookie.
- # Note this is YOUR validator, Kore does not have built-in
- # session support. You must add this manually using your
- # preferred method (Storing it in postgres, redis, ...)
- authentication_validator v_session
-
- # The URI Kore will redirect to if a authentication fails.
- # If this is not set, Kore will return a simple 403.
- authentication_uri /private
-}
-
-# 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.
-# require_client_cert
-# - Asks the client to present a certificate
-# matching the CA given to require_client_cert
-#
-# 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 [auth block]
-#
-# Note that the auth block is optional and if set will force Kore to
-# authenticate the user according to the authentication block its settings
-# before allowing access to the page.
-
-# Example domain that responds to localhost.
-domain localhost {
- certfile cert/server.crt
- certkey cert/server.key
- accesslog /var/log/kore_access.log
-
- # Page handlers with no authentication required.
- static /css/style.css serve_style_css
- static / serve_index
- static /intro.jpg serve_intro
- static /b64test serve_b64test
- static /spdy-reset serve_spdyreset
- static /upload serve_file_upload
- static /lock-test serve_lock_test
- static /validator serve_validator
- static /params-test serve_params_test
- static /private serve_private
-
- # Page handlers with authentication.
- static /private/test serve_private_test auth_example
-
- # Configure /params-test POST to only accept the following parameters.
- # They are automatically tested against the validator listed.
- # If the validator would fail Kore will automatically remove the
- # failing parameter, indicating something was wrong with it.
- # Any parameters not present in the params block are also filtered out.
- params post /params-test {
- validate test1 v_example
- validate test2 v_regex
- }
-
- # Configure a GET parameter that /params-test can received. As before
- # this is validated against the validator and removed if validation
- # fails. All extra parameters in the GET query are filtered out.
- params get /params-test {
- validate arg1 v_example
- validate id v_number
- }
-}
-
-#domain domain.com {
-# certfile cert/other/server.crt
-# certkey cert/other/server.key
-# accesslog /var/log/other_kore_access.log
-# require_client_cert cert/other/ca.crt
-
-# static /css/style.css serve_style_css
-# static / serve_index
-# dynamic ^/[a-z0-9_]*$ serve_profile
-#}
diff --git a/contrib/modules/example/src/example.c b/contrib/modules/example/src/example.c
@@ -1,361 +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 "kore.h"
-#include "http.h"
-
-#include "static.h"
-
-void example_load(int);
-
-int serve_style_css(struct http_request *);
-int serve_index(struct http_request *);
-int serve_intro(struct http_request *);
-int serve_b64test(struct http_request *);
-int serve_spdyreset(struct http_request *);
-int serve_file_upload(struct http_request *);
-int serve_lock_test(struct http_request *);
-int serve_validator(struct http_request *);
-int serve_params_test(struct http_request *);
-int serve_private(struct http_request *);
-int serve_private_test(struct http_request *);
-
-void my_callback(void);
-int v_example_func(struct http_request *, char *);
-int v_session_validate(struct http_request *, char *);
-void test_base64(u_int8_t *, u_int32_t, struct kore_buf *);
-
-char *b64tests[] = {
- "1234567890",
- "One two three four five",
- "Man",
- "any carnal pleasure.",
- "any carnal pleasure",
- "any carnal pleas",
- "I am a nobody, nobody is perfect, therefor I am.",
- NULL
-};
-
-void
-example_load(int state)
-{
- switch (state) {
- case KORE_MODULE_LOAD:
- kore_log(LOG_NOTICE, "module loading");
- break;
- case KORE_MODULE_UNLOAD:
- kore_log(LOG_NOTICE, "module unloading");
- break;
- default:
- kore_log(LOG_NOTICE, "state %d unknown!", state);
- break;
- }
-}
-
-int
-serve_style_css(struct http_request *req)
-{
- char *date;
- time_t tstamp;
-
- tstamp = 0;
- if (http_request_header_get(req, "if-modified-since", &date)) {
- tstamp = kore_date_to_time(date);
- kore_mem_free(date);
-
- kore_debug("header was present with %ld", tstamp);
- }
-
- if (tstamp != 0 && tstamp <= static_mtime_css_style) {
- 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");
- http_response(req, 200, static_css_style, static_len_css_style);
- }
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_index(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "text/html");
- http_response(req, 200, static_html_index, static_len_html_index);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_intro(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "image/jpg");
- http_response(req, 200, static_jpg_intro, static_len_jpg_intro);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_b64test(struct http_request *req)
-{
- int i;
- u_int32_t len;
- struct kore_buf *res;
- u_int8_t *data;
-
- res = kore_buf_create(1024);
- for (i = 0; b64tests[i] != NULL; i++)
- test_base64((u_int8_t *)b64tests[i], strlen(b64tests[i]), res);
-
- data = kore_buf_release(res, &len);
-
- http_response_header_add(req, "content-type", "text/plain");
- http_response(req, 200, data, len);
- kore_mem_free(data);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_spdyreset(struct http_request *req)
-{
- spdy_session_teardown(req->owner, SPDY_SESSION_ERROR_OK);
- return (KORE_RESULT_OK);
-}
-
-int
-serve_file_upload(struct http_request *req)
-{
- int r;
- u_int8_t *d;
- struct kore_buf *b;
- u_int32_t len;
- char *name, buf[BUFSIZ];
-
- b = kore_buf_create(static_len_html_upload);
- kore_buf_append(b, static_html_upload, static_len_html_upload);
-
- if (req->method == HTTP_METHOD_POST) {
- http_populate_multipart_form(req, &r);
- if (http_argument_get_string("firstname", &name, &len)) {
- kore_buf_replace_string(b, "$firstname$", name, len);
- } else {
- kore_buf_replace_string(b, "$firstname$", NULL, 0);
- }
-
- if (http_file_lookup(req, "file", &name, &d, &len)) {
- snprintf(buf, sizeof(buf), "%s is %d bytes", name, len);
- kore_buf_replace_string(b,
- "$upload$", buf, strlen(buf));
- } else {
- kore_buf_replace_string(b, "$upload$", NULL, 0);
- }
- } else {
- kore_buf_replace_string(b, "$upload$", NULL, 0);
- kore_buf_replace_string(b, "$firstname$", NULL, 0);
- }
-
- d = kore_buf_release(b, &len);
-
- http_response_header_add(req, "content-type", "text/html");
- http_response(req, 200, d, len);
- kore_mem_free(d);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_lock_test(struct http_request *req)
-{
- kore_log(LOG_NOTICE, "lock-test called on worker %d", worker->id);
- kore_worker_acceptlock_release();
-
- http_response(req, 200, "OK", 2);
- return (KORE_RESULT_OK);
-}
-
-void
-test_base64(u_int8_t *src, u_int32_t slen, struct kore_buf *res)
-{
- char *in;
- u_int32_t len;
- u_int8_t *out;
-
- kore_buf_appendf(res, "test '%s'\n", src);
-
- if (!kore_base64_encode(src, slen, &in)) {
- kore_buf_appendf(res, "encoding '%s' failed\n", src);
- } else {
- kore_buf_appendf(res, "encoded: '%s'\n", in);
-
- if (!kore_base64_decode(in, &out, &len)) {
- kore_buf_appendf(res, "decoding failed\n");
- } else {
- kore_buf_appendf(res, "decoded: ");
- kore_buf_append(res, out, len);
- kore_buf_appendf(res, "\n");
- kore_mem_free(out);
- }
-
- kore_mem_free(in);
- }
-
- kore_buf_appendf(res, "\n");
-}
-
-int
-serve_validator(struct http_request *req)
-{
- if (kore_validator_run(NULL, "v_example", "test"))
- kore_log(LOG_NOTICE, "v_example ok (expected)");
- else
- kore_log(LOG_NOTICE, "v_example failed");
-
- if (kore_validator_run(NULL, "v_regex", "/test/123"))
- kore_log(LOG_NOTICE, "regex #1 ok");
- else
- kore_log(LOG_NOTICE, "regex #1 failed (expected)");
-
- if (kore_validator_run(NULL, "v_regex", "/test/joris"))
- kore_log(LOG_NOTICE, "regex #2 ok (expected)");
- else
- kore_log(LOG_NOTICE, "regex #2 failed");
-
- http_response(req, 200, "OK", 2);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_params_test(struct http_request *req)
-{
- struct kore_buf *b;
- u_int8_t *d;
- u_int32_t len;
- int r, i;
- char *test, name[10];
-
- http_populate_arguments(req);
-
- b = kore_buf_create(static_len_html_params);
- kore_buf_append(b, static_html_params, static_len_html_params);
-
- /*
- * The GET parameters will be filtered out on POST.
- */
- if (http_argument_get_string("arg1", &test, &len)) {
- kore_buf_replace_string(b, "$arg1$", test, len);
- } else {
- kore_buf_replace_string(b, "$arg1$", NULL, 0);
- }
-
- if (http_argument_get_string("arg2", &test, &len)) {
- kore_buf_replace_string(b, "$arg2$", test, len);
- } else {
- kore_buf_replace_string(b, "$arg2$", NULL, 0);
- }
-
- if (req->method == HTTP_METHOD_GET) {
- kore_buf_replace_string(b, "$test1$", NULL, 0);
- kore_buf_replace_string(b, "$test2$", NULL, 0);
- kore_buf_replace_string(b, "$test3$", NULL, 0);
-
- if (http_argument_get_uint16("id", &r))
- kore_log(LOG_NOTICE, "id: %d", r);
- else
- kore_log(LOG_NOTICE, "No id set");
-
- http_response_header_add(req, "content-type", "text/html");
- d = kore_buf_release(b, &len);
- http_response(req, 200, d, len);
- kore_mem_free(d);
-
- return (KORE_RESULT_OK);
- }
-
- for (i = 1; i < 4; i++) {
- snprintf(name, sizeof(name), "test%d", i);
- if (http_argument_get_string(name, &test, &len)) {
- snprintf(name, sizeof(name), "$test%d$", i);
- kore_buf_replace_string(b, name, test, len);
- } else {
- snprintf(name, sizeof(name), "$test%d$", i);
- kore_buf_replace_string(b, name, NULL, 0);
- }
- }
-
- http_response_header_add(req, "content-type", "text/html");
- d = kore_buf_release(b, &len);
- http_response(req, 200, d, len);
- kore_mem_free(d);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_private(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "text/html");
- http_response_header_add(req, "set-cookie", "session_id=test123");
- http_response(req, 200, static_html_private, static_len_html_private);
-
- return (KORE_RESULT_OK);
-}
-
-int
-serve_private_test(struct http_request *req)
-{
- http_response_header_add(req, "content-type", "text/html");
-
- http_response(req, 200, static_html_private_test,
- static_len_html_private_test);
-
- return (KORE_RESULT_OK);
-}
-
-void
-my_callback(void)
-{
- if (worker != NULL)
- kore_log(LOG_NOTICE, "running on worker %d", worker->id);
- else
- kore_log(LOG_NOTICE, "running from parent");
-}
-
-int
-v_example_func(struct http_request *req, char *data)
-{
- kore_log(LOG_NOTICE, "v_example_func called");
-
- if (!strcmp(data, "test"))
- return (KORE_RESULT_OK);
-
- return (KORE_RESULT_ERROR);
-}
-
-int
-v_session_validate(struct http_request *req, char *data)
-{
- kore_log(LOG_NOTICE, "v_session_validate: %s", data);
-
- if (!strcmp(data, "test123"))
- return (KORE_RESULT_OK);
-
- return (KORE_RESULT_ERROR);
-}
diff --git a/contrib/modules/example/tools/inject.c b/contrib/modules/example/tools/inject.c
@@ -1,119 +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 <inttypes.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if defined(OpenBSD)
-#define PRI_TIME_T "d"
-#endif
-
-#if defined(linux)
-#if defined(__x86_64__)
-#define PRI_TIME_T PRIu64
-#else
-#define PRI_TIME_T "ld"
-#endif
-#endif
-
-#if defined(__MACH__)
-#define PRI_TIME_T "ld"
-#endif
-
-int
-main(int argc, char *argv[])
-{
- struct stat st;
- ssize_t len;
- FILE *hdr;
- char *ext;
- unsigned char 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 = %" PRIu32 ";\n",
- ext, argv[2], (u_int32_t)st.st_size);
-
- printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\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/contrib/modules/pgsql_test/build.sh b/contrib/modules/pgsql_test/build.sh
@@ -1,71 +0,0 @@
-#!/bin/sh
-#
-# Kore pgsql test module build directives.
-#
-
-MODULE=pgsql_test.module
-MEDIA_DIR=media
-SOURCE_DIR=src
-KORE_DIR=../../..
-PGDIR=$(pg_config --includedir)
-CC=gcc
-CFLAGS="-I. -I${KORE_DIR}/includes -I${PGDIR} \
- -Wall -Wstrict-prototypes -Wmissing-prototypes \
- -Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual \
- -Wsign-compare -g"
-
-OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
-if [ "${OSNAME}" = "darwin" ]; then
- LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
-else
- LDFLAGS="-shared"
-fi
-
-MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
-
-### Begin building ####
-echo "Building module ${MODULE}..."
-rm -f ${MODULE}
-
-${CC} ${CFLAGS} tools/inject.c -o tools/inject
-
-if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
- mkdir ${SOURCE_DIR}/${MEDIA_DIR};
-fi
-rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
-
-if [ ! -d .objs ]; then
- mkdir .objs;
-fi
-rm -f .objs/*
-
-rm -f static.h
-
-for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; 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
-
-echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
-
-for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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
-rm -f static.h
diff --git a/contrib/modules/pgsql_test/module.conf b/contrib/modules/pgsql_test/module.conf
@@ -1,20 +0,0 @@
-# Kore pgsql_test configuration
-# see modules/examples/module.conf for a better overview
-# of what a configuration file has to offer and what different
-# settings mean and do.
-
-bind 127.0.0.1 8080
-chroot /home/joris/src/kore
-runas joris
-workers 4
-pidfile kore.pid
-load contrib/modules/pgsql_test/pgsql_test.module pgsql_load
-ssl_no_compression
-
-domain localhost {
- certfile cert/server.crt
- certkey cert/server.key
- accesslog kore_pgsql.log
-
- static / serve_pgsql_test
-}
diff --git a/contrib/modules/pgsql_test/src/pgsql_test.c b/contrib/modules/pgsql_test/src/pgsql_test.c
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2014 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 "kore.h"
-#include "http.h"
-#include "kore_pgsql.h"
-
-#include "static.h"
-
-void pgsql_load(int);
-int serve_pgsql_test(struct http_request *);
-
-void
-pgsql_load(int state)
-{
- switch (state) {
- case KORE_MODULE_LOAD:
- pgsql_conn_string = "Your connection string";
- break;
- default:
- break;
- }
-}
-
-int
-serve_pgsql_test(struct http_request *req)
-{
- int r, i;
- char *col1, *col2;
-
- KORE_PGSQL(req, "SELECT * FROM test", 0, {
- if (req->pgsql[0]->state == KORE_PGSQL_STATE_ERROR) {
- kore_pgsql_logerror(req->pgsql[0]);
- http_response(req, 500, "fail\n", 5);
- return (KORE_RESULT_OK);
- }
-
- r = kore_pgsql_ntuples(req->pgsql[0]);
- for (i = 0; i < r; i++) {
- col1 = kore_pgsql_getvalue(req->pgsql[0], i, 0);
- col2 = kore_pgsql_getvalue(req->pgsql[0], i, 1);
-
- kore_log(LOG_NOTICE, "%s and %s", col1, col2);
- }
- });
-
- KORE_PGSQL(req, "SELECT * FROM foobar", 1, {
- if (req->pgsql[1]->state != KORE_PGSQL_STATE_ERROR) {
- kore_log(LOG_NOTICE, "expected error, got %d",
- req->pgsql[1]->state);
- http_response(req, 500, "fail2\n", 6);
- return (KORE_RESULT_OK);
- } else {
- kore_pgsql_logerror(req->pgsql[1]);
- }
- });
-
- /* Query successfully completed */
- http_response(req, 200, "ok\n", 3);
-
- return (KORE_RESULT_OK);
-}
diff --git a/contrib/modules/pgsql_test/tools/inject.c b/contrib/modules/pgsql_test/tools/inject.c
@@ -1,119 +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 <inttypes.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if defined(OpenBSD)
-#define PRI_TIME_T "d"
-#endif
-
-#if defined(linux)
-#if defined(__x86_64__)
-#define PRI_TIME_T PRIu64
-#else
-#define PRI_TIME_T "ld"
-#endif
-#endif
-
-#if defined(__MACH__)
-#define PRI_TIME_T "ld"
-#endif
-
-int
-main(int argc, char *argv[])
-{
- struct stat st;
- ssize_t len;
- FILE *hdr;
- char *ext;
- unsigned char 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 = %" PRIu32 ";\n",
- ext, argv[2], (u_int32_t)st.st_size);
-
- printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\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/contrib/modules/skeleton/build.sh b/contrib/modules/skeleton/build.sh
@@ -1,86 +0,0 @@
-#!/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=site.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.
-MEDIA_DIR=media
-
-# The directory containing your module source.
-SOURCE_DIR=src
-
-# The directory containing the Kore source code.
-KORE_DIR="notset"
-if [ ${KORE_DIR} = "notset" ]; then
- echo "Please edit build.sh and set KORE_DIR properly";
- exit;
-fi
-
-# 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"
-
-OSNAME=$(uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
-if [ "${OSNAME}" = "darwin" ]; then
- LDFLAGS="-dynamiclib -undefined suppress -flat_namespace"
-else
- LDFLAGS="-shared"
-fi
-
-MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
-
-### Begin building ####
-echo "Building module ${MODULE}..."
-rm -f ${MODULE}
-
-${CC} ${CFLAGS} tools/inject.c -o tools/inject
-
-if [ ! -d ${SOURCE_DIR}/${MEDIA_DIR} ]; then
- mkdir ${SOURCE_DIR}/${MEDIA_DIR};
-fi
-rm -f ${SOURCE_DIR}/${MEDIA_DIR}/*
-
-if [ ! -d .objs ]; then
- mkdir .objs;
-fi
-rm -f .objs/*
-
-rm -f static.h
-
-for file in `find ${MEDIA_DIR} -type f \( ! -name \*.swp \)`; 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
-
-echo "#define MODULE_BUILD_DATE \"${MODULE_BUILD_DATE}\"" >> static.h
-
-for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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
-rm -f static.h
diff --git a/contrib/modules/skeleton/media/.gitignore b/contrib/modules/skeleton/media/.gitignore
diff --git a/contrib/modules/skeleton/src/.gitignore b/contrib/modules/skeleton/src/.gitignore
diff --git a/contrib/modules/skeleton/tools/inject.c b/contrib/modules/skeleton/tools/inject.c
@@ -1,119 +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 <inttypes.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if defined(OpenBSD)
-#define PRI_TIME_T "d"
-#endif
-
-#if defined(linux)
-#if defined(__x86_64__)
-#define PRI_TIME_T PRIu64
-#else
-#define PRI_TIME_T "ld"
-#endif
-#endif
-
-#if defined(__MACH__)
-#define PRI_TIME_T "ld"
-#endif
-
-int
-main(int argc, char *argv[])
-{
- struct stat st;
- ssize_t len;
- FILE *hdr;
- char *ext;
- unsigned char 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 = %" PRIu32 ";\n",
- ext, argv[2], (u_int32_t)st.st_size);
-
- printf("time_t static_mtime_%s_%s = %" PRI_TIME_T ";\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/contrib/modules/task_curl/build.sh b/contrib/modules/task_curl/build.sh
@@ -1,48 +0,0 @@
-#!/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=task_curl.so
-
-# The directory containing your module source.
-SOURCE_DIR=.
-
-# 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 -lcurl"
-
-MODULE_BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S")
-
-### Begin building ####
-echo "Building module ${MODULE}..."
-rm -f ${MODULE}
-
-if [ ! -d .objs ]; then
- mkdir .objs;
-fi
-rm -f .objs/*
-
-for src in `find ${SOURCE_DIR} -type f -name \*.c`; 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 .objs
diff --git a/contrib/modules/task_curl/example.c b/contrib/modules/task_curl/example.c
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2014 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.
- */
-
-/*
- * In this example, we use the background tasks available in Kore
- * to fire off a POST to our /post_back page handler containing
- * the user argument that was passed to us in our GET request to /.
- *
- * This illustrates how Kore its background tasks in effect work and
- * how to operate on the channel in order to pass data back and forth.
- *
- * The page_handler() page handler is not called until the background
- * task it fired off has completed.
- *
- * You need libcurl installed for this to build (including headers)
- *
- * Compile using build.sh, afterwards start using:
- * # kore -nc module.conf (depending on where kore is installed)
- *
- * Test using:
- * # curl -k https://127.0.0.1:4443/?user=foobar
- *
- * If the result echo'd back matches what you specified, its all green.
- */
-
-#include <curl/curl.h>
-
-#include "kore.h"
-#include "http.h"
-#include "kore_tasks.h"
-
-int run_curl(struct kore_task *);
-int post_back(struct http_request *);
-int page_handler(struct http_request *);
-size_t curl_write_cb(char *, size_t, size_t, void *);
-
-int
-page_handler(struct http_request *req)
-{
- u_int32_t len;
- char *user, result[64];
-
- /*
- * Lets check if a task has been created yet, this is important
- * as we only want to fire this off once and we will be called
- * again once it has been created.
- */
- if (req->task == NULL) {
- /* Grab the user argument */
- http_populate_arguments(req);
- if (!http_argument_get_string("user", &user, &len)) {
- http_response(req, 500, "ERROR\n", 6);
- return (KORE_RESULT_OK);
- }
-
- /*
- * Create a new task that will execute the run_curl()
- * function and bind it to our request.
- *
- * Binding a task to a request means Kore will reschedule
- * the page handler for that request to refire after the
- * task has completed.
- */
- kore_task_create(&req->task, run_curl);
- kore_task_bind_request(req->task, req);
-
- /*
- * Start the task and write the user we received in our
- * GET request to its channel.
- */
- kore_task_run(req->task);
- kore_task_channel_write(req->task, user, len);
-
- /*
- * Tell Kore to retry us later.
- */
- return (KORE_RESULT_RETRY);
- }
-
- /*
- * When we come back here, our background task is finished
- * and we can check its result.
- */
- if (req->task->result != KORE_RESULT_OK) {
- kore_task_destroy(req->task);
- http_response(req, 500, NULL, 0);
- return (KORE_RESULT_OK);
- }
-
- /*
- * Lets read what our task has written to the channel.
- *
- * kore_task_channel_read() will return the amount of bytes
- * that it received for that read. If the returned bytes is
- * larger then the buffer you passed this is a sign of truncation
- * and should be treated carefully.
- */
- len = kore_task_channel_read(req->task, result, sizeof(result));
- if (len >= sizeof(result)) {
- http_response(req, 500, NULL, 0);
- } else {
- http_response(req, 200, result, len);
- }
-
- /* We good, destroy the task. */
- kore_task_destroy(req->task);
-
- return (KORE_RESULT_OK);
-}
-
-int
-post_back(struct http_request *req)
-{
- u_int32_t len;
- char *user;
-
- if (req->method != HTTP_METHOD_POST) {
- http_response(req, 500, NULL, 0);
- return (KORE_RESULT_OK);
- }
-
- http_populate_arguments(req);
- if (!http_argument_get_string("user", &user, &len)) {
- http_response(req, 500, NULL, 0);
- return (KORE_RESULT_OK);
- }
-
- /* Simply echo the supplied user argument back. */
- http_response(req, 200, user, len);
-
- return (KORE_RESULT_OK);
-}
-
-/*
- * This is the function that is executed by our task which is created
- * in the page_handler() callback.
- *
- * It sets up a CURL POST request to /post_back passing along the
- * user argument which it receives from its channel from page_handler().
- */
-int
-run_curl(struct kore_task *t)
-{
- int l;
- struct kore_buf *b;
- u_int32_t len;
- CURLcode res;
- u_int8_t *data;
- CURL *curl;
- char user[64], fields[128];
-
- /*
- * Read the channel in order to obtain the user argument
- * that was written to it by page_handler().
- */
- len = kore_task_channel_read(t, user, sizeof(user));
- if (len >= sizeof(user))
- return (KORE_RESULT_ERROR);
-
- l = snprintf(fields, sizeof(fields), "user=%.*s", len, user);
- if (l == -1 || (size_t)l >= sizeof(fields))
- return (KORE_RESULT_ERROR);
-
- if ((curl = curl_easy_init()) == NULL)
- return (KORE_RESULT_ERROR);
-
- b = kore_buf_create(128);
-
- /* Do CURL magic. */
- curl_easy_setopt(curl, CURLOPT_POST, 1);
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, b);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);
- curl_easy_setopt(curl, CURLOPT_URL, "https://127.0.0.1:4443/post_back");
-
- res = curl_easy_perform(curl);
- if (res != CURLE_OK) {
- kore_buf_free(b);
- curl_easy_cleanup(curl);
- return (KORE_RESULT_ERROR);
- }
-
- /*
- * Grab the response from the CURL request and write the
- * result back to the task channel.
- */
- data = kore_buf_release(b, &len);
- kore_task_channel_write(t, data, len);
- kore_mem_free(data);
-
- return (KORE_RESULT_OK);
-}
-
-size_t
-curl_write_cb(char *ptr, size_t size, size_t nmemb, void *udata)
-{
- struct kore_buf *b = udata;
-
- kore_buf_append(b, ptr, size * nmemb);
- return (size * nmemb);
-}
diff --git a/contrib/modules/task_curl/module.conf b/contrib/modules/task_curl/module.conf
@@ -1,31 +0,0 @@
-# Configuration for the contrib/modules/task_curl example.
-
-bind 127.0.0.1 4443
-chroot # configure this (ex: /home/joris/src/kore)
-runas # configure this (ex: joris)
-
-workers 1
-pidfile kore.pid
-
-load ./task_curl.so
-
-ssl_no_compression
-
-validator v_user regex ^[a-z]*$
-
-domain 127.0.0.1 {
- certfile # configure this (ex: cert/server.crt)
- certkey # configure this (ex: cert/server.key)
- accesslog kore_access.log
-
- static / page_handler
- static /post_back post_back
-
- params get / {
- validate user v_user
- }
-
- params post /post_back {
- validate user v_user
- }
-}