aboutsummaryrefslogtreecommitdiff
path: root/src/clog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/clog.c')
-rw-r--r--src/clog.c161
1 files changed, 136 insertions, 25 deletions
diff --git a/src/clog.c b/src/clog.c
index 9364a2f..767d731 100644
--- a/src/clog.c
+++ b/src/clog.c
@@ -21,7 +21,8 @@ KORE_SECCOMP_FILTER("clog",
int init(int);
int post(struct http_request *);
int posts(struct http_request *);
-int render_posts(struct http_request *, const char *);
+int render_posts_html(struct http_request *, const char *);
+int render_posts_json(struct http_request *, const char *);
static void process_md_output(const MD_CHAR *, MD_SIZE size, void *);
static int render_md(char *, struct kore_buf *);
@@ -32,30 +33,54 @@ int
init(int state)
{
// Register the database
- int err = kore_pgsql_register(
+ return kore_pgsql_register(
database,
"host=postgres port=5432 user=postgres password=postgres dbname=clog sslmode=disable"
);
- return err;
}
int
post(struct http_request *req)
{
- const char *resource;
+ int err;
+
+ const char *accept, *resource;
+
resource = req->path + strlen("/posts/");
kore_log(LOG_DEBUG, "Resource /posts/%s", resource);
- return render_posts(req, resource);
+
+ err = http_request_header(req, "accept", &accept);
+ if (err == KORE_RESULT_OK) {
+ kore_log(LOG_DEBUG, "Accept: %s", accept);
+ if (strcmp(accept, "application/json") == 0) {
+ return render_posts_json(req, resource);
+ }
+ }
+
+ return render_posts_html(req, resource);
}
int
posts(struct http_request *req)
{
- return render_posts(req, NULL);
+ int err;
+
+ const char *accept;
+
+ err = http_request_header(req, "accept", &accept);
+ err = http_request_header(req, "accept", &accept);
+ if (err == KORE_RESULT_OK) {
+ kore_log(LOG_DEBUG, "Accept: %s", accept);
+ if (strcmp(accept, "application/json") == 0) {
+ return render_posts_json(req, NULL);
+ }
+ }
+
+ return render_posts_html(req, NULL);
}
int
-render_posts(struct http_request *req, const char *resource)
+render_posts_html(struct http_request *req, const char *resource)
{
// Errors
int err;
@@ -81,8 +106,7 @@ render_posts(struct http_request *req, const char *resource)
// kore_pgsql_register()). We also say we will perform a synchronous
// query (KORE_PGSQL_SYNC).
err = kore_pgsql_setup(&sql, database, KORE_PGSQL_SYNC);
- kore_log(LOG_DEBUG, "kore_pgsql_setup: %d", err);
- if (!err)
+ if (err == KORE_RESULT_ERROR)
{
kore_buf_appendf(
resp_buf,
@@ -94,26 +118,25 @@ render_posts(struct http_request *req, const char *resource)
}
// Query for posts, check for error.
- if (!resource) {
- // Query all posts.
- err = kore_pgsql_query(
+ if (resource) {
+ // Query a post.
+ err = kore_pgsql_query_params(
&sql,
"SELECT id, title, created_at::DATE, body FROM posts "
- "ORDER BY updated_at DESC;"
+ "WHERE id = $1;",
+ 0, // return string data
+ 1, // param count
+ KORE_PGSQL_PARAM_TEXT(resource)
);
} else {
- // Query a post.
- err = kore_pgsql_query_params(
+ // Query all posts.
+ err = kore_pgsql_query(
&sql,
"SELECT id, title, created_at::DATE, body FROM posts "
- "WHERE id = $1 "
- "ORDER BY updated_at DESC;",
- 0,
- 1,
- KORE_PGSQL_PARAM_TEXT(resource)
+ "ORDER BY updated_at DESC;"
);
}
- if (!err) {
+ if (err == KORE_RESULT_ERROR) {
kore_buf_appendf(
resp_buf,
(const char *) asset_error_html,
@@ -135,7 +158,8 @@ render_posts(struct http_request *req, const char *resource)
// Allocate a buffer to render the markdown as HTML into.
struct kore_buf *html_buf = kore_buf_alloc(0);
// Render MD.
- if (!render_md(body, html_buf)) {
+ err = render_md(body, html_buf);
+ if (err == KORE_RESULT_ERROR) {
kore_log(LOG_ERR, "Error rendering markdown for entry %s.", id);
kore_buf_free(html_buf);
continue;
@@ -164,7 +188,94 @@ out: ;
kore_pgsql_cleanup(&sql);
kore_buf_free(resp_buf);
- return (KORE_RESULT_OK);
+ return KORE_RESULT_OK;
+}
+
+int
+render_posts_json(struct http_request *req, const char *resource) {
+ // Errors
+ int err;
+
+ // Buffer for response
+ struct kore_buf *resp_buf = kore_buf_alloc(0);
+
+ // SQL vars
+ struct kore_pgsql sql;
+ int rows;
+
+ // JSON results form PostgreSQL.
+ char *json;
+
+ // Setup SQL
+ kore_pgsql_init(&sql);
+
+ // Initialise our kore_pgsql data structure with the database name
+ // we want to connect to (note that we registered this earlier with
+ // kore_pgsql_register()). We also say we will perform a synchronous
+ // query (KORE_PGSQL_SYNC).
+ err = kore_pgsql_setup(&sql, database, KORE_PGSQL_SYNC);
+ if (err == KORE_RESULT_ERROR)
+ {
+ kore_buf_appendf(
+ resp_buf,
+ (const char *) asset_error_html,
+ "There was an error processing the request."
+ );
+ kore_pgsql_logerror(&sql);
+ goto out;
+ }
+
+ if (resource) {
+ err = kore_pgsql_query_params(
+ &sql,
+ "SELECT JSON_AGG(ROW_TO_JSON(row)) FROM ("
+ "SELECT id, title, body, created_at, updated_at FROM "
+ "posts WHERE id = $1"
+ ") row;",
+ 0, // return string data
+ 1, // param count
+ KORE_PGSQL_PARAM_TEXT(resource)
+ );
+ } else {
+ err = kore_pgsql_query(
+ &sql,
+ "SELECT JSON_AGG(ROW_TO_JSON(row)) FROM ("
+ "SELECT id, title, body, created_at, updated_at FROM "
+ "posts ORDER BY updated_at DESC "
+ ") row;"
+ );
+ }
+ if (err == KORE_RESULT_ERROR) {
+ kore_buf_appendf(
+ resp_buf,
+ (const char *) asset_error_html,
+ "There was an error processing the request."
+ );
+ kore_pgsql_logerror(&sql);
+ goto out;
+ }
+
+ rows = kore_pgsql_ntuples(&sql);
+ if (rows == 1) {
+ json = kore_pgsql_getvalue(&sql, 0, 0);
+ kore_buf_append(
+ resp_buf,
+ json,
+ strlen(json)
+ );
+ } // else {
+
+out: ;
+
+ // Finish building response.
+ http_response_header(req, "content-type", "application/json; charset=utf-8");
+ http_response(req, HTTP_STATUS_OK, resp_buf->data, resp_buf->offset);
+
+ // Cleanup.
+ kore_pgsql_cleanup(&sql);
+ kore_buf_free(resp_buf);
+
+ return KORE_RESULT_OK;
}
static int
@@ -186,10 +297,10 @@ render_md(char *in, struct kore_buf *out)
if(err != 0) {
kore_log(LOG_ERR, "Parsing Markdown failed.\n");
- return -1;
+ return KORE_RESULT_ERROR;
}
- return 1;
+ return KORE_RESULT_OK;
}
static void