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 }