diff options
Diffstat (limited to 'activitypub.c')
| -rw-r--r-- | activitypub.c | 283 |
1 files changed, 106 insertions, 177 deletions
diff --git a/activitypub.c b/activitypub.c index 231715b..f4b4eac 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -67,7 +67,7 @@ int activitypub_request(snac *user, const char *url, xs_dict **data) | |||
| 67 | xs *response = NULL; | 67 | xs *response = NULL; |
| 68 | xs *payload = NULL; | 68 | xs *payload = NULL; |
| 69 | int p_size; | 69 | int p_size; |
| 70 | char *ctype; | 70 | const char *ctype; |
| 71 | 71 | ||
| 72 | *data = NULL; | 72 | *data = NULL; |
| 73 | 73 | ||
| @@ -154,20 +154,21 @@ int actor_request(snac *user, const char *actor, xs_dict **data) | |||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | 156 | ||
| 157 | char *get_atto(const xs_dict *msg) | 157 | const char *get_atto(const xs_dict *msg) |
| 158 | /* gets the attributedTo field (an actor) */ | 158 | /* gets the attributedTo field (an actor) */ |
| 159 | { | 159 | { |
| 160 | char *actor = xs_dict_get(msg, "attributedTo"); | 160 | const xs_val *actor = xs_dict_get(msg, "attributedTo"); |
| 161 | 161 | ||
| 162 | /* if the actor is a list of objects (like on Peertube videos), pick the Person */ | 162 | /* if the actor is a list of objects (like on Peertube videos), pick the Person */ |
| 163 | if (xs_type(actor) == XSTYPE_LIST) { | 163 | if (xs_type(actor) == XSTYPE_LIST) { |
| 164 | xs_list *p = actor; | 164 | const xs_list *p = actor; |
| 165 | int c = 0; | ||
| 165 | xs_dict *v; | 166 | xs_dict *v; |
| 166 | actor = NULL; | 167 | actor = NULL; |
| 167 | 168 | ||
| 168 | while (actor == NULL && xs_list_iter(&p, &v)) { | 169 | while (actor == NULL && xs_list_next(p, &v, &c)) { |
| 169 | if (xs_type(v) == XSTYPE_DICT) { | 170 | if (xs_type(v) == XSTYPE_DICT) { |
| 170 | char *type = xs_dict_get(v, "type"); | 171 | const char *type = xs_dict_get(v, "type"); |
| 171 | if (xs_type(type) == XSTYPE_STRING && strcmp(type, "Person") == 0) { | 172 | if (xs_type(type) == XSTYPE_STRING && strcmp(type, "Person") == 0) { |
| 172 | actor = xs_dict_get(v, "id"); | 173 | actor = xs_dict_get(v, "id"); |
| 173 | 174 | ||
| @@ -186,7 +187,7 @@ xs_list *get_attachments(const xs_dict *msg) | |||
| 186 | /* unify the garbage fire that are the attachments */ | 187 | /* unify the garbage fire that are the attachments */ |
| 187 | { | 188 | { |
| 188 | xs_list *l = xs_list_new(); | 189 | xs_list *l = xs_list_new(); |
| 189 | xs_list *p; | 190 | const xs_list *p; |
| 190 | 191 | ||
| 191 | /* try first the attachments list */ | 192 | /* try first the attachments list */ |
| 192 | if (!xs_is_null(p = xs_dict_get(msg, "attachment"))) { | 193 | if (!xs_is_null(p = xs_dict_get(msg, "attachment"))) { |
| @@ -203,23 +204,24 @@ xs_list *get_attachments(const xs_dict *msg) | |||
| 203 | 204 | ||
| 204 | if (xs_type(attach) == XSTYPE_LIST) { | 205 | if (xs_type(attach) == XSTYPE_LIST) { |
| 205 | /* does the message have an image? */ | 206 | /* does the message have an image? */ |
| 206 | if (xs_type(v = xs_dict_get(msg, "image")) == XSTYPE_DICT) { | 207 | const xs_dict *d = xs_dict_get(msg, "image"); |
| 208 | if (xs_type(d) == XSTYPE_DICT) { | ||
| 207 | /* add it to the attachment list */ | 209 | /* add it to the attachment list */ |
| 208 | attach = xs_list_append(attach, v); | 210 | attach = xs_list_append(attach, d); |
| 209 | } | 211 | } |
| 210 | } | 212 | } |
| 211 | 213 | ||
| 212 | /* now iterate the list */ | 214 | /* now iterate the list */ |
| 213 | p = attach; | 215 | int c = 0; |
| 214 | while (xs_list_iter(&p, &v)) { | 216 | while (xs_list_next(attach, &v, &c)) { |
| 215 | char *type = xs_dict_get(v, "mediaType"); | 217 | const char *type = xs_dict_get(v, "mediaType"); |
| 216 | if (xs_is_null(type)) | 218 | if (xs_is_null(type)) |
| 217 | type = xs_dict_get(v, "type"); | 219 | type = xs_dict_get(v, "type"); |
| 218 | 220 | ||
| 219 | if (xs_is_null(type)) | 221 | if (xs_is_null(type)) |
| 220 | continue; | 222 | continue; |
| 221 | 223 | ||
| 222 | char *href = xs_dict_get(v, "url"); | 224 | const char *href = xs_dict_get(v, "url"); |
| 223 | if (xs_is_null(href)) | 225 | if (xs_is_null(href)) |
| 224 | href = xs_dict_get(v, "href"); | 226 | href = xs_dict_get(v, "href"); |
| 225 | if (xs_is_null(href)) | 227 | if (xs_is_null(href)) |
| @@ -233,7 +235,7 @@ xs_list *get_attachments(const xs_dict *msg) | |||
| 233 | type = mt; | 235 | type = mt; |
| 234 | } | 236 | } |
| 235 | 237 | ||
| 236 | char *name = xs_dict_get(v, "name"); | 238 | const char *name = xs_dict_get(v, "name"); |
| 237 | if (xs_is_null(name)) | 239 | if (xs_is_null(name)) |
| 238 | name = xs_dict_get(msg, "name"); | 240 | name = xs_dict_get(msg, "name"); |
| 239 | if (xs_is_null(name)) | 241 | if (xs_is_null(name)) |
| @@ -252,29 +254,31 @@ xs_list *get_attachments(const xs_dict *msg) | |||
| 252 | p = xs_dict_get(msg, "url"); | 254 | p = xs_dict_get(msg, "url"); |
| 253 | 255 | ||
| 254 | if (xs_type(p) == XSTYPE_LIST) { | 256 | if (xs_type(p) == XSTYPE_LIST) { |
| 255 | char *href = NULL; | 257 | const char *href = NULL; |
| 256 | char *type = NULL; | 258 | const char *type = NULL; |
| 259 | int c = 0; | ||
| 257 | xs_val *v; | 260 | xs_val *v; |
| 258 | 261 | ||
| 259 | while (href == NULL && xs_list_iter(&p, &v)) { | 262 | while (href == NULL && xs_list_next(p, &v, &c)) { |
| 260 | if (xs_type(v) == XSTYPE_DICT) { | 263 | if (xs_type(v) == XSTYPE_DICT) { |
| 261 | char *mtype = xs_dict_get(v, "type"); | 264 | const char *mtype = xs_dict_get(v, "type"); |
| 262 | 265 | ||
| 263 | if (xs_type(mtype) == XSTYPE_STRING && strcmp(mtype, "Link") == 0) { | 266 | if (xs_type(mtype) == XSTYPE_STRING && strcmp(mtype, "Link") == 0) { |
| 264 | mtype = xs_dict_get(v, "mediaType"); | 267 | mtype = xs_dict_get(v, "mediaType"); |
| 265 | xs_list *tag = xs_dict_get(v, "tag"); | 268 | const xs_list *tag = xs_dict_get(v, "tag"); |
| 266 | 269 | ||
| 267 | if (xs_type(mtype) == XSTYPE_STRING && | 270 | if (xs_type(mtype) == XSTYPE_STRING && |
| 268 | strcmp(mtype, "application/x-mpegURL") == 0 && | 271 | strcmp(mtype, "application/x-mpegURL") == 0 && |
| 269 | xs_type(tag) == XSTYPE_LIST) { | 272 | xs_type(tag) == XSTYPE_LIST) { |
| 270 | /* now iterate the tag list, looking for a video URL */ | 273 | /* now iterate the tag list, looking for a video URL */ |
| 271 | xs_dict *d; | 274 | xs_dict *d; |
| 275 | int c = 0; | ||
| 272 | 276 | ||
| 273 | while (href == NULL && xs_list_iter(&tag, &d)) { | 277 | while (href == NULL && xs_list_next(tag, &d, &c)) { |
| 274 | if (xs_type(d) == XSTYPE_DICT) { | 278 | if (xs_type(d) == XSTYPE_DICT) { |
| 275 | if (xs_type(mtype = xs_dict_get(d, "mediaType")) == XSTYPE_STRING && | 279 | if (xs_type(mtype = xs_dict_get(d, "mediaType")) == XSTYPE_STRING && |
| 276 | xs_startswith(mtype, "video/")) { | 280 | xs_startswith(mtype, "video/")) { |
| 277 | char *h = xs_dict_get(d, "href"); | 281 | const char *h = xs_dict_get(d, "href"); |
| 278 | 282 | ||
| 279 | /* this is probably it */ | 283 | /* this is probably it */ |
| 280 | if (xs_type(h) == XSTYPE_STRING) { | 284 | if (xs_type(h) == XSTYPE_STRING) { |
| @@ -303,7 +307,7 @@ xs_list *get_attachments(const xs_dict *msg) | |||
| 303 | } | 307 | } |
| 304 | 308 | ||
| 305 | 309 | ||
| 306 | int timeline_request(snac *snac, char **id, xs_str **wrk, int level) | 310 | int timeline_request(snac *snac, const char **id, xs_str **wrk, int level) |
| 307 | /* ensures that an entry and its ancestors are in the timeline */ | 311 | /* ensures that an entry and its ancestors are in the timeline */ |
| 308 | { | 312 | { |
| 309 | int status = 0; | 313 | int status = 0; |
| @@ -323,7 +327,7 @@ int timeline_request(snac *snac, char **id, xs_str **wrk, int level) | |||
| 323 | status = activitypub_request(snac, *id, &msg); | 327 | status = activitypub_request(snac, *id, &msg); |
| 324 | 328 | ||
| 325 | if (valid_status(status)) { | 329 | if (valid_status(status)) { |
| 326 | xs_dict *object = msg; | 330 | const xs_dict *object = msg; |
| 327 | const char *type = xs_dict_get(object, "type"); | 331 | const char *type = xs_dict_get(object, "type"); |
| 328 | 332 | ||
| 329 | /* get the id again from the object, as it may be different */ | 333 | /* get the id again from the object, as it may be different */ |
| @@ -369,7 +373,7 @@ int timeline_request(snac *snac, char **id, xs_str **wrk, int level) | |||
| 369 | } | 373 | } |
| 370 | 374 | ||
| 371 | /* does it have an ancestor? */ | 375 | /* does it have an ancestor? */ |
| 372 | char *in_reply_to = xs_dict_get(object, "inReplyTo"); | 376 | const char *in_reply_to = xs_dict_get(object, "inReplyTo"); |
| 373 | 377 | ||
| 374 | /* store */ | 378 | /* store */ |
| 375 | timeline_add(snac, nid, object); | 379 | timeline_add(snac, nid, object); |
| @@ -381,83 +385,12 @@ int timeline_request(snac *snac, char **id, xs_str **wrk, int level) | |||
| 381 | } | 385 | } |
| 382 | } | 386 | } |
| 383 | } | 387 | } |
| 384 | |||
| 385 | enqueue_request_replies(snac, *id); | ||
| 386 | } | 388 | } |
| 387 | 389 | ||
| 388 | return status; | 390 | return status; |
| 389 | } | 391 | } |
| 390 | 392 | ||
| 391 | 393 | ||
| 392 | void timeline_request_replies(snac *user, const char *id) | ||
| 393 | /* requests all replies of a message */ | ||
| 394 | /* FIXME: experimental -- needs more testing */ | ||
| 395 | { | ||
| 396 | /* FIXME: TEMPORARILY DISABLED */ | ||
| 397 | /* Reason: I've found that many of the posts in the 'replies' Collection | ||
| 398 | do not have an inReplyTo field (why??? aren't they 'replies'???). | ||
| 399 | For this reason, these requested objects are not stored as children | ||
| 400 | of the original post and they are shown as out-of-context, top level posts. | ||
| 401 | This process is disabled until I find an elegant way of providing a parent | ||
| 402 | for these 'stray' children. */ | ||
| 403 | return; | ||
| 404 | |||
| 405 | xs *msg = NULL; | ||
| 406 | |||
| 407 | if (!valid_status(object_get(id, &msg))) | ||
| 408 | return; | ||
| 409 | |||
| 410 | /* does it have a replies collection? */ | ||
| 411 | const xs_dict *replies = xs_dict_get(msg, "replies"); | ||
| 412 | |||
| 413 | if (!xs_is_null(replies)) { | ||
| 414 | const char *type = xs_dict_get(replies, "type"); | ||
| 415 | const char *first = xs_dict_get(replies, "first"); | ||
| 416 | |||
| 417 | if (!xs_is_null(type) && !xs_is_null(first) && strcmp(type, "Collection") == 0) { | ||
| 418 | const char *next = xs_dict_get(first, "next"); | ||
| 419 | |||
| 420 | if (!xs_is_null(next)) { | ||
| 421 | xs *rpls = NULL; | ||
| 422 | int status = activitypub_request(user, next, &rpls); | ||
| 423 | |||
| 424 | /* request the Collection of replies */ | ||
| 425 | if (valid_status(status)) { | ||
| 426 | xs_list *items = xs_dict_get(rpls, "items"); | ||
| 427 | |||
| 428 | if (xs_type(items) == XSTYPE_LIST) { | ||
| 429 | xs_val *v; | ||
| 430 | |||
| 431 | /* request them all */ | ||
| 432 | while (xs_list_iter(&items, &v)) { | ||
| 433 | if (xs_type(v) == XSTYPE_DICT) { | ||
| 434 | /* not an id, but the object itself (!) */ | ||
| 435 | const char *c_id = xs_dict_get(v, "id"); | ||
| 436 | |||
| 437 | if (!xs_is_null(id)) { | ||
| 438 | snac_debug(user, 0, xs_fmt("embedded reply %s", c_id)); | ||
| 439 | |||
| 440 | object_add(c_id, v); | ||
| 441 | |||
| 442 | /* get its own children */ | ||
| 443 | timeline_request_replies(user, v); | ||
| 444 | } | ||
| 445 | } | ||
| 446 | else { | ||
| 447 | snac_debug(user, 0, xs_fmt("request reply %s", v)); | ||
| 448 | timeline_request(user, &v, NULL, 0); | ||
| 449 | } | ||
| 450 | } | ||
| 451 | } | ||
| 452 | } | ||
| 453 | else | ||
| 454 | snac_debug(user, 0, xs_fmt("replies request error %s %d", next, status)); | ||
| 455 | } | ||
| 456 | } | ||
| 457 | } | ||
| 458 | } | ||
| 459 | |||
| 460 | |||
| 461 | int send_to_inbox_raw(const char *keyid, const char *seckey, | 394 | int send_to_inbox_raw(const char *keyid, const char *seckey, |
| 462 | const xs_str *inbox, const xs_dict *msg, | 395 | const xs_str *inbox, const xs_dict *msg, |
| 463 | xs_val **payload, int *p_size, int timeout) | 396 | xs_val **payload, int *p_size, int timeout) |
| @@ -480,7 +413,7 @@ int send_to_inbox(snac *snac, const xs_str *inbox, const xs_dict *msg, | |||
| 480 | xs_val **payload, int *p_size, int timeout) | 413 | xs_val **payload, int *p_size, int timeout) |
| 481 | /* sends a message to an Inbox */ | 414 | /* sends a message to an Inbox */ |
| 482 | { | 415 | { |
| 483 | char *seckey = xs_dict_get(snac->key, "secret"); | 416 | const char *seckey = xs_dict_get(snac->key, "secret"); |
| 484 | 417 | ||
| 485 | return send_to_inbox_raw(snac->actor, seckey, inbox, msg, payload, p_size, timeout); | 418 | return send_to_inbox_raw(snac->actor, seckey, inbox, msg, payload, p_size, timeout); |
| 486 | } | 419 | } |
| @@ -490,7 +423,7 @@ xs_str *get_actor_inbox(const char *actor) | |||
| 490 | /* gets an actor's inbox */ | 423 | /* gets an actor's inbox */ |
| 491 | { | 424 | { |
| 492 | xs *data = NULL; | 425 | xs *data = NULL; |
| 493 | char *v = NULL; | 426 | const char *v = NULL; |
| 494 | 427 | ||
| 495 | if (valid_status(actor_request(NULL, actor, &data))) { | 428 | if (valid_status(actor_request(NULL, actor, &data))) { |
| 496 | /* try first endpoints/sharedInbox */ | 429 | /* try first endpoints/sharedInbox */ |
| @@ -539,16 +472,16 @@ void post_message(snac *snac, const char *actor, const xs_dict *msg) | |||
| 539 | xs_list *recipient_list(snac *snac, const xs_dict *msg, int expand_public) | 472 | xs_list *recipient_list(snac *snac, const xs_dict *msg, int expand_public) |
| 540 | /* returns the list of recipients for a message */ | 473 | /* returns the list of recipients for a message */ |
| 541 | { | 474 | { |
| 542 | char *to = xs_dict_get(msg, "to"); | 475 | const xs_val *to = xs_dict_get(msg, "to"); |
| 543 | char *cc = xs_dict_get(msg, "cc"); | 476 | const xs_val *cc = xs_dict_get(msg, "cc"); |
| 544 | xs_set rcpts; | 477 | xs_set rcpts; |
| 545 | int n; | 478 | int n; |
| 546 | 479 | ||
| 547 | xs_set_init(&rcpts); | 480 | xs_set_init(&rcpts); |
| 548 | 481 | ||
| 549 | char *lists[] = { to, cc, NULL }; | 482 | const xs_list *lists[] = { to, cc, NULL }; |
| 550 | for (n = 0; lists[n]; n++) { | 483 | for (n = 0; lists[n]; n++) { |
| 551 | char *l = lists[n]; | 484 | xs_list *l = (xs_list *)lists[n]; |
| 552 | char *v; | 485 | char *v; |
| 553 | xs *tl = NULL; | 486 | xs *tl = NULL; |
| 554 | 487 | ||
| @@ -671,13 +604,13 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 671 | 604 | ||
| 672 | /* if it's a Follow, it must be explicitly for us */ | 605 | /* if it's a Follow, it must be explicitly for us */ |
| 673 | if (xs_match(type, "Follow")) { | 606 | if (xs_match(type, "Follow")) { |
| 674 | char *object = xs_dict_get(c_msg, "object"); | 607 | const char *object = xs_dict_get(c_msg, "object"); |
| 675 | return !xs_is_null(object) && strcmp(snac->actor, object) == 0; | 608 | return !xs_is_null(object) && strcmp(snac->actor, object) == 0; |
| 676 | } | 609 | } |
| 677 | 610 | ||
| 678 | /* only accept Ping directed to us */ | 611 | /* only accept Ping directed to us */ |
| 679 | if (xs_match(type, "Ping")) { | 612 | if (xs_match(type, "Ping")) { |
| 680 | char *dest = xs_dict_get(c_msg, "to"); | 613 | const char *dest = xs_dict_get(c_msg, "to"); |
| 681 | return !xs_is_null(dest) && strcmp(snac->actor, dest) == 0; | 614 | return !xs_is_null(dest) && strcmp(snac->actor, dest) == 0; |
| 682 | } | 615 | } |
| 683 | 616 | ||
| @@ -692,7 +625,7 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 692 | if (pub_msg && following_check(snac, actor)) | 625 | if (pub_msg && following_check(snac, actor)) |
| 693 | return 1; | 626 | return 1; |
| 694 | 627 | ||
| 695 | xs_dict *msg = xs_dict_get(c_msg, "object"); | 628 | const xs_dict *msg = xs_dict_get(c_msg, "object"); |
| 696 | xs *rcpts = recipient_list(snac, msg, 0); | 629 | xs *rcpts = recipient_list(snac, msg, 0); |
| 697 | xs_list *p = rcpts; | 630 | xs_list *p = rcpts; |
| 698 | xs_str *v; | 631 | xs_str *v; |
| @@ -704,8 +637,9 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 704 | xs *actor_obj = NULL; | 637 | xs *actor_obj = NULL; |
| 705 | 638 | ||
| 706 | if (valid_status(object_get(actor, &actor_obj))) { | 639 | if (valid_status(object_get(actor, &actor_obj))) { |
| 707 | if ((v = xs_dict_get(actor_obj, "followers"))) | 640 | const xs_val *fw = xs_dict_get(actor_obj, "followers"); |
| 708 | actor_followers = xs_dup(v); | 641 | if (fw) |
| 642 | actor_followers = xs_dup(fw); | ||
| 709 | } | 643 | } |
| 710 | } | 644 | } |
| 711 | 645 | ||
| @@ -728,13 +662,13 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 728 | } | 662 | } |
| 729 | 663 | ||
| 730 | /* accept if it's by someone we follow */ | 664 | /* accept if it's by someone we follow */ |
| 731 | char *atto = get_atto(msg); | 665 | const char *atto = get_atto(msg); |
| 732 | 666 | ||
| 733 | if (pub_msg && !xs_is_null(atto) && following_check(snac, atto)) | 667 | if (pub_msg && !xs_is_null(atto) && following_check(snac, atto)) |
| 734 | return 3; | 668 | return 3; |
| 735 | 669 | ||
| 736 | /* is this message a reply to another? */ | 670 | /* is this message a reply to another? */ |
| 737 | char *irt = xs_dict_get(msg, "inReplyTo"); | 671 | const char *irt = xs_dict_get(msg, "inReplyTo"); |
| 738 | if (!xs_is_null(irt)) { | 672 | if (!xs_is_null(irt)) { |
| 739 | xs *r_msg = NULL; | 673 | xs *r_msg = NULL; |
| 740 | 674 | ||
| @@ -987,8 +921,8 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, | |||
| 987 | 921 | ||
| 988 | /* telegram */ | 922 | /* telegram */ |
| 989 | 923 | ||
| 990 | char *bot = xs_dict_get(snac->config, "telegram_bot"); | 924 | const char *bot = xs_dict_get(snac->config, "telegram_bot"); |
| 991 | char *chat_id = xs_dict_get(snac->config, "telegram_chat_id"); | 925 | const char *chat_id = xs_dict_get(snac->config, "telegram_chat_id"); |
| 992 | 926 | ||
| 993 | if (!xs_is_null(bot) && !xs_is_null(chat_id) && *bot && *chat_id) | 927 | if (!xs_is_null(bot) && !xs_is_null(chat_id) && *bot && *chat_id) |
| 994 | enqueue_telegram(body, bot, chat_id); | 928 | enqueue_telegram(body, bot, chat_id); |
| @@ -1001,8 +935,8 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, | |||
| 1001 | objid = actor; | 935 | objid = actor; |
| 1002 | 936 | ||
| 1003 | /* ntfy */ | 937 | /* ntfy */ |
| 1004 | char *ntfy_server = xs_dict_get(snac->config, "ntfy_server"); | 938 | const char *ntfy_server = xs_dict_get(snac->config, "ntfy_server"); |
| 1005 | char *ntfy_token = xs_dict_get(snac->config, "ntfy_token"); | 939 | const char *ntfy_token = xs_dict_get(snac->config, "ntfy_token"); |
| 1006 | 940 | ||
| 1007 | if (!xs_is_null(ntfy_server) && *ntfy_server) | 941 | if (!xs_is_null(ntfy_server) && *ntfy_server) |
| 1008 | enqueue_ntfy(body, ntfy_server, ntfy_token); | 942 | enqueue_ntfy(body, ntfy_server, ntfy_token); |
| @@ -1088,7 +1022,7 @@ xs_dict *msg_base(snac *snac, const char *type, const char *id, | |||
| 1088 | } | 1022 | } |
| 1089 | 1023 | ||
| 1090 | 1024 | ||
| 1091 | xs_dict *msg_collection(snac *snac, char *id) | 1025 | xs_dict *msg_collection(snac *snac, const char *id) |
| 1092 | /* creates an empty OrderedCollection message */ | 1026 | /* creates an empty OrderedCollection message */ |
| 1093 | { | 1027 | { |
| 1094 | xs_dict *msg = msg_base(snac, "OrderedCollection", id, NULL, NULL, NULL); | 1028 | xs_dict *msg = msg_base(snac, "OrderedCollection", id, NULL, NULL, NULL); |
| @@ -1102,7 +1036,7 @@ xs_dict *msg_collection(snac *snac, char *id) | |||
| 1102 | } | 1036 | } |
| 1103 | 1037 | ||
| 1104 | 1038 | ||
| 1105 | xs_dict *msg_accept(snac *snac, char *object, char *to) | 1039 | xs_dict *msg_accept(snac *snac, const xs_val *object, const char *to) |
| 1106 | /* creates an Accept message (as a response to a Follow) */ | 1040 | /* creates an Accept message (as a response to a Follow) */ |
| 1107 | { | 1041 | { |
| 1108 | xs_dict *msg = msg_base(snac, "Accept", "@dummy", snac->actor, NULL, object); | 1042 | xs_dict *msg = msg_base(snac, "Accept", "@dummy", snac->actor, NULL, object); |
| @@ -1113,12 +1047,12 @@ xs_dict *msg_accept(snac *snac, char *object, char *to) | |||
| 1113 | } | 1047 | } |
| 1114 | 1048 | ||
| 1115 | 1049 | ||
| 1116 | xs_dict *msg_update(snac *snac, xs_dict *object) | 1050 | xs_dict *msg_update(snac *snac, const xs_dict *object) |
| 1117 | /* creates an Update message */ | 1051 | /* creates an Update message */ |
| 1118 | { | 1052 | { |
| 1119 | xs_dict *msg = msg_base(snac, "Update", "@object", snac->actor, "@now", object); | 1053 | xs_dict *msg = msg_base(snac, "Update", "@object", snac->actor, "@now", object); |
| 1120 | 1054 | ||
| 1121 | char *type = xs_dict_get(object, "type"); | 1055 | const char *type = xs_dict_get(object, "type"); |
| 1122 | 1056 | ||
| 1123 | if (strcmp(type, "Note") == 0) { | 1057 | if (strcmp(type, "Note") == 0) { |
| 1124 | msg = xs_dict_append(msg, "to", xs_dict_get(object, "to")); | 1058 | msg = xs_dict_append(msg, "to", xs_dict_get(object, "to")); |
| @@ -1141,7 +1075,7 @@ xs_dict *msg_update(snac *snac, xs_dict *object) | |||
| 1141 | } | 1075 | } |
| 1142 | 1076 | ||
| 1143 | 1077 | ||
| 1144 | xs_dict *msg_admiration(snac *snac, char *object, char *type) | 1078 | xs_dict *msg_admiration(snac *snac, const char *object, const char *type) |
| 1145 | /* creates a Like or Announce message */ | 1079 | /* creates a Like or Announce message */ |
| 1146 | { | 1080 | { |
| 1147 | xs *a_msg = NULL; | 1081 | xs *a_msg = NULL; |
| @@ -1172,7 +1106,7 @@ xs_dict *msg_admiration(snac *snac, char *object, char *type) | |||
| 1172 | } | 1106 | } |
| 1173 | 1107 | ||
| 1174 | 1108 | ||
| 1175 | xs_dict *msg_repulsion(snac *user, char *id, char *type) | 1109 | xs_dict *msg_repulsion(snac *user, const char *id, const char *type) |
| 1176 | /* creates an Undo + admiration message */ | 1110 | /* creates an Undo + admiration message */ |
| 1177 | { | 1111 | { |
| 1178 | xs *a_msg = NULL; | 1112 | xs *a_msg = NULL; |
| @@ -1210,7 +1144,7 @@ xs_dict *msg_actor(snac *snac) | |||
| 1210 | xs *kid = NULL; | 1144 | xs *kid = NULL; |
| 1211 | xs *f_bio = NULL; | 1145 | xs *f_bio = NULL; |
| 1212 | xs_dict *msg = msg_base(snac, "Person", snac->actor, NULL, NULL, NULL); | 1146 | xs_dict *msg = msg_base(snac, "Person", snac->actor, NULL, NULL, NULL); |
| 1213 | char *p; | 1147 | const char *p; |
| 1214 | int n; | 1148 | int n; |
| 1215 | 1149 | ||
| 1216 | /* change the @context (is this really necessary?) */ | 1150 | /* change the @context (is this really necessary?) */ |
| @@ -1268,7 +1202,7 @@ xs_dict *msg_actor(snac *snac) | |||
| 1268 | } | 1202 | } |
| 1269 | 1203 | ||
| 1270 | /* add the metadata as attachments of PropertyValue */ | 1204 | /* add the metadata as attachments of PropertyValue */ |
| 1271 | xs_dict *metadata = xs_dict_get(snac->config, "metadata"); | 1205 | const xs_dict *metadata = xs_dict_get(snac->config, "metadata"); |
| 1272 | if (xs_type(metadata) == XSTYPE_DICT) { | 1206 | if (xs_type(metadata) == XSTYPE_DICT) { |
| 1273 | xs *attach = xs_list_new(); | 1207 | xs *attach = xs_list_new(); |
| 1274 | xs_str *k; | 1208 | xs_str *k; |
| @@ -1314,7 +1248,7 @@ xs_dict *msg_create(snac *snac, const xs_dict *object) | |||
| 1314 | /* creates a 'Create' message */ | 1248 | /* creates a 'Create' message */ |
| 1315 | { | 1249 | { |
| 1316 | xs_dict *msg = msg_base(snac, "Create", "@wrapper", snac->actor, NULL, object); | 1250 | xs_dict *msg = msg_base(snac, "Create", "@wrapper", snac->actor, NULL, object); |
| 1317 | xs_val *v; | 1251 | const xs_val *v; |
| 1318 | 1252 | ||
| 1319 | if ((v = get_atto(object))) | 1253 | if ((v = get_atto(object))) |
| 1320 | msg = xs_dict_append(msg, "attributedTo", v); | 1254 | msg = xs_dict_append(msg, "attributedTo", v); |
| @@ -1331,7 +1265,7 @@ xs_dict *msg_create(snac *snac, const xs_dict *object) | |||
| 1331 | } | 1265 | } |
| 1332 | 1266 | ||
| 1333 | 1267 | ||
| 1334 | xs_dict *msg_undo(snac *snac, char *object) | 1268 | xs_dict *msg_undo(snac *snac, const xs_val *object) |
| 1335 | /* creates an 'Undo' message */ | 1269 | /* creates an 'Undo' message */ |
| 1336 | { | 1270 | { |
| 1337 | xs_dict *msg = msg_base(snac, "Undo", "@object", snac->actor, "@now", object); | 1271 | xs_dict *msg = msg_base(snac, "Undo", "@object", snac->actor, "@now", object); |
| @@ -1344,7 +1278,7 @@ xs_dict *msg_undo(snac *snac, char *object) | |||
| 1344 | } | 1278 | } |
| 1345 | 1279 | ||
| 1346 | 1280 | ||
| 1347 | xs_dict *msg_delete(snac *snac, char *id) | 1281 | xs_dict *msg_delete(snac *snac, const char *id) |
| 1348 | /* creates a 'Delete' + 'Tombstone' for a local entry */ | 1282 | /* creates a 'Delete' + 'Tombstone' for a local entry */ |
| 1349 | { | 1283 | { |
| 1350 | xs *tomb = xs_dict_new(); | 1284 | xs *tomb = xs_dict_new(); |
| @@ -1386,7 +1320,7 @@ xs_dict *msg_follow(snac *snac, const char *q) | |||
| 1386 | 1320 | ||
| 1387 | if (valid_status(status)) { | 1321 | if (valid_status(status)) { |
| 1388 | /* check if the actor is an alias */ | 1322 | /* check if the actor is an alias */ |
| 1389 | char *r_actor = xs_dict_get(actor_o, "id"); | 1323 | const char *r_actor = xs_dict_get(actor_o, "id"); |
| 1390 | 1324 | ||
| 1391 | if (r_actor && strcmp(actor, r_actor) != 0) { | 1325 | if (r_actor && strcmp(actor, r_actor) != 0) { |
| 1392 | snac_log(snac, xs_fmt("actor to follow is an alias %s -> %s", actor, r_actor)); | 1326 | snac_log(snac, xs_fmt("actor to follow is an alias %s -> %s", actor, r_actor)); |
| @@ -1402,7 +1336,7 @@ xs_dict *msg_follow(snac *snac, const char *q) | |||
| 1402 | 1336 | ||
| 1403 | 1337 | ||
| 1404 | xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, | 1338 | xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, |
| 1405 | xs_str *in_reply_to, xs_list *attach, int priv) | 1339 | const xs_str *in_reply_to, const xs_list *attach, int priv) |
| 1406 | /* creates a 'Note' message */ | 1340 | /* creates a 'Note' message */ |
| 1407 | { | 1341 | { |
| 1408 | xs *ntid = tid(0); | 1342 | xs *ntid = tid(0); |
| @@ -1442,7 +1376,7 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, | |||
| 1442 | 1376 | ||
| 1443 | if (valid_status(object_get(in_reply_to, &p_msg))) { | 1377 | if (valid_status(object_get(in_reply_to, &p_msg))) { |
| 1444 | /* add this author as recipient */ | 1378 | /* add this author as recipient */ |
| 1445 | char *a, *v; | 1379 | const char *a, *v; |
| 1446 | 1380 | ||
| 1447 | if ((a = get_atto(p_msg)) && xs_list_in(to, a) == -1) | 1381 | if ((a = get_atto(p_msg)) && xs_list_in(to, a) == -1) |
| 1448 | to = xs_list_append(to, a); | 1382 | to = xs_list_append(to, a); |
| @@ -1453,7 +1387,7 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, | |||
| 1453 | xs *actor_o = NULL; | 1387 | xs *actor_o = NULL; |
| 1454 | 1388 | ||
| 1455 | if (xs_list_len(l) > 3 && valid_status(object_get(a, &actor_o))) { | 1389 | if (xs_list_len(l) > 3 && valid_status(object_get(a, &actor_o))) { |
| 1456 | char *uname = xs_dict_get(actor_o, "preferredUsername"); | 1390 | const char *uname = xs_dict_get(actor_o, "preferredUsername"); |
| 1457 | 1391 | ||
| 1458 | if (!xs_is_null(uname) && *uname) { | 1392 | if (!xs_is_null(uname) && *uname) { |
| 1459 | xs *handle = xs_fmt("@%s@%s", uname, xs_list_get(l, 2)); | 1393 | xs *handle = xs_fmt("@%s@%s", uname, xs_list_get(l, 2)); |
| @@ -1492,7 +1426,8 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, | |||
| 1492 | 1426 | ||
| 1493 | /* create the attachment list, if there are any */ | 1427 | /* create the attachment list, if there are any */ |
| 1494 | if (!xs_is_null(attach)) { | 1428 | if (!xs_is_null(attach)) { |
| 1495 | while (xs_list_iter(&attach, &v)) { | 1429 | int c = 0; |
| 1430 | while (xs_list_next(attach, &v, &c)) { | ||
| 1496 | xs *d = xs_dict_new(); | 1431 | xs *d = xs_dict_new(); |
| 1497 | const char *url = xs_list_get(v, 0); | 1432 | const char *url = xs_list_get(v, 0); |
| 1498 | const char *alt = xs_list_get(v, 1); | 1433 | const char *alt = xs_list_get(v, 1); |
| @@ -1515,7 +1450,7 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts, | |||
| 1515 | p = tag; | 1450 | p = tag; |
| 1516 | while (xs_list_iter(&p, &v)) { | 1451 | while (xs_list_iter(&p, &v)) { |
| 1517 | if (xs_type(v) == XSTYPE_DICT) { | 1452 | if (xs_type(v) == XSTYPE_DICT) { |
| 1518 | char *t; | 1453 | const char *t; |
| 1519 | 1454 | ||
| 1520 | if (!xs_is_null(t = xs_dict_get(v, "type")) && strcmp(t, "Mention") == 0) { | 1455 | if (!xs_is_null(t = xs_dict_get(v, "type")) && strcmp(t, "Mention") == 0) { |
| 1521 | if (!xs_is_null(t = xs_dict_get(v, "href"))) | 1456 | if (!xs_is_null(t = xs_dict_get(v, "href"))) |
| @@ -1639,7 +1574,7 @@ int update_question(snac *user, const char *id) | |||
| 1639 | xs *msg = NULL; | 1574 | xs *msg = NULL; |
| 1640 | xs *rcnt = xs_dict_new(); | 1575 | xs *rcnt = xs_dict_new(); |
| 1641 | xs *lopts = xs_list_new(); | 1576 | xs *lopts = xs_list_new(); |
| 1642 | xs_list *opts; | 1577 | const xs_list *opts; |
| 1643 | xs_list *p; | 1578 | xs_list *p; |
| 1644 | xs_val *v; | 1579 | xs_val *v; |
| 1645 | 1580 | ||
| @@ -1657,8 +1592,8 @@ int update_question(snac *user, const char *id) | |||
| 1657 | return -3; | 1592 | return -3; |
| 1658 | 1593 | ||
| 1659 | /* fill the initial count */ | 1594 | /* fill the initial count */ |
| 1660 | p = opts; | 1595 | int c = 0; |
| 1661 | while (xs_list_iter(&p, &v)) { | 1596 | while (xs_list_next(opts, &v, &c)) { |
| 1662 | const char *name = xs_dict_get(v, "name"); | 1597 | const char *name = xs_dict_get(v, "name"); |
| 1663 | if (name) { | 1598 | if (name) { |
| 1664 | lopts = xs_list_append(lopts, name); | 1599 | lopts = xs_list_append(lopts, name); |
| @@ -1764,13 +1699,13 @@ int update_question(snac *user, const char *id) | |||
| 1764 | 1699 | ||
| 1765 | /** queues **/ | 1700 | /** queues **/ |
| 1766 | 1701 | ||
| 1767 | int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | 1702 | int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) |
| 1768 | /* processes an ActivityPub message from the input queue */ | 1703 | /* processes an ActivityPub message from the input queue */ |
| 1769 | /* return values: -1, fatal error; 0, transient error, retry; | 1704 | /* return values: -1, fatal error; 0, transient error, retry; |
| 1770 | 1, processed and done; 2, propagate to users (only when no user is set) */ | 1705 | 1, processed and done; 2, propagate to users (only when no user is set) */ |
| 1771 | { | 1706 | { |
| 1772 | char *actor = xs_dict_get(msg, "actor"); | 1707 | const char *actor = xs_dict_get(msg, "actor"); |
| 1773 | char *type = xs_dict_get(msg, "type"); | 1708 | const char *type = xs_dict_get(msg, "type"); |
| 1774 | xs *actor_o = NULL; | 1709 | xs *actor_o = NULL; |
| 1775 | int a_status; | 1710 | int a_status; |
| 1776 | int do_notify = 0; | 1711 | int do_notify = 0; |
| @@ -1790,7 +1725,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | |||
| 1790 | return -1; | 1725 | return -1; |
| 1791 | } | 1726 | } |
| 1792 | 1727 | ||
| 1793 | char *object, *utype; | 1728 | const char *object, *utype; |
| 1794 | 1729 | ||
| 1795 | object = xs_dict_get(msg, "object"); | 1730 | object = xs_dict_get(msg, "object"); |
| 1796 | if (object != NULL && xs_type(object) == XSTYPE_DICT) | 1731 | if (object != NULL && xs_type(object) == XSTYPE_DICT) |
| @@ -1813,7 +1748,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | |||
| 1813 | } | 1748 | } |
| 1814 | 1749 | ||
| 1815 | /* also discard if the object to be deleted is not here */ | 1750 | /* also discard if the object to be deleted is not here */ |
| 1816 | char *obj_id = object; | 1751 | const char *obj_id = object; |
| 1817 | if (xs_type(obj_id) == XSTYPE_DICT) | 1752 | if (xs_type(obj_id) == XSTYPE_DICT) |
| 1818 | obj_id = xs_dict_get(obj_id, "id"); | 1753 | obj_id = xs_dict_get(obj_id, "id"); |
| 1819 | 1754 | ||
| @@ -1885,7 +1820,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | |||
| 1885 | int min_account_age = xs_number_get(xs_dict_get(srv_config, "min_account_age")); | 1820 | int min_account_age = xs_number_get(xs_dict_get(srv_config, "min_account_age")); |
| 1886 | 1821 | ||
| 1887 | if (min_account_age > 0) { | 1822 | if (min_account_age > 0) { |
| 1888 | char *actor_date = xs_dict_get(actor_o, "published"); | 1823 | const char *actor_date = xs_dict_get(actor_o, "published"); |
| 1889 | if (!xs_is_null(actor_date)) { | 1824 | if (!xs_is_null(actor_date)) { |
| 1890 | time_t actor_t = xs_parse_iso_date(actor_date, 0); | 1825 | time_t actor_t = xs_parse_iso_date(actor_date, 0); |
| 1891 | 1826 | ||
| @@ -1945,7 +1880,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | |||
| 1945 | } | 1880 | } |
| 1946 | else | 1881 | else |
| 1947 | if (strcmp(type, "Undo") == 0) { /** **/ | 1882 | if (strcmp(type, "Undo") == 0) { /** **/ |
| 1948 | char *id = xs_dict_get(object, "object"); | 1883 | const char *id = xs_dict_get(object, "object"); |
| 1949 | 1884 | ||
| 1950 | if (xs_type(object) != XSTYPE_DICT) | 1885 | if (xs_type(object) != XSTYPE_DICT) |
| 1951 | utype = "Follow"; | 1886 | utype = "Follow"; |
| @@ -1990,9 +1925,9 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | |||
| 1990 | } | 1925 | } |
| 1991 | 1926 | ||
| 1992 | if (xs_match(utype, "Note|Article")) { /** **/ | 1927 | if (xs_match(utype, "Note|Article")) { /** **/ |
| 1993 | char *id = xs_dict_get(object, "id"); | 1928 | const char *id = xs_dict_get(object, "id"); |
| 1994 | char *in_reply_to = xs_dict_get(object, "inReplyTo"); | 1929 | const char *in_reply_to = xs_dict_get(object, "inReplyTo"); |
| 1995 | char *atto = get_atto(object); | 1930 | const char *atto = get_atto(object); |
| 1996 | xs *wrk = NULL; | 1931 | xs *wrk = NULL; |
| 1997 | 1932 | ||
| 1998 | if (xs_is_null(id)) | 1933 | if (xs_is_null(id)) |
| @@ -2029,14 +1964,14 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | |||
| 2029 | } | 1964 | } |
| 2030 | else | 1965 | else |
| 2031 | if (strcmp(utype, "Question") == 0) { /** **/ | 1966 | if (strcmp(utype, "Question") == 0) { /** **/ |
| 2032 | char *id = xs_dict_get(object, "id"); | 1967 | const char *id = xs_dict_get(object, "id"); |
| 2033 | 1968 | ||
| 2034 | if (timeline_add(snac, id, object)) | 1969 | if (timeline_add(snac, id, object)) |
| 2035 | snac_log(snac, xs_fmt("new 'Question' %s %s", actor, id)); | 1970 | snac_log(snac, xs_fmt("new 'Question' %s %s", actor, id)); |
| 2036 | } | 1971 | } |
| 2037 | else | 1972 | else |
| 2038 | if (strcmp(utype, "Video") == 0) { /** **/ | 1973 | if (strcmp(utype, "Video") == 0) { /** **/ |
| 2039 | char *id = xs_dict_get(object, "id"); | 1974 | const char *id = xs_dict_get(object, "id"); |
| 2040 | 1975 | ||
| 2041 | if (timeline_add(snac, id, object)) | 1976 | if (timeline_add(snac, id, object)) |
| 2042 | snac_log(snac, xs_fmt("new 'Video' %s %s", actor, id)); | 1977 | snac_log(snac, xs_fmt("new 'Video' %s %s", actor, id)); |
| @@ -2212,7 +2147,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req) | |||
| 2212 | } | 2147 | } |
| 2213 | 2148 | ||
| 2214 | 2149 | ||
| 2215 | int send_email(char *msg) | 2150 | int send_email(const char *msg) |
| 2216 | /* invoke sendmail with email headers and body in msg */ | 2151 | /* invoke sendmail with email headers and body in msg */ |
| 2217 | { | 2152 | { |
| 2218 | FILE *f; | 2153 | FILE *f; |
| @@ -2244,14 +2179,14 @@ int send_email(char *msg) | |||
| 2244 | void process_user_queue_item(snac *snac, xs_dict *q_item) | 2179 | void process_user_queue_item(snac *snac, xs_dict *q_item) |
| 2245 | /* processes an item from the user queue */ | 2180 | /* processes an item from the user queue */ |
| 2246 | { | 2181 | { |
| 2247 | char *type; | 2182 | const char *type; |
| 2248 | int queue_retry_max = xs_number_get(xs_dict_get(srv_config, "queue_retry_max")); | 2183 | int queue_retry_max = xs_number_get(xs_dict_get(srv_config, "queue_retry_max")); |
| 2249 | 2184 | ||
| 2250 | if ((type = xs_dict_get(q_item, "type")) == NULL) | 2185 | if ((type = xs_dict_get(q_item, "type")) == NULL) |
| 2251 | type = "output"; | 2186 | type = "output"; |
| 2252 | 2187 | ||
| 2253 | if (strcmp(type, "message") == 0) { | 2188 | if (strcmp(type, "message") == 0) { |
| 2254 | xs_dict *msg = xs_dict_get(q_item, "message"); | 2189 | const xs_dict *msg = xs_dict_get(q_item, "message"); |
| 2255 | xs *rcpts = recipient_list(snac, msg, 1); | 2190 | xs *rcpts = recipient_list(snac, msg, 1); |
| 2256 | xs_set inboxes; | 2191 | xs_set inboxes; |
| 2257 | xs_list *p; | 2192 | xs_list *p; |
| @@ -2292,8 +2227,8 @@ void process_user_queue_item(snac *snac, xs_dict *q_item) | |||
| 2292 | else | 2227 | else |
| 2293 | if (strcmp(type, "input") == 0) { | 2228 | if (strcmp(type, "input") == 0) { |
| 2294 | /* process the message */ | 2229 | /* process the message */ |
| 2295 | xs_dict *msg = xs_dict_get(q_item, "message"); | 2230 | const xs_dict *msg = xs_dict_get(q_item, "message"); |
| 2296 | xs_dict *req = xs_dict_get(q_item, "req"); | 2231 | const xs_dict *req = xs_dict_get(q_item, "req"); |
| 2297 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); | 2232 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); |
| 2298 | 2233 | ||
| 2299 | if (xs_is_null(msg)) | 2234 | if (xs_is_null(msg)) |
| @@ -2320,13 +2255,6 @@ void process_user_queue_item(snac *snac, xs_dict *q_item) | |||
| 2320 | update_question(snac, id); | 2255 | update_question(snac, id); |
| 2321 | } | 2256 | } |
| 2322 | else | 2257 | else |
| 2323 | if (strcmp(type, "request_replies") == 0) { | ||
| 2324 | const char *id = xs_dict_get(q_item, "message"); | ||
| 2325 | |||
| 2326 | if (!xs_is_null(id)) | ||
| 2327 | timeline_request_replies(snac, id); | ||
| 2328 | } | ||
| 2329 | else | ||
| 2330 | if (strcmp(type, "object_request") == 0) { | 2258 | if (strcmp(type, "object_request") == 0) { |
| 2331 | const char *id = xs_dict_get(q_item, "message"); | 2259 | const char *id = xs_dict_get(q_item, "message"); |
| 2332 | 2260 | ||
| @@ -2395,15 +2323,15 @@ int process_user_queue(snac *snac) | |||
| 2395 | void process_queue_item(xs_dict *q_item) | 2323 | void process_queue_item(xs_dict *q_item) |
| 2396 | /* processes an item from the global queue */ | 2324 | /* processes an item from the global queue */ |
| 2397 | { | 2325 | { |
| 2398 | char *type = xs_dict_get(q_item, "type"); | 2326 | const char *type = xs_dict_get(q_item, "type"); |
| 2399 | int queue_retry_max = xs_number_get(xs_dict_get(srv_config, "queue_retry_max")); | 2327 | int queue_retry_max = xs_number_get(xs_dict_get(srv_config, "queue_retry_max")); |
| 2400 | 2328 | ||
| 2401 | if (strcmp(type, "output") == 0) { | 2329 | if (strcmp(type, "output") == 0) { |
| 2402 | int status; | 2330 | int status; |
| 2403 | xs_str *inbox = xs_dict_get(q_item, "inbox"); | 2331 | const xs_str *inbox = xs_dict_get(q_item, "inbox"); |
| 2404 | xs_str *keyid = xs_dict_get(q_item, "keyid"); | 2332 | const xs_str *keyid = xs_dict_get(q_item, "keyid"); |
| 2405 | xs_str *seckey = xs_dict_get(q_item, "seckey"); | 2333 | const xs_str *seckey = xs_dict_get(q_item, "seckey"); |
| 2406 | xs_dict *msg = xs_dict_get(q_item, "message"); | 2334 | const xs_dict *msg = xs_dict_get(q_item, "message"); |
| 2407 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); | 2335 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); |
| 2408 | int p_status = xs_number_get(xs_dict_get(q_item, "p_status")); | 2336 | int p_status = xs_number_get(xs_dict_get(q_item, "p_status")); |
| 2409 | xs *payload = NULL; | 2337 | xs *payload = NULL; |
| @@ -2475,7 +2403,7 @@ void process_queue_item(xs_dict *q_item) | |||
| 2475 | else | 2403 | else |
| 2476 | if (strcmp(type, "email") == 0) { | 2404 | if (strcmp(type, "email") == 0) { |
| 2477 | /* send this email */ | 2405 | /* send this email */ |
| 2478 | xs_str *msg = xs_dict_get(q_item, "message"); | 2406 | const xs_str *msg = xs_dict_get(q_item, "message"); |
| 2479 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); | 2407 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); |
| 2480 | 2408 | ||
| 2481 | if (!send_email(msg)) | 2409 | if (!send_email(msg)) |
| @@ -2497,8 +2425,8 @@ void process_queue_item(xs_dict *q_item) | |||
| 2497 | else | 2425 | else |
| 2498 | if (strcmp(type, "telegram") == 0) { | 2426 | if (strcmp(type, "telegram") == 0) { |
| 2499 | /* send this via telegram */ | 2427 | /* send this via telegram */ |
| 2500 | char *bot = xs_dict_get(q_item, "bot"); | 2428 | const char *bot = xs_dict_get(q_item, "bot"); |
| 2501 | char *msg = xs_dict_get(q_item, "message"); | 2429 | const char *msg = xs_dict_get(q_item, "message"); |
| 2502 | xs *chat_id = xs_dup(xs_dict_get(q_item, "chat_id")); | 2430 | xs *chat_id = xs_dup(xs_dict_get(q_item, "chat_id")); |
| 2503 | int status = 0; | 2431 | int status = 0; |
| 2504 | 2432 | ||
| @@ -2521,9 +2449,9 @@ void process_queue_item(xs_dict *q_item) | |||
| 2521 | else | 2449 | else |
| 2522 | if (strcmp(type, "ntfy") == 0) { | 2450 | if (strcmp(type, "ntfy") == 0) { |
| 2523 | /* send this via ntfy */ | 2451 | /* send this via ntfy */ |
| 2524 | char *ntfy_server = xs_dict_get(q_item, "ntfy_server"); | 2452 | const char *ntfy_server = xs_dict_get(q_item, "ntfy_server"); |
| 2525 | char *msg = xs_dict_get(q_item, "message"); | 2453 | const char *msg = xs_dict_get(q_item, "message"); |
| 2526 | char *ntfy_token = xs_dict_get(q_item, "ntfy_token"); | 2454 | const char *ntfy_token = xs_dict_get(q_item, "ntfy_token"); |
| 2527 | int status = 0; | 2455 | int status = 0; |
| 2528 | 2456 | ||
| 2529 | xs *url = xs_fmt("%s", ntfy_server); | 2457 | xs *url = xs_fmt("%s", ntfy_server); |
| @@ -2552,8 +2480,8 @@ void process_queue_item(xs_dict *q_item) | |||
| 2552 | } | 2480 | } |
| 2553 | else | 2481 | else |
| 2554 | if (strcmp(type, "input") == 0) { | 2482 | if (strcmp(type, "input") == 0) { |
| 2555 | xs_dict *msg = xs_dict_get(q_item, "message"); | 2483 | const xs_dict *msg = xs_dict_get(q_item, "message"); |
| 2556 | xs_dict *req = xs_dict_get(q_item, "req"); | 2484 | const xs_dict *req = xs_dict_get(q_item, "req"); |
| 2557 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); | 2485 | int retries = xs_number_get(xs_dict_get(q_item, "retries")); |
| 2558 | 2486 | ||
| 2559 | /* do some instance-level checks */ | 2487 | /* do some instance-level checks */ |
| @@ -2572,7 +2500,7 @@ void process_queue_item(xs_dict *q_item) | |||
| 2572 | else | 2500 | else |
| 2573 | if (r == 2) { | 2501 | if (r == 2) { |
| 2574 | /* redistribute the input message to all users */ | 2502 | /* redistribute the input message to all users */ |
| 2575 | char *ntid = xs_dict_get(q_item, "ntid"); | 2503 | const char *ntid = xs_dict_get(q_item, "ntid"); |
| 2576 | xs *tmpfn = xs_fmt("%s/tmp/%s.json", srv_basedir, ntid); | 2504 | xs *tmpfn = xs_fmt("%s/tmp/%s.json", srv_basedir, ntid); |
| 2577 | FILE *f; | 2505 | FILE *f; |
| 2578 | 2506 | ||
| @@ -2647,7 +2575,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 2647 | char **body, int *b_size, char **ctype) | 2575 | char **body, int *b_size, char **ctype) |
| 2648 | { | 2576 | { |
| 2649 | int status = 200; | 2577 | int status = 200; |
| 2650 | char *accept = xs_dict_get(req, "accept"); | 2578 | const char *accept = xs_dict_get(req, "accept"); |
| 2651 | snac snac; | 2579 | snac snac; |
| 2652 | xs *msg = NULL; | 2580 | xs *msg = NULL; |
| 2653 | 2581 | ||
| @@ -2659,7 +2587,8 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 2659 | return 0; | 2587 | return 0; |
| 2660 | 2588 | ||
| 2661 | xs *l = xs_split_n(q_path, "/", 2); | 2589 | xs *l = xs_split_n(q_path, "/", 2); |
| 2662 | char *uid, *p_path; | 2590 | const char *uid; |
| 2591 | const char *p_path; | ||
| 2663 | 2592 | ||
| 2664 | uid = xs_list_get(l, 1); | 2593 | uid = xs_list_get(l, 1); |
| 2665 | if (!user_open(&snac, uid)) { | 2594 | if (!user_open(&snac, uid)) { |
| @@ -2677,7 +2606,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 2677 | msg = msg_actor(&snac); | 2606 | msg = msg_actor(&snac); |
| 2678 | *ctype = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""; | 2607 | *ctype = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""; |
| 2679 | 2608 | ||
| 2680 | char *ua = xs_dict_get(req, "user-agent"); | 2609 | const char *ua = xs_dict_get(req, "user-agent"); |
| 2681 | 2610 | ||
| 2682 | snac_debug(&snac, 0, xs_fmt("serving actor [%s]", ua ? ua : "No UA")); | 2611 | snac_debug(&snac, 0, xs_fmt("serving actor [%s]", ua ? ua : "No UA")); |
| 2683 | } | 2612 | } |
| @@ -2694,8 +2623,8 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 2694 | xs *i = NULL; | 2623 | xs *i = NULL; |
| 2695 | 2624 | ||
| 2696 | if (valid_status(object_get_by_md5(v, &i))) { | 2625 | if (valid_status(object_get_by_md5(v, &i))) { |
| 2697 | char *type = xs_dict_get(i, "type"); | 2626 | const char *type = xs_dict_get(i, "type"); |
| 2698 | char *id = xs_dict_get(i, "id"); | 2627 | const char *id = xs_dict_get(i, "id"); |
| 2699 | 2628 | ||
| 2700 | if (type && id && strcmp(type, "Note") == 0 && xs_startswith(id, snac.actor)) { | 2629 | if (type && id && strcmp(type, "Note") == 0 && xs_startswith(id, snac.actor)) { |
| 2701 | xs *c_msg = msg_create(&snac, i); | 2630 | xs *c_msg = msg_create(&snac, i); |
| @@ -2748,9 +2677,9 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path, | |||
| 2748 | (void)b_size; | 2677 | (void)b_size; |
| 2749 | 2678 | ||
| 2750 | int status = 202; /* accepted */ | 2679 | int status = 202; /* accepted */ |
| 2751 | char *i_ctype = xs_dict_get(req, "content-type"); | 2680 | const char *i_ctype = xs_dict_get(req, "content-type"); |
| 2752 | snac snac; | 2681 | snac snac; |
| 2753 | char *v; | 2682 | const char *v; |
| 2754 | 2683 | ||
| 2755 | if (i_ctype == NULL) { | 2684 | if (i_ctype == NULL) { |
| 2756 | *body = xs_str_new("no content-type"); | 2685 | *body = xs_str_new("no content-type"); |