1 // Output static content
3 // Copyright (c) 1996-2022 by the citadel.org team
5 // This program is open source software. Use, duplication, or
6 // disclosure are subject to the GNU General Public License v3.
11 // Called from perform_request() to handle static content.
12 void output_static(struct http_transaction *h) {
13 char filename[PATH_MAX];
16 syslog(LOG_DEBUG, "static: %s", h->url);
18 if (!strncasecmp(h->url, "/ctdl/s/", 8)) {
19 snprintf(filename, sizeof filename, "static/%s", &h->url[8]);
21 else if (!strncasecmp(h->url, "/.well-known/", 13)) {
22 snprintf(filename, sizeof filename, "static/.well-known/%s", &h->url[13]);
24 else if (!strcasecmp(h->url, "/favicon.ico")) {
25 snprintf(filename, sizeof filename, "static/images/favicon.ico");
32 if (strstr(filename, "../")) { // 100% guaranteed attacker.
33 do_404(h); // Die in a car fire.
37 FILE *fp = fopen(filename, "r"); // Try to open the requested file.
39 syslog(LOG_DEBUG, "%s: %s", filename, strerror(errno));
44 fstat(fileno(fp), &statbuf);
45 h->response_body_length = statbuf.st_size;
46 h->response_body = malloc(h->response_body_length);
47 if (h->response_body != NULL) {
48 fread(h->response_body, h->response_body_length, 1, fp);
51 h->response_body_length = 0;
53 fclose(fp); // Content is now in memory.
55 h->response_code = 200;
56 h->response_string = strdup("OK");
57 add_response_header(h, strdup("Content-type"), strdup(GuessMimeByFilename(filename, strlen(filename))));
59 char *datestring = http_datestring(statbuf.st_mtime);
61 add_response_header(h, strdup("Last-Modified"), datestring);