#include <unistd.h>
#include <errno.h>
#include <string.h>
+#include <sys/socket.h>
#include <ashd/req.h>
#include <ashd/resp.h>
#include <ashd/log.h>
}
}
+static int cached(struct hthead *req, struct fileinfo f)
+{
+ char *hdr;
+ time_t cdate;
+
+ if((hdr = getheader(req, "If-Modified-Since")) != NULL) {
+ cdate = parsehttpdate(hdr);
+ return((cdate > 0) && !(cdate < f.mtime));
+ }
+ return(0);
+}
+
static void serve(struct muth *muth, va_list args)
{
vavar(struct hthead *, req);
simpleerror(fd, 404, "Resource not found", "The resource %s was not found", htmlquote(req->rest));
goto out;
}
- out = mtstdopen(fd, 1, 60, "r+");
- fprintf(out, "HTTP/1.1 200 OK\n");
- fprintf(out, "Content-Type: %s\n", f.ctype);
- fprintf(out, "Content-Length: %zi\n", f.sz);
- fprintf(out, "Last-Modified: %s\n", fmthttpdate(f.mtime));
- fprintf(out, "\n");
- fwrite(f.data, 1, f.sz, out);
+ out = mtstdopen(fd, 1, 60, "r+", NULL);
+ if(cached(req, f)) {
+ fprintf(out, "HTTP/1.1 304 Not Modified\n");
+ fprintf(out, "Content-Length: 0\n");
+ fprintf(out, "\n");
+ } else {
+ fprintf(out, "HTTP/1.1 200 OK\n");
+ fprintf(out, "Content-Type: %s\n", f.ctype);
+ fprintf(out, "Content-Length: %zi\n", f.sz);
+ fprintf(out, "Last-Modified: %s\n", fmthttpdate(f.mtime));
+ fprintf(out, "\n");
+ fwrite(f.data, 1, f.sz, out);
+ }
free(f.data);
out:
static void usage(FILE *out)
{
- fprintf(out, "usage: statserve [-h] SOURCE...\n");
+ fprintf(out, "usage: statserve [-h] [-P PAGESIZE] SOURCE...\n");
}
static void listenloop(struct muth *muth, va_list args)
}
}
+static void sigterm(int sig)
+{
+ shutdown(0, SHUT_RDWR);
+}
+
+static void closeall(void)
+{
+ struct source *src;
+
+ for(src = sources; src != NULL; src = src->next) {
+ if(src->close)
+ src->close(src);
+ }
+}
+
int main(int argc, char **argv)
{
int c;
struct source *last, *src;
- while((c = getopt(argc, argv, "+h")) >= 0) {
+ while((c = getopt(argc, argv, "+hP:")) >= 0) {
switch(c) {
+ case 'P':
+ dbpagesize = atoi(optarg);
+ break;
case 'h':
usage(stdout);
return(0);
}
last = NULL;
while(optind < argc) {
- src = parsesource(argv[optind++]);
+ if((src = parsesource(argv[optind++])) == NULL) {
+ closeall();
+ return(1);
+ }
if(!sources)
sources = src;
if(last)
}
if(!sources) {
usage(stderr);
+ closeall();
return(1);
}
mustart(listenloop, 0);
+ signal(SIGINT, sigterm);
+ signal(SIGTERM, sigterm);
ioloop();
+ closeall();
return(0);
}