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

example.c (7275B)



      1 /*
      2  * Copyright (c) 2013 Joris Vink <joris@coders.se>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include <kore/kore.h>
     18 #include <kore/http.h>
     19 
     20 #include <openssl/sha.h>
     21 
     22 #include <fcntl.h>
     23 #include <stdlib.h>
     24 #include <unistd.h>
     25 
     26 #include "assets.h"
     27 
     28 int		example_load(int);
     29 
     30 int		serve_b64test(struct http_request *);
     31 int		serve_file_upload(struct http_request *);
     32 int		serve_validator(struct http_request *);
     33 int		serve_params_test(struct http_request *);
     34 int		serve_private(struct http_request *);
     35 int		serve_private_test(struct http_request *);
     36 
     37 int		v_example_func(struct http_request *, char *);
     38 int		v_session_validate(struct http_request *, char *);
     39 void		test_base64(u_int8_t *, u_int32_t, struct kore_buf *);
     40 
     41 char *b64tests[] = {
     42 	"1234567890",
     43 	"One two three four five",
     44 	"Man",
     45 	"any carnal pleasure.",
     46 	"any carnal pleasure",
     47 	"any carnal pleas",
     48 	"I am a nobody, nobody is perfect, therefore I am.",
     49 	NULL
     50 };
     51 
     52 int
     53 example_load(int state)
     54 {
     55 	switch (state) {
     56 	case KORE_MODULE_LOAD:
     57 		kore_log(LOG_NOTICE, "module loading");
     58 
     59 		/* Set server version */
     60 		http_server_version("Server/0.1");
     61 		break;
     62 	case KORE_MODULE_UNLOAD:
     63 		kore_log(LOG_NOTICE, "module unloading");
     64 		break;
     65 	default:
     66 		kore_log(LOG_NOTICE, "state %d unknown!", state);
     67 		break;
     68 	}
     69 
     70 	return (KORE_RESULT_OK);
     71 }
     72 
     73 int
     74 serve_b64test(struct http_request *req)
     75 {
     76 	int			i;
     77 	size_t			len;
     78 	struct kore_buf		*res;
     79 	u_int8_t		*data;
     80 
     81 	res = kore_buf_alloc(1024);
     82 	for (i = 0; b64tests[i] != NULL; i++)
     83 		test_base64((u_int8_t *)b64tests[i], strlen(b64tests[i]), res);
     84 
     85 	data = kore_buf_release(res, &len);
     86 
     87 	http_response_header(req, "content-type", "text/plain");
     88 	http_response(req, 200, data, len);
     89 	kore_free(data);
     90 
     91 	return (KORE_RESULT_OK);
     92 }
     93 
     94 int
     95 serve_file_upload(struct http_request *req)
     96 {
     97 	u_int8_t		*d;
     98 	struct kore_buf		*b;
     99 	struct http_file	*f;
    100 	size_t			len;
    101 	char			*name, buf[BUFSIZ];
    102 
    103 	b = kore_buf_alloc(asset_len_upload_html);
    104 	kore_buf_append(b, asset_upload_html, asset_len_upload_html);
    105 
    106 	if (req->method == HTTP_METHOD_POST) {
    107 		if (req->http_body_fd != -1)
    108 			kore_log(LOG_NOTICE, "file is on disk");
    109 
    110 		http_populate_multipart_form(req);
    111 		if (http_argument_get_string(req, "firstname", &name)) {
    112 			kore_buf_replace_string(b, "$firstname$",
    113 			    name, strlen(name));
    114 		} else {
    115 			kore_buf_replace_string(b, "$firstname$", NULL, 0);
    116 		}
    117 
    118 		if ((f = http_file_lookup(req, "file")) != NULL) {
    119 			(void)snprintf(buf, sizeof(buf),
    120 			    "%s is %ld bytes", f->filename, f->length);
    121 			kore_buf_replace_string(b,
    122 			    "$upload$", buf, strlen(buf));
    123 		} else {
    124 			kore_buf_replace_string(b, "$upload$", NULL, 0);
    125 		}
    126 	} else {
    127 		kore_buf_replace_string(b, "$upload$", NULL, 0);
    128 		kore_buf_replace_string(b, "$firstname$", NULL, 0);
    129 	}
    130 
    131 	d = kore_buf_release(b, &len);
    132 
    133 	http_response_header(req, "content-type", "text/html");
    134 	http_response(req, 200, d, len);
    135 	kore_free(d);
    136 
    137 	return (KORE_RESULT_OK);
    138 }
    139 
    140 void
    141 test_base64(u_int8_t *src, u_int32_t slen, struct kore_buf *res)
    142 {
    143 	char		*in;
    144 	size_t		len;
    145 	u_int8_t	*out;
    146 
    147 	kore_buf_appendf(res, "test '%s'\n", src);
    148 
    149 	if (!kore_base64_encode(src, slen, &in)) {
    150 		kore_buf_appendf(res, "encoding '%s' failed\n", src);
    151 	} else {
    152 		kore_buf_appendf(res, "encoded: '%s'\n", in);
    153 
    154 		if (!kore_base64_decode(in, &out, &len)) {
    155 			kore_buf_appendf(res, "decoding failed\n");
    156 		} else {
    157 			kore_buf_appendf(res, "decoded: ");
    158 			kore_buf_append(res, out, len);
    159 			kore_buf_appendf(res, "\n");
    160 			kore_free(out);
    161 		}
    162 
    163 		kore_free(in);
    164 	}
    165 
    166 	kore_buf_appendf(res, "\n");
    167 }
    168 
    169 int
    170 serve_validator(struct http_request *req)
    171 {
    172 	if (kore_validator_run(NULL, "v_example", "test"))
    173 		kore_log(LOG_NOTICE, "v_example ok (expected)");
    174 	else
    175 		kore_log(LOG_NOTICE, "v_example failed");
    176 
    177 	if (kore_validator_run(NULL, "v_regex", "/test/123"))
    178 		kore_log(LOG_NOTICE, "regex #1 ok");
    179 	else
    180 		kore_log(LOG_NOTICE, "regex #1 failed (expected)");
    181 
    182 	if (kore_validator_run(NULL, "v_regex", "/test/joris"))
    183 		kore_log(LOG_NOTICE, "regex #2 ok (expected)");
    184 	else
    185 		kore_log(LOG_NOTICE, "regex #2 failed");
    186 
    187 	http_response(req, 200, "OK", 2);
    188 
    189 	return (KORE_RESULT_OK);
    190 }
    191 
    192 int
    193 serve_params_test(struct http_request *req)
    194 {
    195 	struct kore_buf		*b;
    196 	u_int8_t		*d;
    197 	size_t			len;
    198 	int			r, i;
    199 	char			*test, name[10];
    200 
    201 	if (req->method == HTTP_METHOD_GET)
    202 		http_populate_get(req);
    203 	else if (req->method == HTTP_METHOD_POST)
    204 		http_populate_post(req);
    205 
    206 	b = kore_buf_alloc(asset_len_params_html);
    207 	kore_buf_append(b, asset_params_html, asset_len_params_html);
    208 
    209 	/*
    210 	 * The GET parameters will be filtered out on POST.
    211 	 */
    212 	if (http_argument_get_string(req, "arg1", &test)) {
    213 		kore_buf_replace_string(b, "$arg1$", test, strlen(test));
    214 	} else {
    215 		kore_buf_replace_string(b, "$arg1$", NULL, 0);
    216 	}
    217 
    218 	if (http_argument_get_string(req, "arg2", &test)) {
    219 		kore_buf_replace_string(b, "$arg2$", test, strlen(test));
    220 	} else {
    221 		kore_buf_replace_string(b, "$arg2$", NULL, 0);
    222 	}
    223 
    224 	if (req->method == HTTP_METHOD_GET) {
    225 		kore_buf_replace_string(b, "$test1$", NULL, 0);
    226 		kore_buf_replace_string(b, "$test2$", NULL, 0);
    227 		kore_buf_replace_string(b, "$test3$", NULL, 0);
    228 
    229 		if (http_argument_get_uint16(req, "id", &r))
    230 			kore_log(LOG_NOTICE, "id: %d", r);
    231 		else
    232 			kore_log(LOG_NOTICE, "No id set");
    233 
    234 		http_response_header(req, "content-type", "text/html");
    235 		d = kore_buf_release(b, &len);
    236 		http_response(req, 200, d, len);
    237 		kore_free(d);
    238 
    239 		return (KORE_RESULT_OK);
    240 	}
    241 
    242 	for (i = 1; i < 4; i++) {
    243 		(void)snprintf(name, sizeof(name), "test%d", i);
    244 		if (http_argument_get_string(req, name, &test)) {
    245 			(void)snprintf(name, sizeof(name), "$test%d$", i);
    246 			kore_buf_replace_string(b, name, test, strlen(test));
    247 		} else {
    248 			(void)snprintf(name, sizeof(name), "$test%d$", i);
    249 			kore_buf_replace_string(b, name, NULL, 0);
    250 		}
    251 	}
    252 
    253 	http_response_header(req, "content-type", "text/html");
    254 	d = kore_buf_release(b, &len);
    255 	http_response(req, 200, d, len);
    256 	kore_free(d);
    257 
    258 	return (KORE_RESULT_OK);
    259 }
    260 
    261 int
    262 serve_private(struct http_request *req)
    263 {
    264 	http_response_header(req, "content-type", "text/html");
    265 	http_response_header(req, "set-cookie", "session_id=test123");
    266 	http_response(req, 200, asset_private_html, asset_len_private_html);
    267 
    268 	return (KORE_RESULT_OK);
    269 }
    270 
    271 int
    272 v_example_func(struct http_request *req, char *data)
    273 {
    274 	kore_log(LOG_NOTICE, "v_example_func called");
    275 
    276 	if (!strcmp(data, "test"))
    277 		return (KORE_RESULT_OK);
    278 
    279 	return (KORE_RESULT_ERROR);
    280 }
    281 
    282 int
    283 v_session_validate(struct http_request *req, char *data)
    284 {
    285 	kore_log(LOG_NOTICE, "v_session_validate: %s", data);
    286 
    287 	if (!strcmp(data, "test123"))
    288 		return (KORE_RESULT_OK);
    289 
    290 	return (KORE_RESULT_ERROR);
    291 }