kore/examples/json_yajl/src/json_yajl.c

99 lines
2.6 KiB
C
Executable File

/*
* Copyright (c) 2013-2018 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 <yajl/yajl_tree.h>
int page(struct http_request *);
int
page(struct http_request *req)
{
ssize_t ret;
struct kore_buf *buf;
char *body;
yajl_val node, v;
char eb[1024];
u_int8_t data[BUFSIZ];
const char *path[] = { "foo", "bar", NULL };
/* We only allow POST/PUT methods. */
if (req->method != HTTP_METHOD_POST &&
req->method != HTTP_METHOD_PUT) {
http_response_header(req, "allow", "POST, PUT");
http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
return (KORE_RESULT_OK);
}
/*
* Read the entire received body into a memory buffer.
*/
buf = kore_buf_alloc(128);
for (;;) {
ret = http_body_read(req, data, sizeof(data));
if (ret == -1) {
kore_buf_free(buf);
kore_log(LOG_NOTICE, "error reading body");
http_response(req, 500, NULL, 0);
return (KORE_RESULT_OK);
}
if (ret == 0)
break;
kore_buf_append(buf, data, ret);
}
/* Grab our body data as a NUL-terminated string. */
body = kore_buf_stringify(buf, NULL);
/* Parse the body via yajl now. */
node = yajl_tree_parse(body, eb, sizeof(eb));
if (node == NULL) {
if (strlen(eb)) {
kore_log(LOG_NOTICE, "parse error: %s", eb);
} else {
kore_log(LOG_NOTICE, "parse error: unknown");
}
kore_buf_free(buf);
http_response(req, 400, NULL, 0);
return (KORE_RESULT_OK);
}
/* Reuse old buffer, don't need it anymore for body. */
kore_buf_reset(buf);
/* Attempt to grab foo.bar from the JSON tree. */
v = yajl_tree_get(node, path, yajl_t_string);
if (v == NULL) {
kore_buf_appendf(buf, "no such path: foo.bar\n");
} else {
kore_buf_appendf(buf, "foo.bar = '%s'\n", YAJL_GET_STRING(v));
}
/* Release the JSON tree now. */
yajl_tree_free(node);
/* Respond to the client. */
http_response(req, 200, buf->data, buf->offset);
kore_buf_free(buf);
return (KORE_RESULT_OK);
}