Use enum instead of numeric status codes for HTTP statuses

This commit is contained in:
Louis Brauer 2024-05-26 21:45:41 +02:00
parent 9749a65007
commit 0e21d35e80
7 changed files with 262 additions and 206 deletions

View file

@ -96,19 +96,19 @@ int activitypub_request(snac *user, const char *url, xs_dict **data)
ctype = xs_dict_get(response, "content-type"); ctype = xs_dict_get(response, "content-type");
if (xs_is_null(ctype)) if (xs_is_null(ctype))
status = 400; status = HTTP_STATUS_BAD_REQUEST;
else else
if (xs_str_in(ctype, "application/activity+json") != -1 || if (xs_str_in(ctype, "application/activity+json") != -1 ||
xs_str_in(ctype, "application/ld+json") != -1) { xs_str_in(ctype, "application/ld+json") != -1) {
/* if there is no payload, fail */ /* if there is no payload, fail */
if (xs_is_null(payload)) if (xs_is_null(payload))
status = 400; status = HTTP_STATUS_BAD_REQUEST;
else else
*data = xs_json_loads(payload); *data = xs_json_loads(payload);
} }
else else
status = 500; status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
} }
return status; return status;
@ -443,7 +443,7 @@ int send_to_actor(snac *snac, const char *actor, const xs_dict *msg,
xs_val **payload, int *p_size, int timeout) xs_val **payload, int *p_size, int timeout)
/* sends a message to an actor */ /* sends a message to an actor */
{ {
int status = 400; int status = HTTP_STATUS_BAD_REQUEST;
xs *inbox = get_actor_inbox(actor); xs *inbox = get_actor_inbox(actor);
if (!xs_is_null(inbox)) if (!xs_is_null(inbox))
@ -1762,7 +1762,9 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
a_status = actor_request(snac, actor, &actor_o); a_status = actor_request(snac, actor, &actor_o);
/* do not retry permanent failures */ /* do not retry permanent failures */
if (a_status == 404 || a_status == 410 || a_status < 0) { if (a_status == HTTP_STATUS_NOT_FOUND
|| a_status == HTTP_STATUS_GONE
|| a_status < 0) {
srv_debug(1, xs_fmt("dropping message due to actor error %s %d", actor, a_status)); srv_debug(1, xs_fmt("dropping message due to actor error %s %d", actor, a_status));
return -1; return -1;
} }
@ -1905,7 +1907,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
} }
else else
if (strcmp(utype, "Announce") == 0) { /** **/ if (strcmp(utype, "Announce") == 0) { /** **/
int status = 200; int status = HTTP_STATUS_OK;
/* commented out: if a followed user boosts something that /* commented out: if a followed user boosts something that
is requested and then unboosts, the post remains here, is requested and then unboosts, the post remains here,
@ -2015,7 +2017,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
if (xs_type(object) == XSTYPE_DICT) if (xs_type(object) == XSTYPE_DICT)
object = xs_dict_get(object, "id"); object = xs_dict_get(object, "id");
if (timeline_admire(snac, object, actor, 1) == 201) if (timeline_admire(snac, object, actor, 1) == HTTP_STATUS_CREATED)
snac_log(snac, xs_fmt("new 'Like' %s %s", actor, object)); snac_log(snac, xs_fmt("new 'Like' %s %s", actor, object));
else else
snac_log(snac, xs_fmt("repeated 'Like' from %s to %s", actor, object)); snac_log(snac, xs_fmt("repeated 'Like' from %s to %s", actor, object));
@ -2046,7 +2048,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
xs *who_o = NULL; xs *who_o = NULL;
if (valid_status(actor_request(snac, who, &who_o))) { if (valid_status(actor_request(snac, who, &who_o))) {
if (timeline_admire(snac, object, actor, 0) == 201) if (timeline_admire(snac, object, actor, 0) == HTTP_STATUS_CREATED)
snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object)); snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object));
else else
snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s", snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s",
@ -2383,11 +2385,15 @@ void process_queue_item(xs_dict *q_item)
/* if it's not the first time it fails with a timeout, /* if it's not the first time it fails with a timeout,
penalize the server by skipping one retry */ penalize the server by skipping one retry */
if (p_status == status && status == 499) if (p_status == status && status == HTTP_STATUS_CLIENT_CLOSED_REQUEST)
retries++; retries++;
/* error sending; requeue? */ /* error sending; requeue? */
if (status == 400 || status == 404 || status == 405 || status == 410 || status < 0) if (status == HTTP_STATUS_BAD_REQUEST
|| status == HTTP_STATUS_NOT_FOUND
|| status == HTTP_STATUS_METHOD_NOT_ALLOWED
|| status == HTTP_STATUS_GONE
|| status < 0)
/* explicit error: discard */ /* explicit error: discard */
srv_log(xs_fmt("output message: fatal error %s %d", inbox, status)); srv_log(xs_fmt("output message: fatal error %s %d", inbox, status));
else else
@ -2574,7 +2580,7 @@ int process_queue(void)
int activitypub_get_handler(const xs_dict *req, const char *q_path, int activitypub_get_handler(const xs_dict *req, const char *q_path,
char **body, int *b_size, char **ctype) char **body, int *b_size, char **ctype)
{ {
int status = 200; int status = HTTP_STATUS_OK;
const char *accept = xs_dict_get(req, "accept"); const char *accept = xs_dict_get(req, "accept");
snac snac; snac snac;
xs *msg = NULL; xs *msg = NULL;
@ -2594,7 +2600,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
if (!user_open(&snac, uid)) { if (!user_open(&snac, uid)) {
/* invalid user */ /* invalid user */
srv_debug(1, xs_fmt("activitypub_get_handler bad user %s", uid)); srv_debug(1, xs_fmt("activitypub_get_handler bad user %s", uid));
return 404; return HTTP_STATUS_NOT_FOUND;
} }
p_path = xs_list_get(l, 2); p_path = xs_list_get(l, 2);
@ -2652,12 +2658,12 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
/* don't return non-public objects */ /* don't return non-public objects */
if (valid_status(status) && !is_msg_public(msg)) if (valid_status(status) && !is_msg_public(msg))
status = 404; status = HTTP_STATUS_NOT_FOUND;
} }
else else
status = 404; status = HTTP_STATUS_NOT_FOUND;
if (status == 200 && msg != NULL) { if (status == HTTP_STATUS_OK && msg != NULL) {
*body = xs_json_dumps(msg, 4); *body = xs_json_dumps(msg, 4);
*b_size = strlen(*body); *b_size = strlen(*body);
} }
@ -2677,7 +2683,7 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path,
{ {
(void)b_size; (void)b_size;
int status = 202; /* accepted */ int status = HTTP_STATUS_ACCEPTED;
const char *i_ctype = xs_dict_get(req, "content-type"); const char *i_ctype = xs_dict_get(req, "content-type");
snac snac; snac snac;
const char *v; const char *v;
@ -2685,13 +2691,13 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path,
if (i_ctype == NULL) { if (i_ctype == NULL) {
*body = xs_str_new("no content-type"); *body = xs_str_new("no content-type");
*ctype = "text/plain"; *ctype = "text/plain";
return 400; return HTTP_STATUS_BAD_REQUEST;
} }
if (xs_is_null(payload)) { if (xs_is_null(payload)) {
*body = xs_str_new("no payload"); *body = xs_str_new("no payload");
*ctype = "text/plain"; *ctype = "text/plain";
return 400; return HTTP_STATUS_BAD_REQUEST;
} }
if (xs_str_in(i_ctype, "application/activity+json") == -1 && if (xs_str_in(i_ctype, "application/activity+json") == -1 &&
@ -2709,7 +2715,7 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path,
*body = xs_str_new("JSON error"); *body = xs_str_new("JSON error");
*ctype = "text/plain"; *ctype = "text/plain";
return 400; return HTTP_STATUS_BAD_REQUEST;
} }
if (id && is_instance_blocked(id)) { if (id && is_instance_blocked(id)) {
@ -2717,7 +2723,7 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path,
*body = xs_str_new("blocked"); *body = xs_str_new("blocked");
*ctype = "text/plain"; *ctype = "text/plain";
return 403; return HTTP_STATUS_FORBIDDEN;
} }
/* get the user and path */ /* get the user and path */
@ -2725,20 +2731,20 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path,
if (xs_list_len(l) == 2 && strcmp(xs_list_get(l, 1), "shared-inbox") == 0) { if (xs_list_len(l) == 2 && strcmp(xs_list_get(l, 1), "shared-inbox") == 0) {
enqueue_shared_input(msg, req, 0); enqueue_shared_input(msg, req, 0);
return 202; return HTTP_STATUS_ACCEPTED;
} }
if (xs_list_len(l) != 3 || strcmp(xs_list_get(l, 2), "inbox") != 0) { if (xs_list_len(l) != 3 || strcmp(xs_list_get(l, 2), "inbox") != 0) {
/* strange q_path */ /* strange q_path */
srv_debug(1, xs_fmt("activitypub_post_handler unsupported path %s", q_path)); srv_debug(1, xs_fmt("activitypub_post_handler unsupported path %s", q_path));
return 404; return HTTP_STATUS_NOT_FOUND;
} }
const char *uid = xs_list_get(l, 1); const char *uid = xs_list_get(l, 1);
if (!user_open(&snac, uid)) { if (!user_open(&snac, uid)) {
/* invalid user */ /* invalid user */
srv_debug(1, xs_fmt("activitypub_post_handler bad user %s", uid)); srv_debug(1, xs_fmt("activitypub_post_handler bad user %s", uid));
return 404; return HTTP_STATUS_NOT_FOUND;
} }
/* if it has a digest, check it now, because /* if it has a digest, check it now, because
@ -2752,7 +2758,7 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path,
*body = xs_str_new("bad digest"); *body = xs_str_new("bad digest");
*ctype = "text/plain"; *ctype = "text/plain";
status = 400; status = HTTP_STATUS_BAD_REQUEST;
} }
} }
@ -2763,7 +2769,7 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path,
*body = xs_str_new("rejected"); *body = xs_str_new("rejected");
*ctype = "text/plain"; *ctype = "text/plain";
status = 403; status = HTTP_STATUS_FORBIDDEN;
} }
} }

68
data.c
View file

@ -355,12 +355,12 @@ int is_md5_hex(const char *md5)
int index_add_md5(const char *fn, const char *md5) int index_add_md5(const char *fn, const char *md5)
/* adds an md5 to an index */ /* adds an md5 to an index */
{ {
int status = 201; /* Created */ int status = HTTP_STATUS_CREATED;
FILE *f; FILE *f;
if (!is_md5_hex(md5)) { if (!is_md5_hex(md5)) {
srv_log(xs_fmt("index_add_md5: bad md5 %s %s", fn, md5)); srv_log(xs_fmt("index_add_md5: bad md5 %s %s", fn, md5));
return 400; return HTTP_STATUS_BAD_REQUEST;
} }
pthread_mutex_lock(&data_mutex); pthread_mutex_lock(&data_mutex);
@ -375,7 +375,7 @@ int index_add_md5(const char *fn, const char *md5)
fclose(f); fclose(f);
} }
else else
status = 500; status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
pthread_mutex_unlock(&data_mutex); pthread_mutex_unlock(&data_mutex);
@ -394,7 +394,7 @@ int index_add(const char *fn, const char *id)
int index_del_md5(const char *fn, const char *md5) int index_del_md5(const char *fn, const char *md5)
/* deletes an md5 from an index */ /* deletes an md5 from an index */
{ {
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
FILE *f; FILE *f;
pthread_mutex_lock(&data_mutex); pthread_mutex_lock(&data_mutex);
@ -411,7 +411,7 @@ int index_del_md5(const char *fn, const char *md5)
[yes: this breaks index_len()] */ [yes: this breaks index_len()] */
fseek(f, -33, SEEK_CUR); fseek(f, -33, SEEK_CUR);
fwrite("-", 1, 1, f); fwrite("-", 1, 1, f);
status = 200; status = HTTP_STATUS_OK;
break; break;
} }
@ -420,7 +420,7 @@ int index_del_md5(const char *fn, const char *md5)
fclose(f); fclose(f);
} }
else else
status = 410; status = HTTP_STATUS_GONE;
pthread_mutex_unlock(&data_mutex); pthread_mutex_unlock(&data_mutex);
@ -660,7 +660,7 @@ int object_here(const char *id)
int object_get_by_md5(const char *md5, xs_dict **obj) int object_get_by_md5(const char *md5, xs_dict **obj)
/* returns a stored object, optionally of the requested type */ /* returns a stored object, optionally of the requested type */
{ {
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
xs *fn = _object_fn_by_md5(md5, "object_get_by_md5"); xs *fn = _object_fn_by_md5(md5, "object_get_by_md5");
FILE *f; FILE *f;
@ -669,7 +669,7 @@ int object_get_by_md5(const char *md5, xs_dict **obj)
fclose(f); fclose(f);
if (*obj) if (*obj)
status = 200; status = HTTP_STATUS_OK;
} }
else else
*obj = NULL; *obj = NULL;
@ -689,7 +689,7 @@ int object_get(const char *id, xs_dict **obj)
int _object_add(const char *id, const xs_dict *obj, int ow) int _object_add(const char *id, const xs_dict *obj, int ow)
/* stores an object */ /* stores an object */
{ {
int status = 201; /* Created */ int status = HTTP_STATUS_CREATED; /* Created */
xs *fn = _object_fn(id); xs *fn = _object_fn(id);
FILE *f; FILE *f;
@ -697,10 +697,10 @@ int _object_add(const char *id, const xs_dict *obj, int ow)
if (!ow) { if (!ow) {
/* object already here */ /* object already here */
srv_debug(1, xs_fmt("object_add object already here %s", id)); srv_debug(1, xs_fmt("object_add object already here %s", id));
return 204; /* No content */ return HTTP_STATUS_NO_CONTENT;
} }
else else
status = 200; status = HTTP_STATUS_OK;
} }
if ((f = fopen(fn, "w")) != NULL) { if ((f = fopen(fn, "w")) != NULL) {
@ -736,7 +736,7 @@ int _object_add(const char *id, const xs_dict *obj, int ow)
} }
else { else {
srv_log(xs_fmt("object_add error writing %s (errno: %d)", fn, errno)); srv_log(xs_fmt("object_add error writing %s (errno: %d)", fn, errno));
status = 500; status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
} }
srv_debug(1, xs_fmt("object_add %s %s %d", id, fn, status)); srv_debug(1, xs_fmt("object_add %s %s %d", id, fn, status));
@ -762,11 +762,11 @@ int object_add_ow(const char *id, const xs_dict *obj)
int object_del_by_md5(const char *md5) int object_del_by_md5(const char *md5)
/* deletes an object by its md5 */ /* deletes an object by its md5 */
{ {
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
xs *fn = _object_fn_by_md5(md5, "object_del_by_md5"); xs *fn = _object_fn_by_md5(md5, "object_del_by_md5");
if (unlink(fn) != -1) { if (unlink(fn) != -1) {
status = 200; status = HTTP_STATUS_OK;
/* also delete associated indexes */ /* also delete associated indexes */
xs *spec = xs_dup(fn); xs *spec = xs_dup(fn);
@ -907,7 +907,7 @@ int object_parent(const char *md5, char *buf, int size)
int object_admire(const char *id, const char *actor, int like) int object_admire(const char *id, const char *actor, int like)
/* actor likes or announces this object */ /* actor likes or announces this object */
{ {
int status = 200; int status = HTTP_STATUS_OK;
xs *fn = _object_fn(id); xs *fn = _object_fn(id);
fn = xs_replace_i(fn, ".json", like ? "_l.idx" : "_a.idx"); fn = xs_replace_i(fn, ".json", like ? "_l.idx" : "_a.idx");
@ -1007,7 +1007,7 @@ int follower_add(snac *snac, const char *actor)
snac_debug(snac, 2, xs_fmt("follower_add %s", actor)); snac_debug(snac, 2, xs_fmt("follower_add %s", actor));
return ret == -1 ? 500 : 200; return ret == -1 ? HTTP_STATUS_INTERNAL_SERVER_ERROR : HTTP_STATUS_OK;
} }
@ -1018,7 +1018,7 @@ int follower_del(snac *snac, const char *actor)
snac_debug(snac, 2, xs_fmt("follower_del %s", actor)); snac_debug(snac, 2, xs_fmt("follower_del %s", actor));
return ret == -1 ? 404 : 200; return ret == -1 ? HTTP_STATUS_NOT_FOUND : HTTP_STATUS_OK;
} }
@ -1109,7 +1109,7 @@ int timeline_here(snac *snac, const char *md5)
int timeline_get_by_md5(snac *snac, const char *md5, xs_dict **msg) int timeline_get_by_md5(snac *snac, const char *md5, xs_dict **msg)
/* gets a message from the timeline */ /* gets a message from the timeline */
{ {
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
FILE *f = NULL; FILE *f = NULL;
xs *fn = timeline_fn_by_md5(snac, md5); xs *fn = timeline_fn_by_md5(snac, md5);
@ -1119,7 +1119,7 @@ int timeline_get_by_md5(snac *snac, const char *md5, xs_dict **msg)
fclose(f); fclose(f);
if (*msg != NULL) if (*msg != NULL)
status = 200; status = HTTP_STATUS_OK;
} }
return status; return status;
@ -1282,7 +1282,7 @@ xs_str *_following_fn(snac *snac, const char *actor)
int following_add(snac *snac, const char *actor, const xs_dict *msg) int following_add(snac *snac, const char *actor, const xs_dict *msg)
/* adds to the following list */ /* adds to the following list */
{ {
int ret = 201; /* created */ int ret = HTTP_STATUS_CREATED;
xs *fn = _following_fn(snac, actor); xs *fn = _following_fn(snac, actor);
FILE *f; FILE *f;
xs *p_object = NULL; xs *p_object = NULL;
@ -1295,7 +1295,7 @@ int following_add(snac *snac, const char *actor, const xs_dict *msg)
if (!xs_is_null(type) && strcmp(type, "Accept") == 0) { if (!xs_is_null(type) && strcmp(type, "Accept") == 0) {
snac_debug(snac, 1, xs_fmt("following_add actor already confirmed %s", actor)); snac_debug(snac, 1, xs_fmt("following_add actor already confirmed %s", actor));
return 200; return HTTP_STATUS_OK;
} }
} }
@ -1311,7 +1311,7 @@ int following_add(snac *snac, const char *actor, const xs_dict *msg)
link(actor_fn, fn); link(actor_fn, fn);
} }
else else
ret = 500; ret = HTTP_STATUS_INTERNAL_SERVER_ERROR;
snac_debug(snac, 2, xs_fmt("following_add %s %s", actor, fn)); snac_debug(snac, 2, xs_fmt("following_add %s %s", actor, fn));
@ -1332,7 +1332,7 @@ int following_del(snac *snac, const char *actor)
fn = xs_replace_i(fn, ".json", "_a.json"); fn = xs_replace_i(fn, ".json", "_a.json");
unlink(fn); unlink(fn);
return 200; return HTTP_STATUS_OK;
} }
@ -1350,14 +1350,14 @@ int following_get(snac *snac, const char *actor, xs_dict **data)
{ {
xs *fn = _following_fn(snac, actor); xs *fn = _following_fn(snac, actor);
FILE *f; FILE *f;
int status = 200; int status = HTTP_STATUS_OK;
if ((f = fopen(fn, "r")) != NULL) { if ((f = fopen(fn, "r")) != NULL) {
*data = xs_json_load(f); *data = xs_json_load(f);
fclose(f); fclose(f);
} }
else else
status = 404; status = HTTP_STATUS_NOT_FOUND;
return status; return status;
} }
@ -1576,7 +1576,7 @@ int actor_add(const char *actor, const xs_dict *msg)
int actor_get(const char *actor, xs_dict **data) int actor_get(const char *actor, xs_dict **data)
/* returns an already downloaded actor */ /* returns an already downloaded actor */
{ {
int status = 200; int status = HTTP_STATUS_OK;
xs_dict *d = NULL; xs_dict *d = NULL;
if (xs_startswith(actor, srv_baseurl)) { if (xs_startswith(actor, srv_baseurl)) {
@ -1590,10 +1590,10 @@ int actor_get(const char *actor, xs_dict **data)
*data = msg_actor(&user); *data = msg_actor(&user);
user_free(&user); user_free(&user);
return 200; return HTTP_STATUS_OK;
} }
else else
return 404; return HTTP_STATUS_NOT_FOUND;
} }
/* read the object */ /* read the object */
@ -1606,7 +1606,7 @@ int actor_get(const char *actor, xs_dict **data)
if (xs_is_null(xs_dict_get(d, "id")) || xs_is_null(xs_dict_get(d, "type"))) { if (xs_is_null(xs_dict_get(d, "id")) || xs_is_null(xs_dict_get(d, "type"))) {
srv_debug(1, xs_fmt("corrupted actor object %s", actor)); srv_debug(1, xs_fmt("corrupted actor object %s", actor));
d = xs_free(d); d = xs_free(d);
return 404; return HTTP_STATUS_NOT_FOUND;
} }
if (data) if (data)
@ -1622,7 +1622,7 @@ int actor_get(const char *actor, xs_dict **data)
if (mtime(fn) + max_time < (double) time(NULL)) { if (mtime(fn) + max_time < (double) time(NULL)) {
/* actor data exists but also stinks */ /* actor data exists but also stinks */
status = 205; /* "205: Reset Content" "110: Response Is Stale" */ status = HTTP_STATUS_RESET_CONTENT; /* "110: Response Is Stale" */
} }
return status; return status;
@ -1634,7 +1634,7 @@ int actor_get_refresh(snac *user, const char *actor, xs_dict **data)
{ {
int status = actor_get(actor, data); int status = actor_get(actor, data);
if (status == 205 && user && !xs_startswith(actor, srv_baseurl)) if (status == HTTP_STATUS_RESET_CONTENT && user && !xs_startswith(actor, srv_baseurl))
enqueue_actor_refresh(user, actor, 0); enqueue_actor_refresh(user, actor, 0);
return status; return status;
@ -1953,7 +1953,7 @@ static int _load_raw_file(const char *fn, xs_val **data, int *size,
const char *inm, xs_str **etag) const char *inm, xs_str **etag)
/* loads a cached file */ /* loads a cached file */
{ {
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
if (fn) { if (fn) {
double tm = mtime(fn); double tm = mtime(fn);
@ -1965,7 +1965,7 @@ static int _load_raw_file(const char *fn, xs_val **data, int *size,
/* if if-none-match is set, check if it's the same */ /* if if-none-match is set, check if it's the same */
if (!xs_is_null(inm) && strcmp(e, inm) == 0) { if (!xs_is_null(inm) && strcmp(e, inm) == 0) {
/* client has the newest version */ /* client has the newest version */
status = 304; status = HTTP_STATUS_NOT_MODIFIED;
} }
else { else {
/* newer or never downloaded; read the full file */ /* newer or never downloaded; read the full file */
@ -1976,7 +1976,7 @@ static int _load_raw_file(const char *fn, xs_val **data, int *size,
*data = xs_read(f, size); *data = xs_read(f, size);
fclose(f); fclose(f);
status = 200; status = HTTP_STATUS_OK;
} }
} }

76
html.c
View file

@ -2540,7 +2540,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
char **body, int *b_size, char **ctype, xs_str **etag) char **body, int *b_size, char **ctype, xs_str **etag)
{ {
const char *accept = xs_dict_get(req, "accept"); const char *accept = xs_dict_get(req, "accept");
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
snac snac; snac snac;
xs *uid = NULL; xs *uid = NULL;
const char *p_path; const char *p_path;
@ -2553,7 +2553,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
if (xs_is_null(v)) { if (xs_is_null(v)) {
srv_log(xs_fmt("html_get_handler bad query '%s'", q_path)); srv_log(xs_fmt("html_get_handler bad query '%s'", q_path));
return 404; return HTTP_STATUS_NOT_FOUND;
} }
uid = xs_dup(v); uid = xs_dup(v);
@ -2569,7 +2569,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
if (!uid || !user_open(&snac, uid)) { if (!uid || !user_open(&snac, uid)) {
/* invalid user */ /* invalid user */
srv_debug(1, xs_fmt("html_get_handler bad user %s", uid)); srv_debug(1, xs_fmt("html_get_handler bad user %s", uid));
return 404; return HTTP_STATUS_NOT_FOUND;
} }
/* return the RSS if requested by Accept header */ /* return the RSS if requested by Accept header */
@ -2598,7 +2598,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
/** empty public timeline for private users **/ /** empty public timeline for private users **/
*body = html_timeline(&snac, NULL, 1, 0, 0, 0, NULL, "", 1); *body = html_timeline(&snac, NULL, 1, 0, 0, 0, NULL, "", 1);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (cache && history_mtime(&snac, h) > timeline_mtime(&snac)) { if (cache && history_mtime(&snac, h) > timeline_mtime(&snac)) {
@ -2617,7 +2617,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = html_timeline(&snac, pins, 1, skip, show, xs_list_len(next), NULL, "", 1); *body = html_timeline(&snac, pins, 1, skip, show, xs_list_len(next), NULL, "", 1);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
if (save) if (save)
history_add(&snac, h, *body, *b_size, etag); history_add(&snac, h, *body, *b_size, etag);
@ -2627,7 +2627,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
if (strcmp(p_path, "admin") == 0) { /** private timeline **/ if (strcmp(p_path, "admin") == 0) { /** private timeline **/
if (!login(&snac, req)) { if (!login(&snac, req)) {
*body = xs_dup(uid); *body = xs_dup(uid);
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else { else {
const char *q = xs_dict_get(q_vars, "q"); const char *q = xs_dict_get(q_vars, "q");
@ -2649,7 +2649,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = html_timeline(&snac, tl, 0, skip, show, more, title, page, 0); *body = html_timeline(&snac, tl, 0, skip, show, more, title, page, 0);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
else { else {
/** search by content **/ /** search by content **/
@ -2670,7 +2670,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show, title, page, 0); *body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show, title, page, 0);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
} }
else { else {
@ -2699,7 +2699,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
xs_list_len(next), NULL, "/admin", 1); xs_list_len(next), NULL, "/admin", 1);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
if (save) if (save)
history_add(&snac, "timeline.html_", *body, *b_size, etag); history_add(&snac, "timeline.html_", *body, *b_size, etag);
@ -2711,7 +2711,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
if (xs_startswith(p_path, "admin/p/")) { /** unique post by md5 **/ if (xs_startswith(p_path, "admin/p/")) { /** unique post by md5 **/
if (!login(&snac, req)) { if (!login(&snac, req)) {
*body = xs_dup(uid); *body = xs_dup(uid);
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else { else {
xs *l = xs_split(p_path, "/"); xs *l = xs_split(p_path, "/");
@ -2722,7 +2722,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = html_timeline(&snac, list, 0, 0, 0, 0, NULL, "/admin", 1); *body = html_timeline(&snac, list, 0, 0, 0, 0, NULL, "/admin", 1);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
@ -2730,31 +2730,31 @@ int html_get_handler(const xs_dict *req, const char *q_path,
if (strcmp(p_path, "people") == 0) { /** the list of people **/ if (strcmp(p_path, "people") == 0) { /** the list of people **/
if (!login(&snac, req)) { if (!login(&snac, req)) {
*body = xs_dup(uid); *body = xs_dup(uid);
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else { else {
*body = html_people(&snac); *body = html_people(&snac);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
if (strcmp(p_path, "notifications") == 0) { /** the list of notifications **/ if (strcmp(p_path, "notifications") == 0) { /** the list of notifications **/
if (!login(&snac, req)) { if (!login(&snac, req)) {
*body = xs_dup(uid); *body = xs_dup(uid);
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else { else {
*body = html_notifications(&snac, skip, show); *body = html_notifications(&snac, skip, show);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
if (strcmp(p_path, "instance") == 0) { /** instance timeline **/ if (strcmp(p_path, "instance") == 0) { /** instance timeline **/
if (!login(&snac, req)) { if (!login(&snac, req)) {
*body = xs_dup(uid); *body = xs_dup(uid);
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else { else {
xs *list = timeline_instance_list(skip, show); xs *list = timeline_instance_list(skip, show);
@ -2763,14 +2763,14 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = html_timeline(&snac, list, 0, skip, show, *body = html_timeline(&snac, list, 0, skip, show,
xs_list_len(next), L("Showing instance timeline"), "/instance", 0); xs_list_len(next), L("Showing instance timeline"), "/instance", 0);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
if (xs_startswith(p_path, "list/")) { /** list timelines **/ if (xs_startswith(p_path, "list/")) { /** list timelines **/
if (!login(&snac, req)) { if (!login(&snac, req)) {
*body = xs_dup(uid); *body = xs_dup(uid);
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else { else {
xs *l = xs_split(p_path, "/"); xs *l = xs_split(p_path, "/");
@ -2787,14 +2787,14 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = html_timeline(&snac, list, 0, skip, show, *body = html_timeline(&snac, list, 0, skip, show,
xs_list_len(next), title, base, 1); xs_list_len(next), title, base, 1);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
else else
if (xs_startswith(p_path, "p/")) { /** a timeline with just one entry **/ if (xs_startswith(p_path, "p/")) { /** a timeline with just one entry **/
if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE) if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE)
return 403; return HTTP_STATUS_FORBIDDEN;
xs *id = xs_fmt("%s/%s", snac.actor, p_path); xs *id = xs_fmt("%s/%s", snac.actor, p_path);
xs *msg = NULL; xs *msg = NULL;
@ -2807,7 +2807,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = html_timeline(&snac, list, 1, 0, 0, 0, NULL, "", 1); *body = html_timeline(&snac, list, 1, 0, 0, 0, NULL, "", 1);
*b_size = strlen(*body); *b_size = strlen(*body);
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
@ -2829,10 +2829,10 @@ int html_get_handler(const xs_dict *req, const char *q_path,
else else
if (xs_startswith(p_path, "h/")) { /** an entry from the history **/ if (xs_startswith(p_path, "h/")) { /** an entry from the history **/
if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE) if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE)
return 403; return HTTP_STATUS_FORBIDDEN;
if (xs_type(xs_dict_get(srv_config, "disable_history")) == XSTYPE_TRUE) if (xs_type(xs_dict_get(srv_config, "disable_history")) == XSTYPE_TRUE)
return 403; return HTTP_STATUS_FORBIDDEN;
xs *l = xs_split(p_path, "/"); xs *l = xs_split(p_path, "/");
const char *id = xs_list_get(l, 1); const char *id = xs_list_get(l, 1);
@ -2841,7 +2841,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
if (xs_endswith(id, "timeline.html_")) { if (xs_endswith(id, "timeline.html_")) {
/* Don't let them in */ /* Don't let them in */
*b_size = 0; *b_size = 0;
status = 404; status = HTTP_STATUS_NOT_FOUND;
} }
else else
status = history_get(&snac, id, body, b_size, status = history_get(&snac, id, body, b_size,
@ -2851,7 +2851,7 @@ int html_get_handler(const xs_dict *req, const char *q_path,
else else
if (strcmp(p_path, ".rss") == 0) { /** public timeline in RSS format **/ if (strcmp(p_path, ".rss") == 0) { /** public timeline in RSS format **/
if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE) if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE)
return 403; return HTTP_STATUS_FORBIDDEN;
xs *elems = timeline_simple_list(&snac, "public", 0, 20); xs *elems = timeline_simple_list(&snac, "public", 0, 20);
xs *bio = not_really_markdown(xs_dict_get(snac.config, "bio"), NULL, NULL); xs *bio = not_really_markdown(xs_dict_get(snac.config, "bio"), NULL, NULL);
@ -2865,12 +2865,12 @@ int html_get_handler(const xs_dict *req, const char *q_path,
*body = timeline_to_rss(&snac, elems, rss_title, rss_link, bio); *body = timeline_to_rss(&snac, elems, rss_title, rss_link, bio);
*b_size = strlen(*body); *b_size = strlen(*body);
*ctype = "application/rss+xml; charset=utf-8"; *ctype = "application/rss+xml; charset=utf-8";
status = 200; status = HTTP_STATUS_OK;
snac_debug(&snac, 1, xs_fmt("serving RSS")); snac_debug(&snac, 1, xs_fmt("serving RSS"));
} }
else else
status = 404; status = HTTP_STATUS_NOT_FOUND;
user_free(&snac); user_free(&snac);
@ -2901,7 +2901,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
if (!uid || !user_open(&snac, uid)) { if (!uid || !user_open(&snac, uid)) {
/* invalid user */ /* invalid user */
srv_debug(1, xs_fmt("html_post_handler bad user %s", uid)); srv_debug(1, xs_fmt("html_post_handler bad user %s", uid));
return 404; return HTTP_STATUS_NOT_FOUND;
} }
p_path = xs_list_get(l, 2); p_path = xs_list_get(l, 2);
@ -2910,7 +2910,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
if (!login(&snac, req)) { if (!login(&snac, req)) {
user_free(&snac); user_free(&snac);
*body = xs_dup(uid); *body = xs_dup(uid);
return 401; return HTTP_STATUS_UNAUTHORIZED;
} }
p_vars = xs_dict_get(req, "p_vars"); p_vars = xs_dict_get(req, "p_vars");
@ -3049,7 +3049,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
history_del(&snac, "timeline.html_"); history_del(&snac, "timeline.html_");
} }
status = 303; status = HTTP_STATUS_SEE_OTHER;
} }
else else
if (p_path && strcmp(p_path, "admin/action") == 0) { /** **/ if (p_path && strcmp(p_path, "admin/action") == 0) { /** **/
@ -3060,11 +3060,11 @@ int html_post_handler(const xs_dict *req, const char *q_path,
const char *group = xs_dict_get(p_vars, "group"); const char *group = xs_dict_get(p_vars, "group");
if (action == NULL) if (action == NULL)
return 404; return HTTP_STATUS_NOT_FOUND;
snac_debug(&snac, 1, xs_fmt("web action '%s' received", action)); snac_debug(&snac, 1, xs_fmt("web action '%s' received", action));
status = 303; status = HTTP_STATUS_SEE_OTHER;
if (strcmp(action, L("Like")) == 0) { /** **/ if (strcmp(action, L("Like")) == 0) { /** **/
xs *msg = msg_admiration(&snac, id, "Like"); xs *msg = msg_admiration(&snac, id, "Like");
@ -3216,10 +3216,10 @@ int html_post_handler(const xs_dict *req, const char *q_path,
timeline_touch(&snac); timeline_touch(&snac);
} }
else else
status = 404; status = HTTP_STATUS_NOT_FOUND;
/* delete the cached timeline */ /* delete the cached timeline */
if (status == 303) if (status == HTTP_STATUS_SEE_OTHER)
history_del(&snac, "timeline.html_"); history_del(&snac, "timeline.html_");
} }
else else
@ -3356,14 +3356,14 @@ int html_post_handler(const xs_dict *req, const char *q_path,
enqueue_verify_links(&snac); enqueue_verify_links(&snac);
status = 303; status = HTTP_STATUS_SEE_OTHER;
} }
else else
if (p_path && strcmp(p_path, "admin/clear-notifications") == 0) { /** **/ if (p_path && strcmp(p_path, "admin/clear-notifications") == 0) { /** **/
notify_clear(&snac); notify_clear(&snac);
timeline_touch(&snac); timeline_touch(&snac);
status = 303; status = HTTP_STATUS_SEE_OTHER;
} }
else else
if (p_path && strcmp(p_path, "admin/vote") == 0) { /** **/ if (p_path && strcmp(p_path, "admin/vote") == 0) { /** **/
@ -3416,10 +3416,10 @@ int html_post_handler(const xs_dict *req, const char *q_path,
} }
} }
status = 303; status = HTTP_STATUS_SEE_OTHER;
} }
if (status == 303) { if (status == HTTP_STATUS_SEE_OTHER) {
const char *redir = xs_dict_get(p_vars, "redir"); const char *redir = xs_dict_get(p_vars, "redir");
if (xs_is_null(redir)) if (xs_is_null(redir))

26
httpd.c
View file

@ -217,17 +217,17 @@ int server_get_handler(xs_dict *req, const char *q_path,
*body = greeting_html(); *body = greeting_html();
if (*body) if (*body)
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(q_path, "/susie.png") == 0 || strcmp(q_path, "/favicon.ico") == 0 ) { if (strcmp(q_path, "/susie.png") == 0 || strcmp(q_path, "/favicon.ico") == 0 ) {
status = 200; status = HTTP_STATUS_OK;
*body = xs_base64_dec(default_avatar_base64(), b_size); *body = xs_base64_dec(default_avatar_base64(), b_size);
*ctype = "image/png"; *ctype = "image/png";
} }
else else
if (strcmp(q_path, "/.well-known/nodeinfo") == 0) { if (strcmp(q_path, "/.well-known/nodeinfo") == 0) {
status = 200; status = HTTP_STATUS_OK;
*ctype = "application/json; charset=utf-8"; *ctype = "application/json; charset=utf-8";
*body = xs_fmt("{\"links\":[" *body = xs_fmt("{\"links\":["
"{\"rel\":\"http:/" "/nodeinfo.diaspora.software/ns/schema/2.0\"," "{\"rel\":\"http:/" "/nodeinfo.diaspora.software/ns/schema/2.0\","
@ -236,7 +236,7 @@ int server_get_handler(xs_dict *req, const char *q_path,
} }
else else
if (strcmp(q_path, "/.well-known/host-meta") == 0) { if (strcmp(q_path, "/.well-known/host-meta") == 0) {
status = 200; status = HTTP_STATUS_OK;
*ctype = "application/xrd+xml"; *ctype = "application/xrd+xml";
*body = xs_fmt("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" *body = xs_fmt("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<XRD>" "<XRD>"
@ -245,13 +245,13 @@ int server_get_handler(xs_dict *req, const char *q_path,
} }
else else
if (strcmp(q_path, "/nodeinfo_2_0") == 0) { if (strcmp(q_path, "/nodeinfo_2_0") == 0) {
status = 200; status = HTTP_STATUS_OK;
*ctype = "application/json; charset=utf-8"; *ctype = "application/json; charset=utf-8";
*body = nodeinfo_2_0(); *body = nodeinfo_2_0();
} }
else else
if (strcmp(q_path, "/robots.txt") == 0) { if (strcmp(q_path, "/robots.txt") == 0) {
status = 200; status = HTTP_STATUS_OK;
*ctype = "text/plain"; *ctype = "text/plain";
*body = xs_str_new("User-agent: *\n" *body = xs_str_new("User-agent: *\n"
"Disallow: /\n"); "Disallow: /\n");
@ -363,7 +363,7 @@ void httpd_connection(FILE *f)
} }
else else
if (strcmp(method, "OPTIONS") == 0) { if (strcmp(method, "OPTIONS") == 0) {
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(method, "DELETE") == 0) { if (strcmp(method, "DELETE") == 0) {
@ -378,22 +378,22 @@ void httpd_connection(FILE *f)
if (status == 0) { if (status == 0) {
srv_archive_error("unattended_method", "unattended method", req, payload); srv_archive_error("unattended_method", "unattended method", req, payload);
srv_debug(1, xs_fmt("httpd_connection unattended %s %s", method, q_path)); srv_debug(1, xs_fmt("httpd_connection unattended %s %s", method, q_path));
status = 404; status = HTTP_STATUS_NOT_FOUND;
} }
if (status == 403) if (status == HTTP_STATUS_FORBIDDEN)
body = xs_str_new("<h1>403 Forbidden</h1>"); body = xs_str_new("<h1>403 Forbidden</h1>");
if (status == 404) if (status == HTTP_STATUS_NOT_FOUND)
body = xs_str_new("<h1>404 Not Found</h1>"); body = xs_str_new("<h1>404 Not Found</h1>");
if (status == 400 && body != NULL) if (status == HTTP_STATUS_BAD_REQUEST && body != NULL)
body = xs_str_new("<h1>400 Bad Request</h1>"); body = xs_str_new("<h1>400 Bad Request</h1>");
if (status == 303) if (status == HTTP_STATUS_SEE_OTHER)
headers = xs_dict_append(headers, "location", body); headers = xs_dict_append(headers, "location", body);
if (status == 401) { if (status == HTTP_STATUS_UNAUTHORIZED) {
xs *www_auth = xs_fmt("Basic realm=\"@%s@%s snac login\"", xs *www_auth = xs_fmt("Basic realm=\"@%s@%s snac login\"",
body, xs_dict_get(srv_config, "host")); body, xs_dict_get(srv_config, "host"));

View file

@ -32,9 +32,9 @@ int app_add(const char *id, const xs_dict *app)
/* stores an app */ /* stores an app */
{ {
if (!xs_is_hex(id)) if (!xs_is_hex(id))
return 500; return HTTP_STATUS_INTERNAL_SERVER_ERROR;
int status = 201; int status = HTTP_STATUS_CREATED;
xs *fn = xs_fmt("%s/app/", srv_basedir); xs *fn = xs_fmt("%s/app/", srv_basedir);
FILE *f; FILE *f;
@ -47,7 +47,7 @@ int app_add(const char *id, const xs_dict *app)
fclose(f); fclose(f);
} }
else else
status = 500; status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
return status; return status;
} }
@ -95,9 +95,9 @@ int token_add(const char *id, const xs_dict *token)
/* stores a token */ /* stores a token */
{ {
if (!xs_is_hex(id)) if (!xs_is_hex(id))
return 500; return HTTP_STATUS_INTERNAL_SERVER_ERROR;
int status = 201; int status = HTTP_STATUS_CREATED;
xs *fn = xs_fmt("%s/token/", srv_basedir); xs *fn = xs_fmt("%s/token/", srv_basedir);
FILE *f; FILE *f;
@ -110,7 +110,7 @@ int token_add(const char *id, const xs_dict *token)
fclose(f); fclose(f);
} }
else else
status = 500; status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
return status; return status;
} }
@ -174,7 +174,7 @@ int oauth_get_handler(const xs_dict *req, const char *q_path,
if (!xs_startswith(q_path, "/oauth/")) if (!xs_startswith(q_path, "/oauth/"))
return 0; return 0;
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
const xs_dict *msg = xs_dict_get(req, "q_vars"); const xs_dict *msg = xs_dict_get(req, "q_vars");
xs *cmd = xs_replace_n(q_path, "/oauth", "", 1); xs *cmd = xs_replace_n(q_path, "/oauth", "", 1);
@ -186,7 +186,7 @@ int oauth_get_handler(const xs_dict *req, const char *q_path,
const char *rtype = xs_dict_get(msg, "response_type"); const char *rtype = xs_dict_get(msg, "response_type");
const char *state = xs_dict_get(msg, "state"); const char *state = xs_dict_get(msg, "state");
status = 400; status = HTTP_STATUS_BAD_REQUEST;
if (cid && ruri && rtype && strcmp(rtype, "code") == 0) { if (cid && ruri && rtype && strcmp(rtype, "code") == 0) {
xs *app = app_get(cid); xs *app = app_get(cid);
@ -201,7 +201,7 @@ int oauth_get_handler(const xs_dict *req, const char *q_path,
*body = xs_fmt(login_page, host, host, "", proto, host, "oauth/x-snac-login", *body = xs_fmt(login_page, host, host, "", proto, host, "oauth/x-snac-login",
ruri, cid, state, USER_AGENT); ruri, cid, state, USER_AGENT);
*ctype = "text/html"; *ctype = "text/html";
status = 200; status = HTTP_STATUS_OK;
srv_debug(1, xs_fmt("oauth authorize: generating login page")); srv_debug(1, xs_fmt("oauth authorize: generating login page"));
} }
@ -219,7 +219,7 @@ int oauth_get_handler(const xs_dict *req, const char *q_path,
*body = xs_fmt(login_page, host, host, "", proto, host, "oauth/x-snac-get-token", *body = xs_fmt(login_page, host, host, "", proto, host, "oauth/x-snac-get-token",
"", "", "", USER_AGENT); "", "", "", USER_AGENT);
*ctype = "text/html"; *ctype = "text/html";
status = 200; status = HTTP_STATUS_OK;
} }
@ -237,7 +237,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
if (!xs_startswith(q_path, "/oauth/")) if (!xs_startswith(q_path, "/oauth/"))
return 0; return 0;
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
const char *i_ctype = xs_dict_get(req, "content-type"); const char *i_ctype = xs_dict_get(req, "content-type");
xs *args = NULL; xs *args = NULL;
@ -255,7 +255,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
args = xs_dup(xs_dict_get(req, "p_vars")); args = xs_dup(xs_dict_get(req, "p_vars"));
if (args == NULL) if (args == NULL)
return 400; return HTTP_STATUS_BAD_REQUEST;
xs *cmd = xs_replace_n(q_path, "/oauth", "", 1); xs *cmd = xs_replace_n(q_path, "/oauth", "", 1);
@ -274,7 +274,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
*body = xs_fmt(login_page, host, host, "LOGIN INCORRECT", proto, host, "oauth/x-snac-login", *body = xs_fmt(login_page, host, host, "LOGIN INCORRECT", proto, host, "oauth/x-snac-login",
redir, cid, state, USER_AGENT); redir, cid, state, USER_AGENT);
*ctype = "text/html"; *ctype = "text/html";
status = 200; status = HTTP_STATUS_OK;
if (login && passwd && redir && cid) { if (login && passwd && redir && cid) {
snac snac; snac snac;
@ -296,7 +296,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
else else
*body = xs_fmt("%s?code=%s", redir, code); *body = xs_fmt("%s?code=%s", redir, code);
status = 303; status = HTTP_STATUS_SEE_OTHER;
} }
/* if there is a state, add it */ /* if there is a state, add it */
@ -375,12 +375,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
xs *app = app_get(cid); xs *app = app_get(cid);
if (app == NULL) { if (app == NULL) {
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
srv_log(xs_fmt("oauth token: invalid app %s", cid)); srv_log(xs_fmt("oauth token: invalid app %s", cid));
} }
else else
if (strcmp(csec, xs_dict_get(app, "client_secret")) != 0) { if (strcmp(csec, xs_dict_get(app, "client_secret")) != 0) {
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
srv_log(xs_fmt("oauth token: invalid client_secret for app %s", cid)); srv_log(xs_fmt("oauth token: invalid client_secret for app %s", cid));
} }
else { else {
@ -397,7 +397,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(rsp, 4); *body = xs_json_dumps(rsp, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
const char *uid = xs_dict_get(app, "uid"); const char *uid = xs_dict_get(app, "uid");
@ -416,7 +416,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
} }
else { else {
srv_debug(1, xs_fmt("oauth token: invalid or unset arguments")); srv_debug(1, xs_fmt("oauth token: invalid or unset arguments"));
status = 400; status = HTTP_STATUS_BAD_REQUEST;
} }
} }
else else
@ -433,12 +433,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
if (token == NULL || strcmp(csec, xs_dict_get(token, "client_secret")) != 0) { if (token == NULL || strcmp(csec, xs_dict_get(token, "client_secret")) != 0) {
srv_debug(1, xs_fmt("oauth revoke: bad secret for token %s", tokid)); srv_debug(1, xs_fmt("oauth revoke: bad secret for token %s", tokid));
status = 403; status = HTTP_STATUS_FORBIDDEN;
} }
else { else {
token_del(tokid); token_del(tokid);
srv_debug(1, xs_fmt("oauth revoke: revoked token %s", tokid)); srv_debug(1, xs_fmt("oauth revoke: revoked token %s", tokid));
status = 200; status = HTTP_STATUS_OK;
/* also delete the app, as it serves no purpose from now on */ /* also delete the app, as it serves no purpose from now on */
app_del(cid); app_del(cid);
@ -446,7 +446,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
} }
else { else {
srv_debug(1, xs_fmt("oauth revoke: invalid or unset arguments")); srv_debug(1, xs_fmt("oauth revoke: invalid or unset arguments"));
status = 403; status = HTTP_STATUS_FORBIDDEN;
} }
} }
if (strcmp(cmd, "/x-snac-get-token") == 0) { /** **/ if (strcmp(cmd, "/x-snac-get-token") == 0) { /** **/
@ -459,7 +459,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
*body = xs_fmt(login_page, host, host, "LOGIN INCORRECT", proto, host, "oauth/x-snac-get-token", *body = xs_fmt(login_page, host, host, "LOGIN INCORRECT", proto, host, "oauth/x-snac-get-token",
"", "", "", USER_AGENT); "", "", "", USER_AGENT);
*ctype = "text/html"; *ctype = "text/html";
status = 200; status = HTTP_STATUS_OK;
if (login && passwd) { if (login && passwd) {
snac user; snac user;
@ -1159,7 +1159,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/")) if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
return 0; return 0;
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
const xs_dict *args = xs_dict_get(req, "q_vars"); const xs_dict *args = xs_dict_get(req, "q_vars");
xs *cmd = xs_replace_n(q_path, "/api", "", 1); xs *cmd = xs_replace_n(q_path, "/api", "", 1);
@ -1249,10 +1249,10 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(acct, 4); *body = xs_json_dumps(acct, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else { else {
status = 422; // "Unprocessable entity" (no login) status = HTTP_STATUS_UNPROCESSABLE_CONTENT; // (no login)
} }
} }
else else
@ -1279,10 +1279,10 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(res, 4); *body = xs_json_dumps(res, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 422; status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
} }
else else
if (strcmp(cmd, "/v1/accounts/lookup") == 0) { /** **/ if (strcmp(cmd, "/v1/accounts/lookup") == 0) { /** **/
@ -1304,7 +1304,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(macct, 4); *body = xs_json_dumps(macct, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
user_free(&user); user_free(&user);
} }
@ -1450,7 +1450,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
if (out != NULL) { if (out != NULL) {
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
@ -1554,12 +1554,12 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
srv_debug(2, xs_fmt("mastoapi timeline: returned %d entries", xs_list_len(out))); srv_debug(2, xs_fmt("mastoapi timeline: returned %d entries", xs_list_len(out)));
} }
else { else {
status = 401; // unauthorized status = HTTP_STATUS_UNAUTHORIZED;
} }
} }
else else
@ -1612,7 +1612,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (xs_startswith(cmd, "/v1/timelines/tag/")) { /** **/ if (xs_startswith(cmd, "/v1/timelines/tag/")) { /** **/
@ -1661,7 +1661,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (xs_startswith(cmd, "/v1/timelines/list/")) { /** **/ if (xs_startswith(cmd, "/v1/timelines/list/")) { /** **/
@ -1729,17 +1729,17 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 421; status = HTTP_STATUS_MISDIRECTED_REQUEST;
} }
else else
if (strcmp(cmd, "/v1/conversations") == 0) { /** **/ if (strcmp(cmd, "/v1/conversations") == 0) { /** **/
/* TBD */ /* TBD */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/notifications") == 0) { /** **/ if (strcmp(cmd, "/v1/notifications") == 0) { /** **/
@ -1817,17 +1817,17 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (strcmp(cmd, "/v1/filters") == 0) { /** **/ if (strcmp(cmd, "/v1/filters") == 0) { /** **/
/* snac will never have filters */ /* snac will never have filters */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v2/filters") == 0) { /** **/ if (strcmp(cmd, "/v2/filters") == 0) { /** **/
@ -1836,21 +1836,21 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
* in some apps */ * in some apps */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/favourites") == 0) { /** **/ if (strcmp(cmd, "/v1/favourites") == 0) { /** **/
/* snac will never support a list of favourites */ /* snac will never support a list of favourites */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/bookmarks") == 0) { /** **/ if (strcmp(cmd, "/v1/bookmarks") == 0) { /** **/
/* snac does not support bookmarks */ /* snac does not support bookmarks */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/lists") == 0) { /** list of lists **/ if (strcmp(cmd, "/v1/lists") == 0) { /** list of lists **/
@ -1873,7 +1873,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(l, 4); *body = xs_json_dumps(l, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
@ -1903,7 +1903,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
@ -1931,7 +1931,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
@ -1941,28 +1941,28 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
/* snac does not schedule notes */ /* snac does not schedule notes */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/follow_requests") == 0) { /** **/ if (strcmp(cmd, "/v1/follow_requests") == 0) { /** **/
/* snac does not support optional follow confirmations */ /* snac does not support optional follow confirmations */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/announcements") == 0) { /** **/ if (strcmp(cmd, "/v1/announcements") == 0) { /** **/
/* snac has no announcements (yet?) */ /* snac has no announcements (yet?) */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/custom_emojis") == 0) { /** **/ if (strcmp(cmd, "/v1/custom_emojis") == 0) { /** **/
/* are you kidding me? */ /* are you kidding me? */
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/instance") == 0) { /** **/ if (strcmp(cmd, "/v1/instance") == 0) { /** **/
@ -2075,7 +2075,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(ins, 4); *body = xs_json_dumps(ins, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (xs_startswith(cmd, "/v1/statuses/")) { /** **/ if (xs_startswith(cmd, "/v1/statuses/")) { /** **/
@ -2188,30 +2188,30 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
if (out != NULL) { if (out != NULL) {
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (strcmp(cmd, "/v1/preferences") == 0) { /** **/ if (strcmp(cmd, "/v1/preferences") == 0) { /** **/
*body = xs_dup("{}"); *body = xs_dup("{}");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/markers") == 0) { /** **/ if (strcmp(cmd, "/v1/markers") == 0) { /** **/
*body = xs_dup("{}"); *body = xs_dup("{}");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v1/followed_tags") == 0) { /** **/ if (strcmp(cmd, "/v1/followed_tags") == 0) { /** **/
*body = xs_dup("[]"); *body = xs_dup("[]");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (strcmp(cmd, "/v2/search") == 0) { /** **/ if (strcmp(cmd, "/v2/search") == 0) { /** **/
@ -2290,10 +2290,10 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(res, 4); *body = xs_json_dumps(res, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
/* user cleanup */ /* user cleanup */
@ -2316,7 +2316,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/")) if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
return 0; return 0;
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
xs *args = NULL; xs *args = NULL;
const char *i_ctype = xs_dict_get(req, "content-type"); const char *i_ctype = xs_dict_get(req, "content-type");
@ -2336,7 +2336,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
args = xs_dup(xs_dict_get(req, "p_vars")); args = xs_dup(xs_dict_get(req, "p_vars"));
if (args == NULL) if (args == NULL)
return 400; return HTTP_STATUS_BAD_REQUEST;
xs *cmd = xs_replace_n(q_path, "/api", "", 1); xs *cmd = xs_replace_n(q_path, "/api", "", 1);
@ -2378,7 +2378,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(app, 4); *body = xs_json_dumps(app, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
app = xs_dict_append(app, "code", ""); app = xs_dict_append(app, "code", "");
@ -2470,10 +2470,10 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(st, 4); *body = xs_json_dumps(st, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (xs_startswith(cmd, "/v1/statuses")) { /** **/ if (xs_startswith(cmd, "/v1/statuses")) { /** **/
@ -2552,7 +2552,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
if (pin(&snac, id)) if (pin(&snac, id))
out = mastoapi_status(&snac, msg); out = mastoapi_status(&snac, msg);
else else
status = 422; status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
} }
else else
if (strcmp(op, "unpin") == 0) { /** **/ if (strcmp(op, "unpin") == 0) { /** **/
@ -2573,12 +2573,12 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
if (out != NULL) { if (out != NULL) {
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (strcmp(cmd, "/v1/notifications/clear") == 0) { /** **/ if (strcmp(cmd, "/v1/notifications/clear") == 0) { /** **/
@ -2588,10 +2588,10 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
*body = xs_dup("{}"); *body = xs_dup("{}");
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (strcmp(cmd, "/v1/push/subscription") == 0) { /** **/ if (strcmp(cmd, "/v1/push/subscription") == 0) { /** **/
@ -2616,10 +2616,10 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(wpush, 4); *body = xs_json_dumps(wpush, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (strcmp(cmd, "/v1/media") == 0 || strcmp(cmd, "/v2/media") == 0) { /** **/ if (strcmp(cmd, "/v1/media") == 0 || strcmp(cmd, "/v2/media") == 0) { /** **/
@ -2630,7 +2630,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
if (xs_is_null(desc)) if (xs_is_null(desc))
desc = ""; desc = "";
status = 400; status = HTTP_STATUS_BAD_REQUEST;
if (xs_type(file) == XSTYPE_LIST) { if (xs_type(file) == XSTYPE_LIST) {
const char *fn = xs_list_get(file, 0); const char *fn = xs_list_get(file, 0);
@ -2659,12 +2659,12 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(rsp, 4); *body = xs_json_dumps(rsp, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (xs_startswith(cmd, "/v1/accounts")) { /** **/ if (xs_startswith(cmd, "/v1/accounts")) { /** **/
@ -2744,11 +2744,11 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
if (rsp != NULL) { if (rsp != NULL) {
*body = xs_json_dumps(rsp, 4); *body = xs_json_dumps(rsp, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (xs_startswith(cmd, "/v1/polls")) { /** **/ if (xs_startswith(cmd, "/v1/polls")) { /** **/
@ -2810,12 +2810,12 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
if (out != NULL) { if (out != NULL) {
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (strcmp(cmd, "/v1/lists") == 0) { if (strcmp(cmd, "/v1/lists") == 0) {
@ -2831,18 +2831,18 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
out = xs_dict_append(out, "replies_policy", xs_dict_get_def(args, "replies_policy", "list")); out = xs_dict_append(out, "replies_policy", xs_dict_get_def(args, "replies_policy", "list"));
out = xs_dict_append(out, "exclusive", xs_stock(XSTYPE_FALSE)); out = xs_dict_append(out, "exclusive", xs_stock(XSTYPE_FALSE));
status = 200; status = HTTP_STATUS_OK;
} }
else { else {
out = xs_dict_append(out, "error", "cannot create list"); out = xs_dict_append(out, "error", "cannot create list");
status = 422; status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
} }
*body = xs_json_dumps(out, 4); *body = xs_json_dumps(out, 4);
*ctype = "application/json"; *ctype = "application/json";
} }
else else
status = 422; status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
} }
} }
if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/ if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/
@ -2861,12 +2861,12 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
list_content(&snac, id, v, 1); list_content(&snac, id, v, 1);
} }
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
else else
status = 422; status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
} }
/* user cleanup */ /* user cleanup */
@ -2891,7 +2891,7 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/")) if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
return 0; return 0;
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
xs *args = NULL; xs *args = NULL;
const char *i_ctype = xs_dict_get(req, "content-type"); const char *i_ctype = xs_dict_get(req, "content-type");
@ -2911,7 +2911,7 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
args = xs_dup(xs_dict_get(req, "p_vars")); args = xs_dup(xs_dict_get(req, "p_vars"));
if (args == NULL) if (args == NULL)
return 400; return HTTP_STATUS_BAD_REQUEST;
snac snac = {0}; snac snac = {0};
int logged_in = process_auth_token(&snac, req); int logged_in = process_auth_token(&snac, req);
@ -2920,7 +2920,7 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
if (xs_startswith(cmd, "/v1/push/subscription") || xs_startswith(cmd, "/v2/push/subscription")) { /** **/ if (xs_startswith(cmd, "/v1/push/subscription") || xs_startswith(cmd, "/v2/push/subscription")) { /** **/
// pretend we deleted it, since it doesn't exist anyway // pretend we deleted it, since it doesn't exist anyway
status = 200; status = HTTP_STATUS_OK;
} }
else else
if (xs_startswith(cmd, "/v1/lists/")) { if (xs_startswith(cmd, "/v1/lists/")) {
@ -2948,10 +2948,10 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
} }
} }
status = 200; status = HTTP_STATUS_OK;
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
/* user cleanup */ /* user cleanup */
@ -2974,7 +2974,7 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/")) if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
return 0; return 0;
int status = 404; int status = HTTP_STATUS_NOT_FOUND;
xs *args = NULL; xs *args = NULL;
const char *i_ctype = xs_dict_get(req, "content-type"); const char *i_ctype = xs_dict_get(req, "content-type");
@ -2986,7 +2986,7 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
args = xs_dup(xs_dict_get(req, "p_vars")); args = xs_dup(xs_dict_get(req, "p_vars"));
if (args == NULL) if (args == NULL)
return 400; return HTTP_STATUS_BAD_REQUEST;
xs *cmd = xs_replace_n(q_path, "/api", "", 1); xs *cmd = xs_replace_n(q_path, "/api", "", 1);
@ -3017,11 +3017,11 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
*body = xs_json_dumps(rsp, 4); *body = xs_json_dumps(rsp, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
else else
if (xs_startswith(cmd, "/v1/statuses")) { if (xs_startswith(cmd, "/v1/statuses")) {
@ -3060,12 +3060,12 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
if (rsp != NULL) { if (rsp != NULL) {
*body = xs_json_dumps(rsp, 4); *body = xs_json_dumps(rsp, 4);
*ctype = "application/json"; *ctype = "application/json";
status = 200; status = HTTP_STATUS_OK;
} }
} }
} }
else else
status = 401; status = HTTP_STATUS_UNAUTHORIZED;
} }
/* user cleanup */ /* user cleanup */

50
snac.h
View file

@ -361,3 +361,53 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
void mastoapi_purge(void); void mastoapi_purge(void);
void verify_links(snac *user); void verify_links(snac *user);
/* HTTP responses RFC 9110 plus some extensions */
typedef enum {
HTTP_STATUS_CONTINUE = 100,
HTTP_STATUS_SWITCHTING_PROTOCOLS = 101,
HTTP_STATUS_PROCESSING = 102,
HTTP_STATUS_EARLY_HINTS = 103,
HTTP_STATUS_OK = 200,
HTTP_STATUS_CREATED = 201,
HTTP_STATUS_ACCEPTED = 202,
HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203,
HTTP_STATUS_NO_CONTENT = 204,
HTTP_STATUS_RESET_CONTENT = 205,
HTTP_STATUS_PARTIAL_CONTENT = 206,
HTTP_STATUS_MULTI_STATUS = 207,
HTTP_STATUS_ALREADY_REPORTED = 208,
HTTP_STATUS_THIS_IS_FINE = 218,
HTTP_STATUS_IM_USED = 226,
HTTP_STATUS_MULTIPLE_CHOICES = 300,
HTTP_STATUS_MOVED_PERMANENTLY = 301,
HTTP_STATUS_FOUND = 302,
HTTP_STATUS_SEE_OTHER = 303,
HTTP_STATUS_NOT_MODIFIED = 304,
HTTP_STATUS_USE_PROXY = 305,
HTTP_STATUS_SWITCH_PROXY = 306,
HTTP_STATUS_TEMPORARY_REDIRECT = 307,
HTTP_STATUS_PERMANENT_REDIRECT = 308,
HTTP_STATUS_BAD_REQUEST = 400,
HTTP_STATUS_UNAUTHORIZED = 401,
HTTP_STATUS_PAYMENT_REQUIRED = 402,
HTTP_STATUS_FORBIDDEN = 403,
HTTP_STATUS_NOT_FOUND = 404,
HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
HTTP_STATUS_NOT_ACCEPTABLE = 406,
HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
HTTP_STATUS_REQUEST_TIMEOUT = 408,
HTTP_STATUS_CONFLICT = 409,
HTTP_STATUS_GONE = 410,
HTTP_STATUS_MISDIRECTED_REQUEST = 421,
HTTP_STATUS_UNPROCESSABLE_CONTENT = 422,
HTTP_STATUS_CLIENT_CLOSED_REQUEST = 499,
HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
HTTP_STATUS_NOT_IMPLEMENTED = 501,
HTTP_STATUS_BAD_GATEWAY = 502,
HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
HTTP_STATUS_GATEWAY_TIMEOUT = 504,
HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505,
HTTP_STATUS_INSUFFICIENT_STORAGE = 507
} http_status;

View file

@ -42,7 +42,7 @@ int webfinger_request_signed(snac *snac, const char *qs, char **actor, char **us
} }
if (host == NULL || resource == NULL) if (host == NULL || resource == NULL)
return 400; return HTTP_STATUS_BAD_REQUEST;
headers = xs_dict_append(headers, "accept", "application/json"); headers = xs_dict_append(headers, "accept", "application/json");
headers = xs_dict_append(headers, "user-agent", USER_AGENT); headers = xs_dict_append(headers, "user-agent", USER_AGENT);
@ -139,7 +139,7 @@ int webfinger_get_handler(xs_dict *req, char *q_path,
const char *resource = xs_dict_get(q_vars, "resource"); const char *resource = xs_dict_get(q_vars, "resource");
if (resource == NULL) if (resource == NULL)
return 400; return HTTP_STATUS_BAD_REQUEST;
snac snac; snac snac;
int found = 0; int found = 0;
@ -220,12 +220,12 @@ int webfinger_get_handler(xs_dict *req, char *q_path,
user_free(&snac); user_free(&snac);
status = 200; status = HTTP_STATUS_OK;
*body = j; *body = j;
*ctype = "application/jrd+json"; *ctype = "application/jrd+json";
} }
else else
status = 404; status = HTTP_STATUS_NOT_FOUND;
srv_debug(1, xs_fmt("webfinger_get_handler resource=%s %d", resource, status)); srv_debug(1, xs_fmt("webfinger_get_handler resource=%s %d", resource, status));