commit dbb4329b8f450ee3ab74e05b8bb6d8f76edcece6
parent 143e638fc66f14dae4403217e4c3ec7391a74f75
Author: William Casarin <jb55@jb55.com>
Date: Fri, 8 Oct 2021 19:50:36 -0700
more outbox handling
Diffstat:
4 files changed, 160 insertions(+), 22 deletions(-)
diff --git a/src/chibipub.c b/src/chibipub.c
@@ -18,6 +18,7 @@
#include "outbox.h"
#include "json.h"
#include "sigcheck.h"
+#include "env.h"
#define BUF_SIZE 1048576
#define ARENA_SIZE 134217728 /* 128 MB virtual mem arena */
@@ -37,27 +38,6 @@ static void error(char *msg)
exit(1);
}
-static inline const char *get_hostname()
-{
- return getenv("CHIBIPUB_HOST");
-}
-
-static inline const char *get_pubkey()
-{
- return getenv("CHIBIPUB_PUBKEY");
-}
-
-static inline const char *get_id()
-{
- const char *ret;
- ret = getenv("CHIBIPUB_ID");
-
- if (!ret)
- return get_hostname();
-
- return ret;
-}
-
#define SCHEMA "https://"
@@ -348,6 +328,8 @@ static int handle_request(struct http_req *req, struct cursor *arena)
return handle_inbox_request(req, arena);
} else if (is_get(req) && patheq(req, "/outbox")) {
return handle_outbox_request(req);
+ } else if (is_get(req) && patheq(req, "/outbox?page=true")) {
+ return handle_outbox_page_request(req, "outbox.json");
} else if (is_get(req) &&
is_accept_activity(req) &&
streq(req->path, "/")) {
diff --git a/src/env.h b/src/env.h
@@ -0,0 +1,26 @@
+
+#pragma once
+
+#include <stdlib.h>
+
+static inline const char *get_hostname()
+{
+ return getenv("CHIBIPUB_HOST");
+}
+
+static inline const char *get_pubkey()
+{
+ return getenv("CHIBIPUB_PUBKEY");
+}
+
+static inline const char *get_id()
+{
+ const char *ret;
+ ret = getenv("CHIBIPUB_ID");
+
+ if (!ret)
+ return get_hostname();
+
+ return ret;
+}
+
diff --git a/src/outbox.c b/src/outbox.c
@@ -1,8 +1,137 @@
#include "http.h"
+#include "env.h"
+#include "io.h"
+
+#include <sys/mman.h>
+
+/*
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://gleasonator.com/schemas/litepub-0.1.jsonld",
+ {
+ "@language": "und"
+ }
+ ],
+ "first": "https://gleasonator.com/users/alex/outbox?page=true",
+ "id": "https://gleasonator.com/users/alex/outbox",
+ "type": "OrderedCollection"
+}
+ */
int handle_outbox_request(struct http_req *req)
{
- http_write_header(req, "501 Not Implemented");
+ const char *hostname = get_hostname();
+
+ http_write_header(req, "200 OK");
+
+ fprintf(req->client.socket_file,
+ "{\"@context\": [\"https://www.w3.org/ns/activitystreams\"],"
+ " \"first\": \"https://%s/outbox?page=true\","
+ " \"id\": \"https://%s/outbox\","
+ " \"type\": \"OrderedCollection\""
+ " }\r\n", hostname, hostname);
+
+ return 1;
+}
+
+static inline int is_space(char c)
+{
+ return c == 0x20 || (c >= 0x09 && c <= 0x0d);
+}
+
+static inline int is_linebreak(char c)
+{
+ return c == '\n' || c == '\r';
+}
+
+static void consume_space_back(const char *start, const char **cursor)
+{
+ const char *p = *cursor;
+ if (p <= start) return;
+ while (!is_space(*p--) && p > start);
+ *cursor = p;
+}
+
+static void consume_until_linebreak(const char *start, const char **cursor)
+{
+ const char *p = *cursor;
+ if (p <= start) return;
+ while (!is_linebreak(*p) && --p > start);
+ *cursor = p == start? start : p+1;
+}
+
+/*
+static void tail_data(const char *data, size_t len, FILE *out, int lines)
+{
+ const char *p = data + len;
+ const char *line_end;
+
+ line_end = p;
+
+ while (lines-- > 0 && p >= data) {
+ line_end = p;
+ consume_space_back(data, &p);
+ consume_until_linebreak(data, &p);
+
+ fwrite(p, line_end - p, 1, out);
+ p--;
+ }
+}
+*/
+
+static void tail_data_array(const char *data, size_t len, FILE *out, int lines)
+{
+ const char *p = data + len;
+ const char *line_end;
+ int first = 1;
+
+ line_end = p;
+
+ while (lines-- > 0 && p >= data) {
+ line_end = p;
+ consume_space_back(data, &p);
+ consume_until_linebreak(data, &p);
+
+ if (!first)
+ putc(',', out);
+ first = 0;
+
+ fwrite(p, line_end - p, 1, out);
+ p--;
+ }
+}
+
+int handle_outbox_page_request(struct http_req *req, const char *outbox)
+{
+ unsigned char *data;
+ const char *hostname;
+ size_t len;
+
+ hostname = get_hostname();
+
+ http_write_header(req, "200 OK");
+
+ fprintf(req->client.socket_file,
+ "{\"@context\": [\"https://www.w3.org/ns/activitystreams\"],"
+ " \"id\": \"https://%s/outbox?page=true\","
+ " \"partOf\": \"https://%s/outbox\","
+ " \"type\": \"OrderedCollectionPage\","
+ " \"orderedItems\": ["
+ , hostname, hostname);
+
+ // technically a 404 but whatevs
+ if (map_file(outbox, &data, &len)) {
+ if (len > 0) {
+ tail_data_array((const char*)data, len,
+ req->client.socket_file, 20);
+ }
+
+ munmap(data, len);
+ }
+
+ fprintf(req->client.socket_file, "]}\r\n");
+
return 1;
}
diff --git a/src/outbox.h b/src/outbox.h
@@ -5,5 +5,6 @@
#include "http.h"
int handle_outbox_request(struct http_req *);
+int handle_outbox_page_request(struct http_req *, const char *outbox);
#endif /* CHIBIPUB_OUTBOX */