eb5d9c185eb9972a2c294496825141163ac9d313
[citadel] / 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.  It runs great on the
7 // Linux operating system (and probably elsewhere).  You can use,
8 // copy, and run it under the terms of the GNU General Public
9 // License version 3.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 #include "webcit.h"
17
18
19 /*
20  * Called from perform_request() to handle the /ctdl/s/ prefix -- always static content.
21  */
22 void output_static(struct http_transaction *h)
23 {
24         char filename[PATH_MAX];
25         struct stat statbuf;
26
27         snprintf(filename, sizeof filename, "static/%s", &h->uri[8]);
28
29         if (strstr(filename, "../")) {  // 100% guaranteed attacker.
30                 do_404(h);      // Die in a car fire.
31                 return;
32         }
33
34         FILE *fp = fopen(filename, "r");        // Try to open the requested file.
35         if (fp == NULL) {
36                 do_404(h);
37                 return;
38         }
39
40         fstat(fileno(fp), &statbuf);
41         h->response_body_length = statbuf.st_size;
42         h->response_body = malloc(h->response_body_length);
43         if (h->response_body != NULL) {
44                 fread(h->response_body, h->response_body_length, 1, fp);
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 }