summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar default2023-07-02 11:11:01 +0200
committerGravatar default2023-07-02 11:11:01 +0200
commitd343b40ee553de8d98c18d3547e6c9b12ab96b48 (patch)
tree2f2d9ab495d2ad4e8187f31530d8019968b905bf
parentFixed footer link. (diff)
downloadsnac2-d343b40ee553de8d98c18d3547e6c9b12ab96b48.tar.gz
snac2-d343b40ee553de8d98c18d3547e6c9b12ab96b48.tar.xz
snac2-d343b40ee553de8d98c18d3547e6c9b12ab96b48.zip
Added HTTP caching to static data.
-rw-r--r--data.c39
-rw-r--r--html.c10
-rw-r--r--httpd.c6
-rw-r--r--snac.h4
4 files changed, 45 insertions, 14 deletions
diff --git a/data.c b/data.c
index 117e16f..87cfc98 100644
--- a/data.c
+++ b/data.c
@@ -1533,19 +1533,44 @@ xs_str *_static_fn(snac *snac, const char *id)
1533} 1533}
1534 1534
1535 1535
1536int static_get(snac *snac, const char *id, xs_val **data, int *size) 1536int static_get(snac *snac, const char *id, xs_val **data, int *size,
1537 const char *inm, xs_str **etag)
1537/* returns static content */ 1538/* returns static content */
1538{ 1539{
1539 xs *fn = _static_fn(snac, id); 1540 xs *fn = _static_fn(snac, id);
1540 FILE *f;
1541 int status = 404; 1541 int status = 404;
1542 1542
1543 if (fn && (f = fopen(fn, "rb")) != NULL) { 1543 if (fn) {
1544 *size = XS_ALL; 1544 double tm = mtime(fn);
1545 *data = xs_read(f, size);
1546 fclose(f);
1547 1545
1548 status = 200; 1546 if (tm > 0.0) {
1547 /* file exists; build the etag */
1548 xs *e = xs_fmt("W/\"snac-%.0lf\"", tm);
1549
1550 /* if if-none-match is set, check if it's the same */
1551 if (!xs_is_null(inm) && strcmp(e, inm) == 0) {
1552 /* client has the newest version */
1553 status = 304;
1554 }
1555 else {
1556 /* newer or never downloaded; read the full file */
1557 FILE *f;
1558
1559 if ((f = fopen(fn, "rb")) != NULL) {
1560 *size = XS_ALL;
1561 *data = xs_read(f, size);
1562 fclose(f);
1563
1564 status = 200;
1565 }
1566 }
1567
1568 /* if caller wants the etag, return it */
1569 if (etag != NULL)
1570 *etag = xs_dup(e);
1571
1572 srv_debug(1, xs_fmt("static_get(): %d %s %s", status, id, e));
1573 }
1549 } 1574 }
1550 1575
1551 return status; 1576 return status;
diff --git a/html.c b/html.c
index 7a0c805..425df4b 100644
--- a/html.c
+++ b/html.c
@@ -226,7 +226,7 @@ d_char *html_user_header(snac *snac, d_char *s, int local)
226 int size; 226 int size;
227 227
228 /* try to open the user css */ 228 /* try to open the user css */
229 if (!valid_status(static_get(snac, "style.css", &css, &size))) { 229 if (!valid_status(static_get(snac, "style.css", &css, &size, NULL, NULL))) {
230 /* it's not there; try to open the server-wide css */ 230 /* it's not there; try to open the server-wide css */
231 FILE *f; 231 FILE *f;
232 xs *g_css_fn = xs_fmt("%s/style.css", srv_basedir); 232 xs *g_css_fn = xs_fmt("%s/style.css", srv_basedir);
@@ -1542,7 +1542,7 @@ xs_str *html_notifications(snac *snac)
1542 1542
1543 1543
1544int html_get_handler(const xs_dict *req, const char *q_path, 1544int html_get_handler(const xs_dict *req, const char *q_path,
1545 char **body, int *b_size, char **ctype) 1545 char **body, int *b_size, char **ctype, xs_str **etag)
1546{ 1546{
1547 char *accept = xs_dict_get(req, "accept"); 1547 char *accept = xs_dict_get(req, "accept");
1548 int status = 404; 1548 int status = 404;
@@ -1695,10 +1695,12 @@ int html_get_handler(const xs_dict *req, const char *q_path,
1695 char *id = xs_list_get(l, 1); 1695 char *id = xs_list_get(l, 1);
1696 int sz; 1696 int sz;
1697 1697
1698 if (valid_status(static_get(&snac, id, body, &sz))) { 1698 status = static_get(&snac, id, body, &sz,
1699 xs_dict_get(req, "if-none-match"), etag);
1700
1701 if (valid_status(status)) {
1699 *b_size = sz; 1702 *b_size = sz;
1700 *ctype = xs_mime_by_ext(id); 1703 *ctype = xs_mime_by_ext(id);
1701 status = 200;
1702 } 1704 }
1703 } 1705 }
1704 else 1706 else
diff --git a/httpd.c b/httpd.c
index de70089..9aac3b5 100644
--- a/httpd.c
+++ b/httpd.c
@@ -156,6 +156,7 @@ void httpd_connection(FILE *f)
156 xs *headers = NULL; 156 xs *headers = NULL;
157 xs *q_path = NULL; 157 xs *q_path = NULL;
158 xs *payload = NULL; 158 xs *payload = NULL;
159 xs *etag = NULL;
159 int p_size = 0; 160 int p_size = 0;
160 char *p; 161 char *p;
161 162
@@ -198,7 +199,7 @@ void httpd_connection(FILE *f)
198#endif /* NO_MASTODON_API */ 199#endif /* NO_MASTODON_API */
199 200
200 if (status == 0) 201 if (status == 0)
201 status = html_get_handler(req, q_path, &body, &b_size, &ctype); 202 status = html_get_handler(req, q_path, &body, &b_size, &ctype, &etag);
202 } 203 }
203 else 204 else
204 if (strcmp(method, "POST") == 0) { 205 if (strcmp(method, "POST") == 0) {
@@ -263,6 +264,9 @@ void httpd_connection(FILE *f)
263 headers = xs_dict_append(headers, "content-type", ctype); 264 headers = xs_dict_append(headers, "content-type", ctype);
264 headers = xs_dict_append(headers, "x-creator", USER_AGENT); 265 headers = xs_dict_append(headers, "x-creator", USER_AGENT);
265 266
267 if (!xs_is_null(etag))
268 headers = xs_dict_append(headers, "etag", etag);
269
266 if (b_size == 0 && body != NULL) 270 if (b_size == 0 && body != NULL)
267 b_size = strlen(body); 271 b_size = strlen(body);
268 272
diff --git a/snac.h b/snac.h
index 13cfe8c..74f4969 100644
--- a/snac.h
+++ b/snac.h
@@ -137,7 +137,7 @@ int is_hidden(snac *snac, const char *id);
137int actor_add(const char *actor, xs_dict *msg); 137int actor_add(const char *actor, xs_dict *msg);
138int actor_get(snac *snac, const char *actor, xs_dict **data); 138int actor_get(snac *snac, const char *actor, xs_dict **data);
139 139
140int static_get(snac *snac, const char *id, xs_val **data, int *size); 140int static_get(snac *snac, const char *id, xs_val **data, int *size, const char *inm, xs_str **etag);
141void static_put(snac *snac, const char *id, const char *data, int size); 141void static_put(snac *snac, const char *id, const char *data, int size);
142void static_put_meta(snac *snac, const char *id, const char *str); 142void static_put_meta(snac *snac, const char *id, const char *str);
143xs_str *static_get_meta(snac *snac, const char *id); 143xs_str *static_get_meta(snac *snac, const char *id);
@@ -250,7 +250,7 @@ xs_str *not_really_markdown(const char *content, xs_list **attach);
250xs_str *sanitize(const char *content); 250xs_str *sanitize(const char *content);
251 251
252int html_get_handler(const xs_dict *req, const char *q_path, 252int html_get_handler(const xs_dict *req, const char *q_path,
253 char **body, int *b_size, char **ctype); 253 char **body, int *b_size, char **ctype, xs_str **etag);
254int html_post_handler(const xs_dict *req, const char *q_path, 254int html_post_handler(const xs_dict *req, const char *q_path,
255 char *payload, int p_size, 255 char *payload, int p_size,
256 char **body, int *b_size, char **ctype); 256 char **body, int *b_size, char **ctype);