From bdf554a3478f35de4f752cec8354d8ecd4d35913 Mon Sep 17 00:00:00 2001 From: "Fish (David B. Trout)" Date: Tue, 5 May 2026 14:56:00 -0700 Subject: [PATCH] FIX PR #837: Step 1 of 2: Revert previous revert This reverts c55ae94be308855b3a2197fb1a0d89ad0b248228, reinstating the original broken PR #837 code. --- httpmisc.h | 3 +-- httpserv.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/httpmisc.h b/httpmisc.h index 8fddd141..6db5763c 100644 --- a/httpmisc.h +++ b/httpmisc.h @@ -38,8 +38,6 @@ /*-------------------------------------------------------------------*/ -#define HTML_EXPIRE_SECS (60*60*24*7) - #define HTTP_WELCOME "hercules.html" #define HTML_HEADER "include/header.htmlpart" #define HTML_FOOTER "include/footer.htmlpart" @@ -90,6 +88,7 @@ struct WEBBLK char* request; char* baseurl; char* user; + time_t mod_time; // file modification time for downloads CGIVAR* cgivar; }; diff --git a/httpserv.c b/httpserv.c index 9ffab179..178b7b06 100644 --- a/httpserv.c +++ b/httpserv.c @@ -252,10 +252,12 @@ static void http_error(WEBBLK *webblk, char *err, char *header, char *info) /*-------------------------------------------------------------------*/ /* http_timestring */ /*-------------------------------------------------------------------*/ +static char *http_tfmt = "%a, %d %b %Y %H:%M:%S %Z"; + static char *http_timestring(char *time_buff,int buff_size, time_t t) { - struct tm *tm = localtime(&t); - strftime(time_buff, buff_size, "%a, %d %b %Y %H:%M:%S %Z", tm); + struct tm *tm = gmtime(&t); // HTTP standard defines GMT + strftime(time_buff, buff_size, http_tfmt, tm); return time_buff; } @@ -523,21 +525,29 @@ static void http_download(WEBBLK *webblk, char *filename) if (fd == -1) http_error(webblk, "404 File Not Found","", strerror(errno)); + + if (webblk->mod_time == st.st_mtime) + { + // browser copy still valid in cache + hprintf(webblk->sock, "HTTP/1.0 304 Not Modified\n"); + } + else + { + hprintf(webblk->sock,"HTTP/1.0 200 OK\n"); + if ((filetype = strrchr(filename,'.'))) + for(mime_type++;mime_type->suffix + && strcasecmp(mime_type->suffix,filetype + 1); + mime_type++); + if(mime_type->type) + hprintf(webblk->sock,"Content-Type: %s\n", mime_type->type); - hprintf(webblk->sock,"HTTP/1.0 200 OK\n"); - if ((filetype = strrchr(filename,'.'))) - for(mime_type++;mime_type->suffix - && strcasecmp(mime_type->suffix,filetype + 1); - mime_type++); - if(mime_type->type) - hprintf(webblk->sock,"Content-Type: %s\n", mime_type->type); + hprintf(webblk->sock,"Last-Modified: %s\n", + http_timestring(tbuf,sizeof(tbuf), st.st_mtime)); - hprintf(webblk->sock,"Expires: %s\n", - http_timestring(tbuf,sizeof(tbuf),time(NULL)+HTML_EXPIRE_SECS)); - - hprintf(webblk->sock,"Content-Length: %d\n\n", (int)st.st_size); - while ((length = read(fd, buffer, sizeof(buffer))) > 0) - hwrite(webblk->sock,buffer, length); + hprintf(webblk->sock,"Content-Length: %d\n\n", (int)st.st_size); + while ((length = read(fd, buffer, sizeof(buffer))) > 0) + hwrite(webblk->sock,buffer, length); + } close(fd); http_exit(webblk); } @@ -612,6 +622,18 @@ static void *http_request(void* arg) if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) content_length = atoi(pointer); } + else + if(!strcasecmp(pointer,"If-Modified-Since:")) + { + // save browser sent file last modification time, if any + struct tm browser_mod_time; + + // memset required as mktime queries full structure + memset(&browser_mod_time, 0, sizeof(struct tm)); + + if (strptime(strtok_str, http_tfmt, &browser_mod_time)) + webblk->mod_time = mktime(&browser_mod_time); + } } } webblk->request = url;