diff --git a/dist/antd-1.0.4b.tar.gz b/dist/antd-1.0.4b.tar.gz index dbf02c8..0cfed59 100644 Binary files a/dist/antd-1.0.4b.tar.gz and b/dist/antd-1.0.4b.tar.gz differ diff --git a/http_server.c b/http_server.c index 7e9570b..d371df3 100644 --- a/http_server.c +++ b/http_server.c @@ -39,6 +39,9 @@ void error_log(const char* fmt, ...) va_end(arguments); if ((data = (char*)malloc(dlen*sizeof(char))) != 0) { + char buf[64]; + server_time(buf,64); + fwrite(buf,strlen(buf),1,server_config.errorfp); va_start(arguments, fmt); vsnprintf(data, dlen, fmt, arguments); va_end(arguments); @@ -62,6 +65,9 @@ void server_log(const char* fmt, ...) va_end(arguments); if ((data = (char*)malloc(dlen*sizeof(char))) != 0) { + char buf[64]; + server_time(buf,64); + fwrite(buf,strlen(buf),1,server_config.logfp); va_start(arguments, fmt); vsnprintf(data, dlen, fmt, arguments); va_end(arguments); @@ -670,10 +676,7 @@ void *serve_file(void *data) task->priority++; char *path = (char *)dvalue(rq->request, "ABS_RESOURCE_PATH"); char *mime_type = (char *)dvalue(rq->request, "RESOURCE_MIME"); - // find content length - /*if (is_bin(path)) - __fb(rq->client, path); - else*/ + struct stat st; int s = stat(path, &st); @@ -683,19 +686,43 @@ void *serve_file(void *data) } else { - int size = (int)st.st_size; - char ibuf[20]; - snprintf (ibuf, sizeof(ibuf), "%d",size); - antd_response_header_t rhd; - rhd.cookie = NULL; - rhd.status = 200; - rhd.header = dict(); - dput(rhd.header, "Content-Type", strdup(mime_type)); - if(!compressable(mime_type) || rq->client->z_level == ANTD_CNONE) - dput(rhd.header, "Content-Length", strdup(ibuf)); - antd_send_header(rq->client, &rhd); + // check if it is modified + dictionary_t header = (dictionary_t)dvalue(rq->request, "REQUEST_HEADER"); + char * last_modif_since = (char*)dvalue(header, "If-Modified-Since"); + time_t t = st.st_ctime; + struct tm tm; + if(last_modif_since) + { + strptime(last_modif_since, "%a, %d %b %Y %H:%M:%S GMT", &tm); + t = timegm(&tm); + //t = mktime(localtime(&t)); + } - __f(rq->client, path); + if(last_modif_since && st.st_ctime == t) + { + // return the not changed + antd_error(rq->client,304, ""); + } + else + { + int size = (int)st.st_size; + char ibuf[64]; + snprintf (ibuf, sizeof(ibuf), "%d",size); + antd_response_header_t rhd; + rhd.cookie = NULL; + rhd.status = 200; + rhd.header = dict(); + dput(rhd.header, "Content-Type", strdup(mime_type)); + if(!compressable(mime_type) || rq->client->z_level == ANTD_CNONE) + dput(rhd.header, "Content-Length", strdup(ibuf)); + gmtime_r(&st.st_ctime, &tm); + strftime(ibuf, 255, "%a, %d %b %Y %H:%M:%S GMT", &tm); + dput(rhd.header, "Last-Modified", strdup(ibuf)); + dput(rhd.header, "Cache-Control", strdup("no-cache")); + antd_send_header(rq->client, &rhd); + + __f(rq->client, path); + } } return task; diff --git a/lib/utils.c b/lib/utils.c index 4f02754..377b4b8 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -85,19 +85,26 @@ void removeAll(const char* path,int mode) } -char* __time(time_t time) -{ - struct tm *t = localtime(&time); - char * buf = asctime(t); - char* pos = strchr(buf,'\n'); - if(pos) *pos = '\0'; - return buf; -} -char* server_time() -{ - return __time(time(NULL)); -} +// WARNING: +// TODO: remove it, this function is not thread-safe +void timestr(time_t time, char* buf,int len,char* format, int gmt) +{ + struct tm t; + if(gmt) + { + gmtime_r(&time, &t); + } + else + { + localtime_r(&time, &t); + } + strftime(buf, len, format, &t); +} +void server_time(char* buf, int len) +{ + timestr(time(NULL), buf, len ,"%a, %d %b %Y %H:%M:%S", 0); +} /** * Get extension of a file name * @param file The file name diff --git a/lib/utils.h b/lib/utils.h index b92bb40..f475b97 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -56,12 +56,12 @@ THE SOFTWARE. #define false 0 #ifdef DEBUG - #define LOG(a,...) server_log("%s: [%s: %d]: " a "\n",server_time(), __FILE__, \ + #define LOG(a,...) server_log(": [%s: %d]: " a "\n", __FILE__, \ __LINE__, ##__VA_ARGS__) #else #define LOG(a,...) do{}while(0) #endif -#define ERROR(a,...) error_log("%s: [%s: %d]: " a "\n", server_time() , __FILE__, \ +#define ERROR(a,...) error_log(": [%s: %d]: " a "\n", __FILE__, \ __LINE__, ##__VA_ARGS__) // add this to the utils #define UNUSED(x) (void)(x) @@ -83,8 +83,8 @@ dictionary_t __attribute__((weak)) mimes_list(); char* __s(const char*,...); void trim(char*,const char); void removeAll(const char* path,int mode); -char* __time(time_t time); -char* server_time(); +void timestr(time_t time, char* buf,int len,char* format, int gmt); +void server_time(char* , int ); char* ext(const char*); char* mime(const char*); int match_int(const char*);