commit d9bbb0b1f1ca89d172318e90eb9867b3328b3c69
parent a074258dcc0f7693c5a0abe75e0ff4035d5ba300
Author: Joris Vink <joris@coders.se>
Date: Wed, 1 May 2013 16:03:48 +0200
initial module support
Diffstat:
7 files changed, 186 insertions(+), 22 deletions(-)
diff --git a/Makefile b/Makefile
@@ -3,7 +3,8 @@
CC=gcc
BIN=kore
-S_SRC= src/kore.c src/net.c src/spdy.c src/http.c src/utils.c src/zlib_dict.c
+S_SRC= src/kore.c src/config.c src/net.c src/spdy.c src/http.c \
+ src/module.c src/utils.c src/zlib_dict.c
S_OBJS= $(S_SRC:.c=.o)
CFLAGS+=-I/usr/local/ssl/include
diff --git a/example.conf b/example.conf
@@ -0,0 +1,12 @@
+# Example Kore configuration
+
+# Server configuration.
+bind 10.211.55.3 443
+
+# Load our site module now (containing all the goodies).
+load ../betrippin/betrippin.module
+
+# Declare page handlers below.
+# handler path module_callback
+static /css/style.css betrippin_serve_style_css
+static / betrippin_serve_index
diff --git a/includes/kore.h b/includes/kore.h
@@ -78,12 +78,33 @@ struct connection {
TAILQ_HEAD(, spdy_stream) spdy_streams;
};
+#define HANDLER_TYPE_STATIC 1
+#define HANDLER_TYPE_DYNAMIC 2
+
+struct kore_module_handle {
+ char *uri;
+ void *func;
+ int type;
+
+ TAILQ_ENTRY(kore_module_handle) list;
+};
+
+extern int server_port;
+extern char *server_ip;
+
void *kore_malloc(size_t);
void *kore_calloc(size_t, size_t);
void *kore_realloc(void *, size_t);
char *kore_strdup(const char *);
+void kore_parse_config(const char *);
void kore_strlcpy(char *, const char *, size_t);
void kore_server_disconnect(struct connection *);
+long long kore_strtonum(const char *, long long, long long, int *);
+
+void kore_module_load(char *);
+int kore_module_loaded(void);
+void *kore_module_handler_find(char *);
+int kore_module_handler_new(char *, char *, int);
void fatal(const char *, ...);
void kore_log_internal(char *, int, const char *, ...);
diff --git a/src/http.c b/src/http.c
@@ -39,7 +39,6 @@
TAILQ_HEAD(, http_request) http_requests;
-static int http_generic_cb(struct http_request *);
static int http_generic_404(struct http_request *);
void
@@ -125,7 +124,8 @@ http_response(struct http_request *req, int status, u_int8_t *d, u_int32_t len)
void
http_process(void)
{
- struct http_request *req, *next;
+ struct http_request *req, *next;
+ int (*handler)(struct http_request *);
if (TAILQ_EMPTY(&http_requests))
return;
@@ -134,12 +134,12 @@ http_process(void)
for (req = TAILQ_FIRST(&http_requests); req != NULL; req = next) {
next = TAILQ_NEXT(req, list);
- /* XXX - add module hooks here */
- if (!strcmp(req->path, "/favicon.ico")) {
+ handler = kore_module_handler_find(req->path);
+ if (handler == NULL) {
if (!http_generic_404(req))
kore_server_disconnect(req->owner);
} else {
- if (!http_generic_cb(req))
+ if (!handler(req))
kore_server_disconnect(req->owner);
}
@@ -150,18 +150,6 @@ http_process(void)
}
static int
-http_generic_cb(struct http_request *req)
-{
- u_int32_t len;
-
- kore_log("http_generic_cb(%s, %s, %s)",
- req->host, req->method, req->path);
-
- len = strlen("<p>Hello world</p>");
- return (http_response(req, 200, (u_int8_t *)"<p>Hello world</p>", len));
-}
-
-static int
http_generic_404(struct http_request *req)
{
kore_log("http_generic_404(%s, %s, %s)",
diff --git a/src/kore.c b/src/kore.c
@@ -42,6 +42,8 @@
static int efd = -1;
static SSL_CTX *ssl_ctx = NULL;
+int server_port = 0;
+char *server_ip = NULL;
static int kore_socket_nonblock(int);
static int kore_server_sslstart(void);
@@ -59,11 +61,17 @@ main(int argc, char *argv[])
struct epoll_event *events;
int n, i, *fd;
- if (argc != 3)
- fatal("Usage: kore [ip] [port]");
+ if (argc != 2)
+ fatal("Usage: kore [config file]");
- if (!kore_server_bind(&server, argv[1], atoi(argv[2])))
- fatal("cannot bind to %s:%s", argv[1], argv[2]);
+ kore_parse_config(argv[1]);
+ if (!kore_module_loaded())
+ fatal("no site module was loaded");
+
+ if (server_ip == NULL || server_port == 0)
+ fatal("missing a correct bind directive in configuration");
+ if (!kore_server_bind(&server, server_ip, server_port))
+ fatal("cannot bind to %s:%d", server_ip, server_port);
if (!kore_server_sslstart())
fatal("cannot initiate SSL");
diff --git a/src/module.c b/src/module.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2013 Joris Vink <joris@coders.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/queue.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+#include <ctype.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <zlib.h>
+
+#include "spdy.h"
+#include "kore.h"
+
+static void *mod_handle = NULL;
+static time_t mod_last_mtime = 0;
+
+static TAILQ_HEAD(, kore_module_handle) handlers;
+
+void
+kore_module_load(char *module_name)
+{
+ struct stat st;
+
+ kore_log("kore_module_load(%s)", module_name);
+
+ if (mod_handle != NULL)
+ fatal("site module already loaded, skipping %s", module_name);
+
+ if (stat(module_name, &st) == -1)
+ fatal("stat(%s): %s", module_name, errno_s);
+
+ mod_last_mtime = st.st_mtime;
+ mod_handle = dlopen(module_name, RTLD_NOW);
+ if (mod_handle == NULL)
+ fatal("dlopen(%s) failed", module_name);
+
+ TAILQ_INIT(&handlers);
+}
+
+int
+kore_module_loaded(void)
+{
+ return (mod_handle != NULL ? KORE_RESULT_OK : KORE_RESULT_ERROR);
+}
+
+int
+kore_module_handler_new(char *uri, char *func, int type)
+{
+ void *addr;
+ struct kore_module_handle *hdlr;
+
+ kore_log("kore_module_handler_new(%s, %s, %d)", uri, func, type);
+
+ addr = dlsym(mod_handle, func);
+ if (addr == NULL) {
+ kore_log("function '%s' not found", func);
+ return (KORE_RESULT_ERROR);
+ }
+
+ hdlr = (struct kore_module_handle *)kore_malloc(sizeof(*hdlr));
+ hdlr->uri = kore_strdup(uri);
+ hdlr->func = addr;
+ hdlr->type = type;
+ TAILQ_INSERT_TAIL(&(handlers), hdlr, list);
+
+ return (KORE_RESULT_OK);
+}
+
+void *
+kore_module_handler_find(char *uri)
+{
+ return (NULL);
+}
diff --git a/src/utils.c b/src/utils.c
@@ -107,6 +107,39 @@ kore_strlcpy(char *dst, const char *src, size_t len)
}
}
+long long
+kore_strtonum(const char *str, long long min, long long max, int *err)
+{
+ long long l;
+ char *ep;
+
+ if (min > max) {
+ *err = KORE_RESULT_ERROR;
+ return (0);
+ }
+
+ l = 0;
+ errno = 0;
+ l = strtoll(str, &ep, 10);
+ if (errno != 0 || str == ep || *ep != '\0') {
+ *err = KORE_RESULT_ERROR;
+ return (0);
+ }
+
+ if (l < min) {
+ *err = KORE_RESULT_ERROR;
+ return (0);
+ }
+
+ if (l > max) {
+ *err = KORE_RESULT_ERROR;
+ return (0);
+ }
+
+ *err = KORE_RESULT_OK;
+ return (l);
+}
+
void
fatal(const char *fmt, ...)
{