kore/examples/generic/src/example.c

347 lines
8.4 KiB
C

/*
* 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/kore.h>
#include <kore/http.h>
#include <openssl/sha.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include "assets.h"
int 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_file_upload(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 *);
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
};
int
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;
}
return (KORE_RESULT_OK);
}
int
serve_style_css(struct http_request *req)
{
char *date;
time_t tstamp;
tstamp = 0;
if (http_request_header(req, "if-modified-since", &date)) {
tstamp = kore_date_to_time(date);
kore_debug("header was present with %ld", tstamp);
}
if (tstamp != 0 && tstamp <= asset_mtime_style_css) {
http_response(req, 304, NULL, 0);
} else {
date = kore_time_to_date(asset_mtime_style_css);
if (date != NULL)
http_response_header(req, "last-modified", date);
http_response_header(req, "content-type", "text/css");
http_response(req, 200, asset_style_css, asset_len_style_css);
}
return (KORE_RESULT_OK);
}
int
serve_index(struct http_request *req)
{
http_response_header(req, "content-type", "text/html");
http_response(req, 200, asset_index_html, asset_len_index_html);
return (KORE_RESULT_OK);
}
int
serve_intro(struct http_request *req)
{
http_response_header(req, "content-type", "image/jpg");
http_response(req, 200, asset_intro_jpg, asset_len_intro_jpg);
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(req, "content-type", "text/plain");
http_response(req, 200, data, len);
kore_mem_free(data);
return (KORE_RESULT_OK);
}
int
serve_file_upload(struct http_request *req)
{
u_int8_t *d;
struct kore_buf *b;
struct http_file *f;
u_int32_t len;
char *name, buf[BUFSIZ];
b = kore_buf_create(asset_len_upload_html);
kore_buf_append(b, asset_upload_html, asset_len_upload_html);
if (req->method == HTTP_METHOD_POST) {
if (req->http_body_fd != -1)
kore_log(LOG_NOTICE, "file is on disk");
http_populate_multipart_form(req);
if (http_argument_get_string(req, "firstname", &name)) {
kore_buf_replace_string(b, "$firstname$",
name, strlen(name));
} else {
kore_buf_replace_string(b, "$firstname$", NULL, 0);
}
if ((f = http_file_lookup(req, "file")) != NULL) {
(void)snprintf(buf, sizeof(buf),
"%s is %ld bytes", f->filename, f->length);
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(req, "content-type", "text/html");
http_response(req, 200, d, len);
kore_mem_free(d);
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];
if (req->method == HTTP_METHOD_GET)
http_populate_get(req);
else if (req->method == HTTP_METHOD_POST)
http_populate_post(req);
b = kore_buf_create(asset_len_params_html);
kore_buf_append(b, asset_params_html, asset_len_params_html);
/*
* The GET parameters will be filtered out on POST.
*/
if (http_argument_get_string(req, "arg1", &test)) {
kore_buf_replace_string(b, "$arg1$", test, strlen(test));
} else {
kore_buf_replace_string(b, "$arg1$", NULL, 0);
}
if (http_argument_get_string(req, "arg2", &test)) {
kore_buf_replace_string(b, "$arg2$", test, strlen(test));
} 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(req, "id", &r))
kore_log(LOG_NOTICE, "id: %d", r);
else
kore_log(LOG_NOTICE, "No id set");
http_response_header(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++) {
(void)snprintf(name, sizeof(name), "test%d", i);
if (http_argument_get_string(req, name, &test)) {
(void)snprintf(name, sizeof(name), "$test%d$", i);
kore_buf_replace_string(b, name, test, strlen(test));
} else {
(void)snprintf(name, sizeof(name), "$test%d$", i);
kore_buf_replace_string(b, name, NULL, 0);
}
}
http_response_header(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(req, "content-type", "text/html");
http_response_header(req, "set-cookie", "session_id=test123");
http_response(req, 200, asset_private_html, asset_len_private_html);
return (KORE_RESULT_OK);
}
int
serve_private_test(struct http_request *req)
{
http_response_header(req, "content-type", "text/html");
http_response(req, 200, asset_private_test_html,
asset_len_private_test_html);
return (KORE_RESULT_OK);
}
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);
}