aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael McVady <femtonaut@gmail.com>2023-01-06 06:31:15 -0600
committerMichael McVady <femtonaut@gmail.com>2023-01-06 06:31:15 -0600
commit850df3b8721963b6fefc226b533c347cde79ff25 (patch)
tree4cba77c8f758d251ba61883820801abc879091c7
parentd88f5cced222ac76511702a80e26dc7de8af93f3 (diff)
Hack in POST handling; needs refactoring
-rw-r--r--README.md10
-rw-r--r--conf/clog.conf9
-rw-r--r--src/clog.c110
-rwxr-xr-xtests.py25
4 files changed, 105 insertions, 49 deletions
diff --git a/README.md b/README.md
index 0030466..6e0e002 100644
--- a/README.md
+++ b/README.md
@@ -37,3 +37,13 @@ seccomp_tracing no
* Have `tests.py` load and drop database.
+Add functions:
+
+get_request_type
+render_json_error
+render_html_error
+
+insert_post
+
+only do HTTP stuff at the edge.
+
diff --git a/conf/clog.conf b/conf/clog.conf
index 0cf3d26..9653e94 100644
--- a/conf/clog.conf
+++ b/conf/clog.conf
@@ -24,24 +24,19 @@ domain * {
route / {
handler posts
+ methods get
}
route /posts {
handler posts
- # TODO Handle HTTP POST request.
methods get post
}
route ^/posts/[a-z0-9\-]+$ {
- handler post
+ handler GET_post
methods get
}
- route /toys {
- handler toys
- methods get post
- }
-
route ^/.*$ {
handler redirect
}
diff --git a/src/clog.c b/src/clog.c
index cb9e291..ba49ffc 100644
--- a/src/clog.c
+++ b/src/clog.c
@@ -39,6 +39,7 @@ static const char *accept_json = "application/json";
static const char *database = "db";
static const char * const error_msg[] = {
+ [HTTP_STATUS_BAD_REQUEST] = "There was an error processing the request data.",
[HTTP_STATUS_NOT_FOUND] = "Resource not found.",
[HTTP_STATUS_INTERNAL_ERROR] = "There was an error processing the request.",
};
@@ -50,15 +51,12 @@ int validate_uuid(const char *input);
int redirect(struct http_request *req);
-int post(struct http_request *req);
+int GET_post(struct http_request *req);
+int POST_post(struct http_request *req);
int posts(struct http_request *req);
int render_posts(struct http_request *req, const char *resource);
-int render_posts_query(struct post_request *post_req);
-
-int toys(struct http_request *req);
-int get_toys(struct http_request *req);
-int post_toys(struct http_request *req);
+int query_posts(struct post_request *post_req);
static void process_md_output(const MD_CHAR *, MD_SIZE size, void *);
static int render_md(const char *, struct kore_buf *);
@@ -115,18 +113,25 @@ redirect(struct http_request *req) {
}
int
-post(struct http_request *req) {
+GET_post(struct http_request *req) {
const char *resource = NULL;
resource = req->path + strlen("/posts/");
kore_log(LOG_DEBUG, "Resource /posts/%s", resource);
- return render_posts(req, resource);
+ (void) render_posts(req, resource);
+
+ return KORE_RESULT_OK;
}
int
posts(struct http_request *req) {
- return render_posts(req, NULL);
+ if (req->method == HTTP_METHOD_GET)
+ (void) render_posts(req, NULL);
+ else if (req->method == HTTP_METHOD_POST)
+ (void) POST_post(req);
+
+ return KORE_RESULT_OK;
}
int
@@ -154,8 +159,9 @@ render_posts(struct http_request *req, const char *resource) {
if (post_req.type == JSON) {
http_response_header(post_req.req, "content-type", "application/json; charset=utf-8");
- (void) render_posts_query(&post_req);
- if (post_req.resp_status != HTTP_STATUS_OK) {
+ (void) query_posts(&post_req);
+ // TOOD: Create a status_ok function
+ if (post_req.resp_status != HTTP_STATUS_OK && post_req.resp_status != HTTP_STATUS_CREATED) {
kore_buf_appendf(
post_req.resp_buf,
(const char *) asset_error_json,
@@ -168,8 +174,8 @@ render_posts(struct http_request *req, const char *resource) {
kore_buf_append(post_req.resp_buf, asset_index_begin_html, asset_len_index_begin_html);
- (void) render_posts_query(&post_req);
- if (post_req.resp_status != HTTP_STATUS_OK) {
+ (void) query_posts(&post_req);
+ if (post_req.resp_status != HTTP_STATUS_OK && post_req.resp_status != HTTP_STATUS_CREATED) {
kore_buf_appendf(
post_req.resp_buf,
(const char *) asset_error_html,
@@ -194,7 +200,7 @@ render_posts(struct http_request *req, const char *resource) {
int
-render_posts_query(struct post_request *post_req) {
+query_posts(struct post_request *post_req) {
int err = 0;
int row = 0, rows = 0;
@@ -317,28 +323,10 @@ out: ;
}
int
-toys(struct http_request *req) {
- if (req->method == HTTP_METHOD_GET)
- get_toys(req);
- else if (req->method == HTTP_METHOD_POST)
- post_toys(req);
-
- return KORE_RESULT_OK;
-}
-
-int
-get_toys(struct http_request *req) {
-
- http_response(req, HTTP_STATUS_OK, "OK", strlen("OK"));
-
- return KORE_RESULT_OK;
-}
-
-int
-post_toys(struct http_request *req) {
+POST_post(struct http_request *req) {
int err = 0;
- int status = HTTP_STATUS_OK;
+ int status = HTTP_STATUS_CREATED;
struct kore_json_item *item = NULL;
@@ -349,10 +337,6 @@ post_toys(struct http_request *req) {
struct kore_json json;
struct kore_pgsql sql;
- // const char *json_str = "{\"id\": \"00000000-0000-0000-0000-000000000000\", "
- // "\"title\": \"title\", \"body\": \"body\"}";
-
- // kore_json_init(&json, json_str, strlen(json_str));
kore_json_init(&json, req->http_body->data, req->http_body->length);
kore_pgsql_init(&sql);
@@ -376,7 +360,7 @@ post_toys(struct http_request *req) {
// Check for valid resource ID/UUID
err = validate_uuid(id);
if (err == KORE_RESULT_ERROR) {
- status = HTTP_STATUS_NOT_FOUND;
+ status = HTTP_STATUS_BAD_REQUEST;
kore_log(LOG_ERR, "Invalid post UUID %s.", id);
goto out;
}
@@ -413,7 +397,7 @@ post_toys(struct http_request *req) {
err = kore_pgsql_query_params(
&sql,
"INSERT INTO posts (id, title, body) "
- "VALUES ($1, $2, $3);",
+ "VALUES ($1, $2, $3) RETURNING id;",
0,
3,
KORE_PGSQL_PARAM_TEXT(id),
@@ -429,11 +413,53 @@ post_toys(struct http_request *req) {
out: ;
+ if (status == HTTP_STATUS_CREATED)
+ render_posts(req, id);
+ else { // ERRORs
+ int type = HTML;
+ struct kore_buf *resp_buf = kore_buf_alloc(0);
+ const char *accept = NULL;
+
+ err = http_request_header(req, "accept", &accept);
+ if (err == KORE_RESULT_OK) {
+ kore_log(LOG_DEBUG, "Accept: %s", accept);
+ if (strncmp(accept, accept_json, sizeof(*accept_json)) == 0)
+ type = JSON;
+ else
+ type = HTML;
+ }
+
+ if (type == JSON) {
+ http_response_header(req, "content-type", "application/json; charset=utf-8");
+ kore_buf_appendf(
+ resp_buf,
+ (const char *) asset_error_json,
+ error_msg[status]
+ );
+ } else {
+ http_response_header(req, "content-type", "text/html; charset=utf-8");
+ kore_buf_append(resp_buf, asset_index_begin_html, asset_len_index_begin_html);
+ kore_buf_appendf(
+ resp_buf,
+ (const char *) asset_error_html,
+ error_msg[status]
+ );
+ kore_buf_append(resp_buf, asset_index_end_html, asset_len_index_end_html);
+ }
+
+ http_response(
+ req,
+ status,
+ resp_buf->data,
+ resp_buf->offset
+ );
+
+ kore_buf_free(resp_buf);
+ }
+
kore_json_cleanup(&json);
kore_pgsql_cleanup(&sql);
- http_response(req, status, NULL, 0);
-
return KORE_RESULT_OK;
}
diff --git a/tests.py b/tests.py
index 533d2c2..33c9f6d 100755
--- a/tests.py
+++ b/tests.py
@@ -2,6 +2,7 @@
import json
import sys
+import uuid
import requests
@@ -94,6 +95,30 @@ def test_json_get_posts():
assert "Debugging CGI / CGit" in text
+def test_json_post_posts():
+ url = f"{BASE_URL}/posts"
+ uuid_ = str(uuid.uuid4())
+ data = {"id": uuid_, "title": "title", "body": "body"}
+ r = requests.post(url, headers={"Accept": "application/json"}, json=data)
+ # FIXME need to refactor to fix status code here.
+ # assert r.status_code == 201
+ assert r.status_code == 200
+ j = r.json()
+
+ assert len(j) == 1
+ assert "title" == j[0]["title"]
+ assert "body" == j[0]["body"]
+
+ url = f"{BASE_URL}/posts/{uuid_}"
+ r = requests.get(url, headers={"Accept": "application/json"})
+ assert r.status_code == 200
+ j = r.json()
+
+ assert len(j) == 1
+ assert "title" == j[0]["title"]
+ assert "body" == j[0]["body"]
+
+
def test_json_get_post_not_found():
url = f"{BASE_URL}/posts/{BAD_UUID}"
r = requests.get(url, headers={"Accept": "application/json"})