kore

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

commit a228cdba0ed434a6b8418abace9684f9c58323f2
parent 39afa6c25b9a51f07f06384c5155d791e9bbb6ff
Author: Joris Vink <joris@coders.se>
Date:   Wed,  1 May 2013 20:10:45 +0200

introduce kore_split_string() to properly split strings apart.
introduce kore_date_to_time() to conver http-date formatted strings to time_t.

Diffstat:
includes/http.h | 1+
includes/kore.h | 2++
src/config.c | 10++--------
src/http.c | 1+
src/kore.c | 1+
src/utils.c | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 122 insertions(+), 8 deletions(-)

diff --git a/includes/http.h b/includes/http.h @@ -30,6 +30,7 @@ struct http_request { void http_init(void); void http_process(void); +time_t http_date_to_time(char *); void http_request_free(struct http_request *); int http_response(struct http_request *, int, u_int8_t *, u_int32_t, char *); diff --git a/includes/kore.h b/includes/kore.h @@ -95,10 +95,12 @@ extern char *server_ip; void *kore_malloc(size_t); void *kore_calloc(size_t, size_t); void *kore_realloc(void *, size_t); +time_t kore_date_to_time(char *); 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 *); +int kore_split_string(char *, char *, char **, size_t); long long kore_strtonum(const char *, long long, long long, int *); void kore_module_load(char *); diff --git a/src/config.c b/src/config.c @@ -57,7 +57,7 @@ kore_parse_config(const char *config_path) { FILE *fp; int i, lineno; - char buf[BUFSIZ], *p, *t, **ap, *argv[5]; + char buf[BUFSIZ], *p, *t, *argv[5]; if ((fp = fopen(config_path, "r")) == NULL) fatal("configuration given cannot be opened: %s", config_path); @@ -79,13 +79,7 @@ kore_parse_config(const char *config_path) *t = ' '; } - for (ap = argv; ap < &argv[4] && - (*ap = strsep(&p, " ")) != NULL;) { - if (**ap != '\0') - ap++; - } - *ap = NULL; - + kore_split_string(p, " ", argv, 5); for (i = 0; config_names[i].name != NULL; i++) { if (!strcmp(config_names[i].name, argv[0])) { if (!config_names[i].configure(argv)) { diff --git a/src/http.c b/src/http.c @@ -31,6 +31,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <zlib.h> #include "spdy.h" diff --git a/src/kore.c b/src/kore.c @@ -32,6 +32,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <time.h> #include <zlib.h> #include "spdy.h" diff --git a/src/utils.c b/src/utils.c @@ -36,6 +36,25 @@ #include "spdy.h" #include "kore.h" +static struct { + char *name; + int value; +} month_names[] = { + { "Jan", 0 }, + { "Feb", 1 }, + { "Mar", 2 }, + { "Apr", 3 }, + { "May", 4 }, + { "Jun", 5 }, + { "Jul", 6 }, + { "Aug", 7 }, + { "Sep", 8 }, + { "Oct", 9 }, + { "Nov", 10 }, + { "Dec", 11 }, + { NULL, 0 }, +}; + void * kore_malloc(size_t len) { @@ -140,6 +159,102 @@ kore_strtonum(const char *str, long long min, long long max, int *err) return (l); } +int +kore_split_string(char *input, char *delim, char **out, size_t ele) +{ + int count; + char **ap; + + count = 0; + for (ap = out; ap < &out[ele - 1] && + (*ap = strsep(&input, delim)) != NULL;) { + if (**ap != '\0') { + ap++; + count++; + } + } + + *ap = NULL; + return (count); +} + +time_t +kore_date_to_time(char *http_date) +{ + time_t t; + int err, i; + struct tm tm, *gtm; + char *args[7], *tbuf[5], *sdup; + + time(&t); + gtm = gmtime(&t); + sdup = kore_strdup(http_date); + + t = KORE_RESULT_ERROR; + + if (kore_split_string(sdup, " ", args, 7) != 6) { + kore_log("misformed http-date: '%s'", http_date); + goto out; + } + + tm.tm_year = kore_strtonum(args[3], 2013, 2068, &err) - 1900; + if (err == KORE_RESULT_ERROR || tm.tm_year < gtm->tm_year) { + kore_log("misformed year in http-date: '%s'", http_date); + goto out; + } + + for (i = 0; month_names[i].name != NULL; i++) { + if (!strcmp(month_names[i].name, args[2])) { + tm.tm_mon = month_names[i].value; + break; + } + } + + if (month_names[i].name == NULL) { + kore_log("misformed month in http-date: '%s'", http_date); + goto out; + } + + tm.tm_mday = kore_strtonum(args[1], 1, 31, &err); + if (err == KORE_RESULT_ERROR) { + kore_log("misformed mday in http-date: '%s'", http_date); + goto out; + } + + if (kore_split_string(args[4], ":", tbuf, 5) != 3) { + kore_log("misformed HH:MM:SS in http-date: '%s'", http_date); + goto out; + } + + tm.tm_hour = kore_strtonum(tbuf[0], 1, 23, &err); + if (err == KORE_RESULT_ERROR) { + kore_log("misformed hour in http-date: '%s'", http_date); + goto out; + } + + tm.tm_min = kore_strtonum(tbuf[1], 1, 59, &err); + if (err == KORE_RESULT_ERROR) { + kore_log("misformed minutes in http-date: '%s'", http_date); + goto out; + } + + tm.tm_sec = kore_strtonum(tbuf[2], 0, 60, &err); + if (err == KORE_RESULT_ERROR) { + kore_log("misformed seconds in http-date: '%s'", http_date); + goto out; + } + + t = mktime(&tm); + if (t == -1) { + t = 0; + kore_log("mktime() on '%s' failed", http_date); + } + +out: + free(sdup); + return (t); +} + void fatal(const char *fmt, ...) {