summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE_NOTES.md4
-rw-r--r--activitypub.c2
-rw-r--r--data/greeting.html13
-rw-r--r--data/server.json21
-rw-r--r--data/style.css27
-rw-r--r--html.c10
-rw-r--r--httpd.c8
-rw-r--r--mastoapi.c45
-rw-r--r--utils.c1
-rw-r--r--xs_formdata.h27
10 files changed, 148 insertions, 10 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 7d3f683..4614da6 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -4,10 +4,12 @@
Added support for Peertube videos.
-Mastodon API: Added support for editing posts, fixed an error related to the edit date of a post.
+Mastodon API: Added support for editing posts, fixed an error related to the edit date of a post, fixed some crashes.
Added a handshake emoji next to a user name if it's a mutual relation (follower and followed), because friendship is bliss.
+Tweaked some retry timeout values for better behaviour in larger instances (thanks to me@mysmallinstance.homelinux.org for their help).
+
## 2.45
Fixed a collision in webfinger caching. This may affect federation with some software, so I recommend an upgrade.
diff --git a/activitypub.c b/activitypub.c
index e680e33..698758c 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -2220,7 +2220,7 @@ void process_queue_item(xs_dict *q_item)
/* deliver (if previous error status was a timeout, try now longer) */
status = send_to_inbox_raw(keyid, seckey, inbox, msg,
- &payload, &p_size, p_status == 599 ? 20 : 3);
+ &payload, &p_size, p_status == 599 ? 8 : 6);
if (payload) {
if (p_size > 64) {
diff --git a/data/greeting.html b/data/greeting.html
new file mode 100644
index 0000000..b664538
--- /dev/null
+++ b/data/greeting.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html><head>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>Welcome to %host%</title>
+<body style="margin: auto; max-width: 50em">
+<p><b>%host%</b> is a <a href="https://en.wikipedia.org/wiki/Fediverse">Fediverse</a> instance that uses the <a href="https://en.wikipedia.org/wiki/ActivityPub">ActivityPub</a> protocol. In other words, users at this host can communicate with people that use software like Mastodon, Pleroma, Friendica, etc. all around the world.</p>
+<p>This server runs the <a href="https://comam.es/what-is-snac">snac</a> software and there is no automatic sign-up process.</p>
+<p>The following users are part of this community:</p>
+
+%userlist%
+
+<p>This site is powered by <abbr title="Social Networks Are Crap">snac</abbr>.</p>
+</body></html>
diff --git a/data/server.json b/data/server.json
new file mode 100644
index 0000000..901f377
--- /dev/null
+++ b/data/server.json
@@ -0,0 +1,21 @@
+{
+ "prefix": "",
+ "port": 8001,
+ "dbglevel": 0,
+ "queue_retry_minutes": 2,
+ "queue_retry_max": 10,
+ "cssurls": [
+ ""
+ ],
+ "max_timeline_entries": 128,
+ "timeline_purge_days": 120,
+ "local_purge_days": 0,
+ "admin_account": "",
+ "title": "",
+ "short_description": "",
+ "fastcgi": false,
+ "layout": 2.7,
+ "address": "0.0.0.0",
+ "host": "snac.notnull.space",
+ "admin_email": "paul@notnull.space"
+} \ No newline at end of file
diff --git a/data/style.css b/data/style.css
new file mode 100644
index 0000000..24be520
--- /dev/null
+++ b/data/style.css
@@ -0,0 +1,27 @@
+body { max-width: 48em; margin: auto; line-height: 1.5; padding: 0.8em; word-wrap: break-word; }
+pre { overflow-x: scroll; }
+.snac-embedded-video, img { max-width: 100% }
+.snac-origin { font-size: 85% }
+.snac-score { float: right; font-size: 85% }
+.snac-top-user { text-align: center; padding-bottom: 2em }
+.snac-top-user-name { font-size: 200% }
+.snac-top-user-id { font-size: 150% }
+.snac-avatar { float: left; height: 2.5em; padding: 0.25em }
+.snac-author { font-size: 90%; text-decoration: none }
+.snac-author-tag { font-size: 80% }
+.snac-pubdate { color: #a0a0a0; font-size: 90% }
+.snac-top-controls { padding-bottom: 1.5em }
+.snac-post { border-top: 1px solid #a0a0a0; }
+.snac-children { padding-left: 2em; border-left: 1px solid #a0a0a0; }
+.snac-textarea { font-family: inherit; width: 100% }
+.snac-history { border: 1px solid #606060; border-radius: 3px; margin: 2.5em 0; padding: 0 2em }
+.snac-btn-mute { float: right; margin-left: 0.5em }
+.snac-btn-unmute { float: right; margin-left: 0.5em }
+.snac-btn-follow { float: right; margin-left: 0.5em }
+.snac-btn-unfollow { float: right; margin-left: 0.5em }
+.snac-btn-hide { float: right; margin-left: 0.5em }
+.snac-btn-delete { float: right; margin-left: 0.5em }
+.snac-btn-limit { float: right; margin-left: 0.5em }
+.snac-btn-unlimit { float: right; margin-left: 0.5em }
+.snac-footer { margin-top: 2em; font-size: 75% }
+.snac-poll-result { margin-left: auto; margin-right: auto; }
diff --git a/html.c b/html.c
index 444a53d..de2c60e 100644
--- a/html.c
+++ b/html.c
@@ -427,7 +427,9 @@ static xs_html *html_base_head(void)
xs_html_attr("name", "generator"),
xs_html_attr("content", USER_AGENT)));
- /* add server CSS */
+ /* add server CSS and favicon */
+ xs *f;
+ f = xs_fmt("%s/favicon.ico", srv_baseurl);
xs_list *p = xs_dict_get(srv_config, "cssurls");
char *v;
while (xs_list_iter(&p, &v)) {
@@ -438,6 +440,12 @@ static xs_html *html_base_head(void)
xs_html_attr("href", v)));
}
+ xs_html_add(head,
+ xs_html_sctag("link",
+ xs_html_attr("rel", "icon"),
+ xs_html_attr("type", "image/x-icon"),
+ xs_html_attr("href", f)));
+
return head;
}
diff --git a/httpd.c b/httpd.c
index a20d692..3a39481 100644
--- a/httpd.c
+++ b/httpd.c
@@ -243,6 +243,14 @@ int server_get_handler(xs_dict *req, const char *q_path,
*body = xs_str_new("User-agent: *\n"
"Disallow: /\n");
}
+ else
+ if (strcmp(q_path, "/.well-known/host-meta") == 0) {
+ status = 200;
+ *ctype = "application/xrd+xml";
+ *body = xs_str_new("<XRD>"
+ "<Link rel=\"lrdd\" type=\"application/xrd+xml\" template=\"%s/.well-known/webfinger?resource={uri}\"/>"
+ "</XRD>");
+ }
if (status != 0)
srv_debug(1, xs_fmt("server_get_handler serving '%s' %d", q_path, status));
diff --git a/mastoapi.c b/mastoapi.c
index 9f6c383..6ed3835 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -240,8 +240,10 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
char *i_ctype = xs_dict_get(req, "content-type");
xs *args = NULL;
- if (i_ctype && xs_startswith(i_ctype, "application/json"))
- args = xs_json_loads(payload);
+ if (i_ctype && xs_startswith(i_ctype, "application/json")) {
+ if (!xs_is_null(payload))
+ args = xs_json_loads(payload);
+ }
else
if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded") && payload) {
xs *upl = xs_url_dec(payload);
@@ -250,6 +252,9 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
else
args = xs_dup(xs_dict_get(req, "p_vars"));
+ if (args == NULL)
+ return 400;
+
xs *cmd = xs_replace_n(q_path, "/oauth", "", 1);
srv_debug(1, xs_fmt("oauth_post_handler %s", q_path));
@@ -354,6 +359,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
}
}
+ /* no code?
+ I'm not sure of the impacts of this right now, but Subway Tooter does not
+ provide a code so one must be generated */
+ if (xs_is_null(code)){
+ code = random_str();
+ }
if (gtype && code && cid && csec && ruri) {
xs *app = app_get(cid);
@@ -1403,7 +1414,6 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
const char *type = xs_dict_get(msg, "type");
if (!xs_match(type, "Note|Question|Page|Article"))
continue;
-
const char *from = NULL;
if (strcmp(type, "Page") == 0)
from = xs_dict_get(msg, "audience");
@@ -1617,6 +1627,15 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
status = 200;
}
else
+ if (strcmp(cmd, "/v2/filters") == 0) { /** **/
+ /* snac will never have filters
+ * but still, without a v2 endpoint a short delay is introduced
+ * in some apps */
+ *body = xs_dup("[]");
+ *ctype = "application/json";
+ status = 200;
+ }
+ else
if (strcmp(cmd, "/v1/favourites") == 0) { /** **/
/* snac will never support a list of favourites */
*body = xs_dup("[]");
@@ -1981,8 +2000,18 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
xs *args = NULL;
char *i_ctype = xs_dict_get(req, "content-type");
- if (i_ctype && xs_startswith(i_ctype, "application/json"))
- args = xs_json_loads(payload);
+ if (i_ctype && xs_startswith(i_ctype, "application/json")) {
+ if (!xs_is_null(payload))
+ args = xs_json_loads(payload);
+ }
+ else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded"))
+ {
+ // Some apps send form data instead of json so we should cater for those
+ if (!xs_is_null(payload)) {
+ xs *upl = xs_url_dec(payload);
+ args = xs_url_vars(upl);
+ }
+ }
else
args = xs_dup(xs_dict_get(req, "p_vars"));
@@ -2504,8 +2533,10 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
xs *args = NULL;
char *i_ctype = xs_dict_get(req, "content-type");
- if (i_ctype && xs_startswith(i_ctype, "application/json"))
- args = xs_json_loads(payload);
+ if (i_ctype && xs_startswith(i_ctype, "application/json")) {
+ if (!xs_is_null(payload))
+ args = xs_json_loads(payload);
+ }
else
args = xs_dup(xs_dict_get(req, "p_vars"));
diff --git a/utils.c b/utils.c
index 9992205..0d02659 100644
--- a/utils.c
+++ b/utils.c
@@ -81,6 +81,7 @@ static const char *greeting_html =
"<!DOCTYPE html>\n"
"<html><head>\n"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n"
+ "<link rel=\"icon\" type=\"image/x-icon\" href=\"https://%host%/favicon.ico\"/>\n"
"<title>Welcome to %host%</title>\n"
"<body style=\"margin: auto; max-width: 50em\">\n"
"%blurb%"
diff --git a/xs_formdata.h b/xs_formdata.h
new file mode 100644
index 0000000..213bd3e
--- /dev/null
+++ b/xs_formdata.h
@@ -0,0 +1,27 @@
+/* copyright (c) 2022 - 2024 grunfink et al. / MIT license */
+#include "xs.h"
+
+#ifndef _XS_FORMDATA_H
+
+#define _XS_FORMDATA_H
+
+xs_val *xs_formdata_loads(const xs_str *formdata);
+
+#ifdef XS_IMPLEMENTATION
+
+/** IMPLEMENTATION **/
+
+xs_val *xs_formdata_loads(const xs_str *formdata)
+/* loads a string in formdata format and converts to a multiple data */
+{
+ xs_val *v = NULL;
+ xs_list *args = xs_split(formdata, "&");
+ int i = 0;
+ while (){}
+ printf("args: %s\r\n", args); fflush(stdout);
+ printf("data: %s\r\n", formdata); fflush(stdout);
+}
+
+#endif /* XS_IMPLEMENTATION */
+
+#endif /* _XS_FORMDATA_H */