diff options
-rw-r--r-- | httpd.h | 13 | ||||
-rw-r--r-- | ls.c | 12 | ||||
-rw-r--r-- | request.c | 59 | ||||
-rw-r--r-- | response.c | 24 | ||||
-rw-r--r-- | webfsd.c | 10 |
5 files changed, 58 insertions, 60 deletions
@@ -31,9 +31,11 @@ #define S1(str) #str #define S(str) S1(str) +#define RFC1123 "%a, %d %b %Y %H:%M:%S GMT" + struct DIRCACHE { char path[1024]; - time_t mtime; + char mtime[40]; time_t add; char *html; int length; @@ -72,9 +74,9 @@ struct REQUEST { int major,minor; /* http version */ char auth[64]; struct strlist *header; - time_t if_modified; - time_t if_unmodified; - time_t if_range; + char *if_modified; + char *if_unmodified; + char *if_range; char *range_hdr; int ranges; off_t *r_start; @@ -92,6 +94,7 @@ struct REQUEST { off_t lbody; int bfd; /* file descriptor */ struct stat bst; /* file info */ + char mtime[40]; /* RFC 1123 */ off_t written; int head_only; int rh,rb; @@ -210,7 +213,7 @@ extern char *h501,*b501; void mkerror(struct REQUEST *req, int status, int ka); void mkredirect(struct REQUEST *req); -void mkheader(struct REQUEST *req, int status, time_t mtime); +void mkheader(struct REQUEST *req, int status); void mkcgi(struct REQUEST *req, char *status, struct strlist *header); void write_request(struct REQUEST *req); @@ -458,8 +458,8 @@ get_dir(struct REQUEST *req, char *filename) } if (this) { /* check mtime and cache entry age */ - if (this->mtime < req->bst.st_mtime || - now - this->add > MAX_CACHE_AGE) { + if (now - this->add > MAX_CACHE_AGE || + 0 != strcmp(this->mtime, req->mtime)) { free_dir(this); this = NULL; } @@ -476,10 +476,10 @@ get_dir(struct REQUEST *req, char *filename) dirs = this; DO_UNLOCK(lock_dircache); - strcpy(this->path,filename); - this->mtime = req->bst.st_mtime; - this->add = now; - this->html = ls(now,req->hostname,filename,req->path,&(this->length)); + strcpy(this->path, filename); + strcpy(this->mtime, req->mtime); + this->add = now; + this->html = ls(now,req->hostname,filename,req->path,&(this->length)); DO_LOCK(this->lock_reading); this->reading = 0; @@ -87,6 +87,7 @@ read_request(struct REQUEST *req, int pipelined) /* ---------------------------------------------------------------------- */ +#if 0 static time_t parse_date(char *line) { @@ -125,6 +126,7 @@ parse_date(char *line) return mktime(&tm); } +#endif static off_t parse_off_t(char *str, int *pos) @@ -145,9 +147,6 @@ parse_ranges(struct REQUEST *req) char *h,*line = req->range_hdr; int i,off; - if (req->if_range > 0 && req->if_range != req->bst.st_mtime) - return 0; - for (h = line, req->ranges=1; *h != '\n' && *h != '\0'; h++) if (*h == ',') req->ranges++; @@ -353,7 +352,6 @@ parse_request(struct REQUEST *req) { char filename[MAX_PATH+1], proto[MAX_MISC+1], *h; int port, rc, len; - time_t t; struct passwd *pw=NULL; if (debug > 2) @@ -429,27 +427,13 @@ parse_request(struct REQUEST *req) req->hostname); } else if (0 == strncasecmp(h,"If-Modified-Since: ",19)) { - if (-1 != (t = parse_date(h+19))) { - req->if_modified = t; - if (debug) - fprintf(stderr,"%03d: if-modified-since: %s", - req->fd,ctime(&t)); - } + req->if_modified = h+19; } else if (0 == strncasecmp(h,"If-Unmodified-Since: ",21)) { - if (-1 != (t = parse_date(h+21))) { - req->if_unmodified = t; - if (debug) - fprintf(stderr,"%03d: if-unmodified-since: %s", - req->fd,ctime(&t)); - } + req->if_unmodified = h+21; } else if (0 == strncasecmp(h,"If-Range: ",10)) { - if (-1 != (t = parse_date(h+10))) { - req->if_range = t; - if (debug) - fprintf(stderr,"%03d: if-range: %s\n",req->fd,ctime(&t)); - } + req->if_range = h+10; } else if (0 == strncasecmp(h,"Authorization: Basic ",21)) { decode_base64(req->auth,h+21,sizeof(req->auth)-1); @@ -462,6 +446,17 @@ parse_request(struct REQUEST *req) req->range_hdr = h+13; } } + if (debug) { + if (req->if_modified) + fprintf(stderr,"%03d: if-modified-since: \"%s\"\n", + req->fd, req->if_modified); + if (req->if_unmodified) + fprintf(stderr,"%03d: if-unmodified-since: \"%s\"\n", + req->fd, req->if_unmodified); + if (req->if_range) + fprintf(stderr,"%03d: if-range: \"%s\"\n", + req->fd, req->if_range); + } /* take care about the hostname */ if (virtualhosts) { @@ -556,21 +551,22 @@ parse_request(struct REQUEST *req) } return; } + strftime(req->mtime, sizeof(req->mtime), RFC1123, gmtime(&req->bst.st_mtime)); req->mime = "text/html"; req->dir = get_dir(req,filename); - t = req->dir->add; if (NULL == req->body) { /* We arrive here if opendir failed, probably due to -EPERM * It does exist (see the stat() call above) */ mkerror(req,403,1); return; - } else if (req->if_modified > 0 && req->if_modified == t) { + } else if (NULL != req->if_modified && + 0 == strcmp(req->if_modified, req->mtime)) { /* 304 not modified */ - mkheader(req,304,t); + mkheader(req,304); req->head_only = 1; } else { /* 200 OK */ - mkheader(req,200,t); + mkheader(req,200); } return; } @@ -610,22 +606,23 @@ parse_request(struct REQUEST *req) /* it is /really/ a regular file */ req->mime = get_mime(filename); - if (req->if_range > 0 && req->if_range != req->bst.st_mtime) + strftime(req->mtime, sizeof(req->mtime), RFC1123, gmtime(&req->bst.st_mtime)); + if (NULL != req->if_range && 0 != strcmp(req->if_range, req->mtime)) /* mtime mismatch -> no ranges */ req->ranges = 0; - if (req->if_unmodified > 0 && req->if_unmodified != req->bst.st_mtime) { + if (NULL != req->if_unmodified && 0 != strcmp(req->if_unmodified, req->mtime)) { /* 412 precondition failed */ mkerror(req,412,1); - } else if (req->if_modified > 0 && req->if_modified == req->bst.st_mtime) { + } else if (NULL != req->if_modified && 0 == strcmp(req->if_modified, req->mtime)) { /* 304 not modified */ - mkheader(req,304,req->bst.st_mtime); + mkheader(req,304); req->head_only = 1; } else if (req->ranges > 0) { /* send byte range(s) */ - mkheader(req,206,req->bst.st_mtime); + mkheader(req,206); } else { /* normal */ - mkheader(req,200,req->bst.st_mtime); + mkheader(req,200); } return; } @@ -172,8 +172,6 @@ static struct HTTP_STATUS { "Server: %s\r\n" \ "Connection: %s\r\n" \ "Accept-Ranges: bytes\r\n" -#define RFCTIME \ - "%a, %d %b %Y %H:%M:%S GMT" #define BOUNDARY \ "XXX_CUT_HERE_%ld_XXX" @@ -200,7 +198,7 @@ mkerror(struct REQUEST *req, int status, int ka) req->lres += sprintf(req->hres+req->lres, "WWW-Authenticate: Basic realm=\"webfs\"\r\n"); req->lres += strftime(req->hres+req->lres,80, - "Date: " RFCTIME "\r\n\r\n", + "Date: " RFC1123 "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER; if (debug) @@ -224,7 +222,7 @@ mkredirect(struct REQUEST *req) req->hostname,tcp_port,quote(req->path,9999), (int64_t)req->lbody); req->lres += strftime(req->hres+req->lres,80, - "Date: " RFCTIME "\r\n\r\n", + "Date: " RFC1123 "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER; if (debug) @@ -255,7 +253,7 @@ mkmulti(struct REQUEST *req, int i) } void -mkheader(struct REQUEST *req, int status, time_t mtime) +mkheader(struct REQUEST *req, int status) { int i; off_t len; @@ -300,19 +298,19 @@ mkheader(struct REQUEST *req, int status, time_t mtime) "Content-Length: %" PRId64 "\r\n", now, (int64_t)len); } - if (mtime != -1) { - req->lres += strftime(req->hres+req->lres,80, - "Last-Modified: " RFCTIME "\r\n", - gmtime(&mtime)); + if (req->mtime[0] != '\0') { + req->lres += sprintf(req->hres+req->lres, + "Last-Modified: %s\r\n", + req->mtime); if (-1 != lifespan) { - expires = mtime + lifespan; + expires = req->bst.st_mtime + lifespan; req->lres += strftime(req->hres+req->lres,80, - "Expires: " RFCTIME "\r\n", + "Expires: " RFC1123 "\r\n", gmtime(&expires)); } } req->lres += strftime(req->hres+req->lres,80, - "Date: " RFCTIME "\r\n\r\n", + "Date: " RFC1123 "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER; if (debug) @@ -331,7 +329,7 @@ mkcgi(struct REQUEST *req, char *status, struct strlist *header) for (; NULL != header; header = header->next) req->lres += sprintf(req->hres+req->lres,"%s\r\n",header->line); req->lres += strftime(req->hres+req->lres,80, - "Date: " RFCTIME "\r\n\r\n", + "Date: " RFC1123 "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER; } @@ -263,7 +263,7 @@ access_log(struct REQUEST *req, time_t now) } /* common log format: host ident authuser date request status bytes */ - strftime(timestamp,31,"[%d/%b/%Y:%H:%M:%S +0000]",gmtime(&now)); + strftime(timestamp,31,"[%d/%b/%Y:%H:%M:%S +0000]",localtime(&now)); if (0 == req->status) req->status = 400; /* bad request */ if (400 == req->status) { @@ -561,9 +561,9 @@ header_parsing: access_log(req,now); /* cleanup */ req->auth[0] = 0; - req->if_modified = 0; - req->if_unmodified = 0; - req->if_range = 0; + req->if_modified = NULL; + req->if_unmodified = NULL; + req->if_range = NULL; req->range_hdr = NULL; req->ranges = 0; if (req->r_start) { free(req->r_start); req->r_start = NULL; } @@ -571,6 +571,7 @@ header_parsing: if (req->r_head) { free(req->r_head); req->r_head = NULL; } if (req->r_hlen) { free(req->r_hlen); req->r_hlen = NULL; } list_free(&req->header); + memset(req->mtime, 0, sizeof(req->mtime)); if (req->bfd != -1) { close(req->bfd); @@ -901,7 +902,6 @@ main(int argc, char *argv[]) /* init misc stuff */ init_mime(mimetypes,"text/plain"); init_quote(); - putenv("TZ=GMT"); tzset(); /* any better way to make mktime(3) use GMT ? */ #ifdef USE_SSL if (with_ssl) init_ssl(); |