diff --git a/activitypub.c b/activitypub.c index b654beb..d470e10 100644 --- a/activitypub.c +++ b/activitypub.c @@ -154,3 +154,38 @@ void process_queue(snac *snac) } } } + + +int activitypub_post_handler(d_char *req, char *q_path, + d_char *payload, int p_size, + char **body, int *b_size, char **ctype) +/* processes an input message */ +{ + int status = 200; + char *i_ctype = xs_dict_get(req, "content-type"); + snac snac; + + if (xs_str_in(i_ctype, "application/activity+json") == -1 && + xs_str_in(i_ctype, "application/ld+json") == -1) + return 0; + + xs *l = xs_split_n(q_path, "/", 2); + char *uid; + + if (xs_list_len(l) != 3 || strcmp(xs_list_get(l, 2), "inbox") != 0) { + /* strange q_path */ + srv_log(xs_fmt("activitypub_post_handler unsupported path %s", q_path)); + return 404; + } + + uid = xs_list_get(l, 1); + if (!user_open(&snac, uid)) { + /* invalid user */ + srv_log(xs_fmt("activitypub_post_handler bad user %s", uid)); + return 404; + } + + user_free(&snac); + + return status; +} diff --git a/httpd.c b/httpd.c index 1ef766c..037f690 100644 --- a/httpd.c +++ b/httpd.c @@ -98,11 +98,13 @@ void httpd_connection(int rs) char *ctype = NULL; xs *headers = NULL; xs *q_path = NULL; + xs *payload = NULL; + int p_size; char *p; f = xs_socket_accept(rs); - req = xs_httpd_request(f); + req = xs_httpd_request(f, &payload, &p_size); { xs *j = xs_json_dumps_pp(req, 4); @@ -132,6 +134,9 @@ void httpd_connection(int rs) } else if (strcmp(method, "POST") == 0) { + if (status == 0) + status = activitypub_post_handler(req, q_path, + payload, p_size, &body, &b_size, &ctype); } /* let's go */ diff --git a/snac.h b/snac.h index 166806b..f876363 100644 --- a/snac.h +++ b/snac.h @@ -85,3 +85,6 @@ int actor_request(snac *snac, char *actor, d_char **data); int send_to_inbox(snac *snac, char *inbox, char *msg, d_char **payload, int *p_size); int send_to_actor(snac *snac, char *actor, char *msg, d_char **payload, int *p_size); void process_queue(snac *snac); +int activitypub_post_handler(d_char *req, char *q_path, + char *payload, int p_size, + char **body, int *b_size, char **ctype); diff --git a/xs_httpd.h b/xs_httpd.h index d15a473..d56226f 100644 --- a/xs_httpd.h +++ b/xs_httpd.h @@ -6,7 +6,7 @@ d_char *xs_url_dec(char *str); d_char *xs_url_vars(char *str); -d_char *xs_httpd_request(FILE *f); +d_char *xs_httpd_request(FILE *f, d_char **payload, int *p_size); void xs_httpd_response(FILE *f, int status, d_char *headers, char *body, int b_size); @@ -69,7 +69,7 @@ d_char *xs_url_vars(char *str) } -d_char *xs_httpd_request(FILE *f) +d_char *xs_httpd_request(FILE *f, d_char **payload, int *p_size) /* processes an httpd connection */ { xs *headers = NULL; @@ -127,19 +127,18 @@ d_char *xs_httpd_request(FILE *f) xs_socket_timeout(fileno(f), 5.0, 0.0); + if ((v = xs_dict_get(headers, "content-length")) != NULL) { + /* if it has a payload, load it */ + *p_size = atoi(v); + *payload = xs_read(f, *p_size); + } + /* does it have a payload with form urlencoded variables? */ v = xs_dict_get(headers, "content-type"); if (v && strcmp(v, "application/x-www-form-urlencoded") == 0) { - if ((v = xs_dict_get(headers, "content-length")) != NULL) { - int cl = atoi(v); - xs *payload; - - if ((payload = xs_read(f, cl)) != NULL) { - xs *upl = xs_url_dec(payload); - p_vars = xs_url_vars(upl); - } - } + xs *upl = xs_url_dec(*payload); + p_vars = xs_url_vars(upl); } else p_vars = xs_dict_new();