207cbabdb634c4f9be9f4b9b7c9baea09ca71260
[citadel.git] / webcit-ng / static.c
1 /*
2  * Output static content
3  *
4  * Copyright (c) 1996-2018 by the citadel.org team
5  *
6  * This program is open source software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 3.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include "webcit.h"
16
17
18 /*
19  * Called from perform_request() to handle the /ctdl/s/ prefix -- always static content.
20  */
21 void output_static(struct http_transaction *h)
22 {
23         char filename[PATH_MAX];
24         struct stat statbuf;
25
26         snprintf(filename, sizeof filename, "static/%s", &h->uri[8]);
27
28         if (strstr(filename, "../")) {                  // 100% guaranteed attacker.
29                 do_404(h);                              // Die in a car fire.
30                 return;
31         }
32
33         FILE *fp = fopen(filename, "r");                // Try to open the requested file.
34         if (fp == NULL) {
35                 do_404(h);
36                 return;
37         }
38
39         fstat(fileno(fp), &statbuf);
40         h->response_body_length = statbuf.st_size;
41         h->response_body = malloc(h->response_body_length);
42         if (h->response_body != NULL) {
43                 fread(h->response_body, h->response_body_length, 1, fp);
44         }
45         else {
46                 h->response_body_length = 0;
47         }
48         fclose(fp);                                     // Content is now in memory.
49
50         h->response_code = 200;
51         h->response_string = strdup("OK");
52         add_response_header(h, strdup("Content-type"), strdup(GuessMimeByFilename(filename, strlen(filename))));
53
54         char *datestring = http_datestring(statbuf.st_mtime);
55         if (datestring) {
56                 add_response_header(h, strdup("Last-Modified"), datestring);
57         }
58 }