In webcit-classic, include webserver.h from webcit.h.
[citadel.git] / webcit / static.c
1 // The functions in this file handle static pages and objects -- a basic web server.
2 //
3 // Copyright (c) 1996-2021 by the citadel.org team
4 //
5 // This program is open source software.  You can redistribute it and/or
6 // modify it under the terms of the GNU General Public License, version 3.
7
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <dirent.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15 #include <stddef.h>
16 #include "webcit.h"
17
18
19 unsigned char OnePixelGif[37] = {
20                 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x01, 0x00,
21                 0x01, 0x00, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff,
22                 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00,
23                 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44,
24                 0x01, 0x00, 0x3b 
25 };
26
27
28 void output_error_pic(const char *ErrMsg1, const char *ErrMsg2) {
29         hprintf("HTTP/1.1 200 %s\r\n", ErrMsg1);
30         hprintf("Content-Type: image/gif\r\n");
31         hprintf("x-webcit-errormessage: %s\r\n", ErrMsg2);
32         begin_burst();
33         StrBufPlain(WC->WBuf, (const char *)OnePixelGif, sizeof(OnePixelGif));
34         end_burst();
35 }
36
37 /*
38  * dump out static pages from disk
39  */
40 void output_static(char *prefix) {
41         int fd;
42         struct stat statbuf;
43         off_t bytes;
44         const char *content_type;
45         int len;
46         const char *Err;
47         char what[SIZ];
48         if (prefix==NULL) {
49                 // Force blank.gif  Overrides the request line.
50                 strcpy(what,"./static/webcit_icons/blank.gif");
51         } else {
52                 snprintf(what, sizeof what, "./%s/%s", prefix, (char *)ChrPtr(WC->Hdr->HR.ReqLine));
53         }
54
55         syslog(LOG_DEBUG, "output_static(%s)", what);
56         len = strlen (what);
57         content_type = GuessMimeByFilename(what, len);
58         fd = open(what, O_RDONLY);
59         if (fd <= 0) {
60                 syslog(LOG_INFO, "output_static('%s') [%s] : %s", what, ChrPtr(WC->Hdr->this_page), strerror(errno));
61                 if (strstr(content_type, "image/") != NULL) {
62                         output_error_pic("the file you requsted is gone.", strerror(errno));
63                 }
64                 else {
65                         hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
66                         hprintf("Content-Type: text/plain\r\n");
67                         begin_burst();
68                         wc_printf("Cannot open %s: %s\r\n", what, strerror(errno));
69                         end_burst();
70                 }
71         }
72         else {
73                 if (fstat(fd, &statbuf) == -1) {
74                         syslog(LOG_INFO, "output_static('%s') : %s", what, strerror(errno));
75                         if (strstr(content_type, "image/") != NULL) {
76                                 output_error_pic("Stat failed!", strerror(errno));
77                         }
78                         else {
79                                 hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
80                                 hprintf("Content-Type: text/plain\r\n");
81                                 begin_burst();
82                                 wc_printf("Cannot fstat %s: %s\n", what, strerror(errno));
83                                 end_burst();
84                         }
85                         if (fd > 0) close(fd);
86                         return;
87                 }
88
89                 bytes = statbuf.st_size;
90
91                 if (StrBufReadBLOB(WC->WBuf, &fd, 1, bytes, &Err) < 0) {
92                         if (fd > 0) close(fd);
93                         syslog(LOG_INFO, "output_static('%s')  -- FREAD FAILED (%s) --\n", what, strerror(errno));
94                                 hprintf("HTTP/1.1 500 internal server error \r\n");
95                                 hprintf("Content-Type: text/plain\r\n");
96                                 end_burst();
97                                 return;
98                 }
99
100                 close(fd);
101                 http_transmit_thing(content_type, 2);
102         }
103         if (yesbstr("force_close_session")) {
104                 end_webcit_session();
105         }
106 }
107
108
109 /*
110  * robots.txt
111  */
112 void robots_txt(void) {
113         output_headers(0, 0, 0, 0, 0, 0);
114
115         hprintf("Content-type: text/plain\r\n"
116                 "Server: %s\r\n"
117                 "Connection: close\r\n",
118                 PACKAGE_STRING);
119         begin_burst();
120
121         wc_printf("User-agent: *\r\n"
122                 "Disallow: /printmsg\r\n"
123                 "Disallow: /msgheaders\r\n"
124                 "Disallow: /groupdav\r\n"
125                 "Disallow: /do_template\r\n"
126                 "Disallow: /static\r\n"
127                 "Disallow: /display_page\r\n"
128                 "Disallow: /readnew\r\n"
129                 "Disallow: /display_enter\r\n"
130                 "Disallow: /skip\r\n"
131                 "Disallow: /ungoto\r\n"
132                 "Sitemap: %s/sitemap.xml\r\n"
133                 "\r\n"
134                 ,
135                 ChrPtr(site_prefix)
136         );
137
138         wDumpContent(0);
139 }
140
141
142 // These are the various prefixes we can use to fetch static pages.
143 void output_static_root(void)           {       output_static(".");             }
144 void output_static_static(void)         {       output_static("static");        }
145 void output_static_tinymce(void)        {       output_static("tiny_mce");      }
146 void output_static_acme(void)           {       output_static(".well-known");   }
147
148
149 void 
150 ServerStartModule_STATIC
151 (void)
152 {
153 }
154
155
156 void 
157 ServerShutdownModule_STATIC
158 (void)
159 {
160 }
161
162 void 
163 InitModule_STATIC
164 (void)
165 {
166         WebcitAddUrlHandler(HKEY("robots.txt"), "", 0, robots_txt, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
167         WebcitAddUrlHandler(HKEY("favicon.ico"), "", 0, output_static_root, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
168         WebcitAddUrlHandler(HKEY("static"), "", 0, output_static_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
169         WebcitAddUrlHandler(HKEY("tinymce"), "", 0, output_static_tinymce, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
170         WebcitAddUrlHandler(HKEY("tiny_mce"), "", 0, output_static_tinymce, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
171         WebcitAddUrlHandler(HKEY(".well-known"), "", 0, output_static_acme, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
172 }