summaryrefslogtreecommitdiff
path: root/httpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'httpd.c')
-rw-r--r--httpd.c120
1 files changed, 106 insertions, 14 deletions
diff --git a/httpd.c b/httpd.c
index 6f7d69b..d01eb9c 100644
--- a/httpd.c
+++ b/httpd.c
@@ -12,6 +12,7 @@
12#include "xs_openssl.h" 12#include "xs_openssl.h"
13#include "xs_fcgi.h" 13#include "xs_fcgi.h"
14#include "xs_html.h" 14#include "xs_html.h"
15#include "xs_webmention.h"
15 16
16#include "snac.h" 17#include "snac.h"
17 18
@@ -65,7 +66,9 @@ const char *nodeinfo_2_0_template = ""
65 "\"services\":{\"outbound\":[],\"inbound\":[]}," 66 "\"services\":{\"outbound\":[],\"inbound\":[]},"
66 "\"usage\":{\"users\":{\"total\":%d,\"activeMonth\":%d,\"activeHalfyear\":%d}," 67 "\"usage\":{\"users\":{\"total\":%d,\"activeMonth\":%d,\"activeHalfyear\":%d},"
67 "\"localPosts\":%d}," 68 "\"localPosts\":%d},"
68 "\"openRegistrations\":false,\"metadata\":{}}"; 69 "\"openRegistrations\":false,\"metadata\":{"
70 "\"nodeDescription\":\"%s\",\"nodeName\":\"%s\""
71 "}}";
69 72
70xs_str *nodeinfo_2_0(void) 73xs_str *nodeinfo_2_0(void)
71/* builds a nodeinfo json object */ 74/* builds a nodeinfo json object */
@@ -98,7 +101,10 @@ xs_str *nodeinfo_2_0(void)
98 n_posts += index_len(pidxfn); 101 n_posts += index_len(pidxfn);
99 } 102 }
100 103
101 return xs_fmt(nodeinfo_2_0_template, n_utotal, n_umonth, n_uhyear, n_posts); 104 const char *name = xs_dict_get_def(srv_config, "title", "");
105 const char *desc = xs_dict_get_def(srv_config, "short_description", "");
106
107 return xs_fmt(nodeinfo_2_0_template, n_utotal, n_umonth, n_uhyear, n_posts, desc, name);
102} 108}
103 109
104 110
@@ -244,7 +250,7 @@ int server_get_handler(xs_dict *req, const char *q_path,
244 if (!xs_is_null(accept) && strcmp(accept, "application/rss+xml") == 0) { 250 if (!xs_is_null(accept) && strcmp(accept, "application/rss+xml") == 0) {
245 xs *link = xs_fmt("%s/?t=%s", srv_baseurl, t); 251 xs *link = xs_fmt("%s/?t=%s", srv_baseurl, t);
246 252
247 *body = timeline_to_rss(NULL, tl, link, link, link); 253 *body = rss_from_timeline(NULL, tl, link, link, link);
248 *ctype = "application/rss+xml; charset=utf-8"; 254 *ctype = "application/rss+xml; charset=utf-8";
249 } 255 }
250 else { 256 else {
@@ -373,6 +379,68 @@ int server_get_handler(xs_dict *req, const char *q_path,
373} 379}
374 380
375 381
382int server_post_handler(const xs_dict *req, const char *q_path,
383 char *payload, int p_size,
384 char **body, int *b_size, char **ctype)
385{
386 int status = 0;
387
388 (void)payload;
389 (void)p_size;
390 (void)body;
391 (void)b_size;
392 (void)ctype;
393
394 if (strcmp(q_path, "/webmention-hook") == 0) {
395 status = HTTP_STATUS_BAD_REQUEST;
396
397 const xs_dict *p_vars = xs_dict_get(req, "p_vars");
398
399 if (!xs_is_dict(p_vars))
400 return status;
401
402 const char *source = xs_dict_get(p_vars, "source");
403 const char *target = xs_dict_get(p_vars, "target");
404
405 if (!xs_is_string(source) || !xs_is_string(target)) {
406 srv_debug(1, xs_fmt("webmention-hook bad source or target"));
407 return status;
408 }
409
410 if (!xs_startswith(target, srv_baseurl)) {
411 srv_debug(1, xs_fmt("webmention-hook unknown target %s", target));
412 return status;
413 }
414
415 /* get the user */
416 xs *s1 = xs_replace(target, srv_baseurl, "");
417
418 xs *l1 = xs_split(s1, "/");
419 const char *uid = xs_list_get(l1, 1);
420 snac user;
421
422 if (!xs_is_string(uid) || !user_open(&user, uid)) {
423 srv_debug(1, xs_fmt("webmention-hook cannot find user for %s", target));
424 return status;
425 }
426
427 int r = xs_webmention_hook(source, target, USER_AGENT);
428
429 if (r > 0) {
430 notify_add(&user, "Webmention", NULL, source, target, xs_stock(XSTYPE_DICT));
431 timeline_touch(&user);
432 }
433
434 srv_log(xs_fmt("webmention-hook source=%s target=%s %d", source, target, r));
435
436 user_free(&user);
437 status = HTTP_STATUS_OK;
438 }
439
440 return status;
441}
442
443
376void httpd_connection(FILE *f) 444void httpd_connection(FILE *f)
377/* the connection processor */ 445/* the connection processor */
378{ 446{
@@ -444,6 +512,10 @@ void httpd_connection(FILE *f)
444 else 512 else
445 if (strcmp(method, "POST") == 0) { 513 if (strcmp(method, "POST") == 0) {
446 514
515 if (status == 0)
516 status = server_post_handler(req, q_path,
517 payload, p_size, &body, &b_size, &ctype);
518
447#ifndef NO_MASTODON_API 519#ifndef NO_MASTODON_API
448 if (status == 0) 520 if (status == 0)
449 status = oauth_post_handler(req, q_path, 521 status = oauth_post_handler(req, q_path,
@@ -705,34 +777,36 @@ static pthread_cond_t sleep_cond;
705static void *background_thread(void *arg) 777static void *background_thread(void *arg)
706/* background thread (queue management and other things) */ 778/* background thread (queue management and other things) */
707{ 779{
708 time_t purge_time; 780 time_t t, purge_time, rss_time;
709 781
710 (void)arg; 782 (void)arg;
711 783
784 t = time(NULL);
785
712 /* first purge time */ 786 /* first purge time */
713 purge_time = time(NULL) + 10 * 60; 787 purge_time = t + 10 * 60;
788
789 /* first RSS polling time */
790 rss_time = t + 15 * 60;
714 791
715 srv_log(xs_fmt("background thread started")); 792 srv_log(xs_fmt("background thread started"));
716 793
717 while (p_state->srv_running) { 794 while (p_state->srv_running) {
718 time_t t;
719 int cnt = 0; 795 int cnt = 0;
720 796
721 p_state->th_state[0] = THST_QUEUE; 797 p_state->th_state[0] = THST_QUEUE;
722 798
723 { 799 {
724 xs *list = user_list(); 800 xs *list = user_list();
725 char *p;
726 const char *uid; 801 const char *uid;
727 802
728 /* process queues for all users */ 803 /* process queues for all users */
729 p = list; 804 xs_list_foreach(list, uid) {
730 while (xs_list_iter(&p, &uid)) { 805 snac user;
731 snac snac;
732 806
733 if (user_open(&snac, uid)) { 807 if (user_open(&user, uid)) {
734 cnt += process_user_queue(&snac); 808 cnt += process_user_queue(&user);
735 user_free(&snac); 809 user_free(&user);
736 } 810 }
737 } 811 }
738 } 812 }
@@ -740,8 +814,10 @@ static void *background_thread(void *arg)
740 /* global queue */ 814 /* global queue */
741 cnt += process_queue(); 815 cnt += process_queue();
742 816
817 t = time(NULL);
818
743 /* time to purge? */ 819 /* time to purge? */
744 if ((t = time(NULL)) > purge_time) { 820 if (t > purge_time) {
745 /* next purge time is tomorrow */ 821 /* next purge time is tomorrow */
746 purge_time = t + 24 * 60 * 60; 822 purge_time = t + 24 * 60 * 60;
747 823
@@ -750,6 +826,22 @@ static void *background_thread(void *arg)
750 job_post(q_item, 0); 826 job_post(q_item, 0);
751 } 827 }
752 828
829 /* time to poll the RSS? */
830 if (t > rss_time) {
831 /* next RSS poll time */
832 int hours = xs_number_get(xs_dict_get_def(srv_config, "rss_hashtag_poll_hours", "4"));
833
834 /* don't hammer servers too much */
835 if (hours < 1)
836 hours = 1;
837
838 rss_time = t + 60 * 60 * hours;
839
840 xs *q_item = xs_dict_new();
841 q_item = xs_dict_append(q_item, "type", "rss_hashtag_poll");
842 job_post(q_item, 0);
843 }
844
753 if (cnt == 0) { 845 if (cnt == 0) {
754 /* sleep 3 seconds */ 846 /* sleep 3 seconds */
755 847