|  | @@ -749,6 +749,20 @@ static void sockaddr_to_string(char *buf, size_t len,
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be included in all responses other than 100, 101, 5xx. */
 | 
	
		
			
				|  |  | +static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    struct tm *tm;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    tm = gmtime(t);
 | 
	
		
			
				|  |  | +    if (tm != NULL) {
 | 
	
		
			
				|  |  | +        strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +        strncpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
 | 
	
		
			
				|  |  | +        buf[buf_len - 1] = '\0';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /* Print error message to the opened error log stream. */
 | 
	
		
			
				|  |  |  void mg_cry(struct mg_connection *conn, const char *fmt, ...)
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -2232,7 +2246,7 @@ int mg_get_cookie(const char *cookie_header, const char *var_name,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void convert_uri_to_file_name(struct mg_connection *conn, char *buf,
 | 
	
		
			
				|  |  | -                                     size_t buf_len, struct file *filep, 
 | 
	
		
			
				|  |  | +                                     size_t buf_len, struct file *filep,
 | 
	
		
			
				|  |  |                                       int * is_script_ressource)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      struct vec a, b;
 | 
	
	
		
			
				|  | @@ -3163,6 +3177,8 @@ static void handle_directory_request(struct mg_connection *conn,
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      int i, sort_direction;
 | 
	
		
			
				|  |  |      struct dir_scan_data data = { NULL, 0, 128 };
 | 
	
		
			
				|  |  | +    char date[64];
 | 
	
		
			
				|  |  | +    time_t curtime = time(NULL);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if (!scan_directory(conn, dir, &data, dir_scan_callback)) {
 | 
	
		
			
				|  |  |          send_http_error(conn, 500, "Cannot open directory",
 | 
	
	
		
			
				|  | @@ -3170,14 +3186,17 @@ static void handle_directory_request(struct mg_connection *conn,
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    gmt_time_string(date, sizeof(date), &curtime);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      sort_direction = conn->request_info.query_string != NULL &&
 | 
	
		
			
				|  |  |                       conn->request_info.query_string[1] == 'd' ? 'a' : 'd';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      conn->must_close = 1;
 | 
	
		
			
				|  |  | -    mg_printf(conn, "%s",
 | 
	
		
			
				|  |  | -              "HTTP/1.1 200 OK\r\n"
 | 
	
		
			
				|  |  | -              "Connection: close\r\n"
 | 
	
		
			
				|  |  | -              "Content-Type: text/html; charset=utf-8\r\n\r\n");
 | 
	
		
			
				|  |  | +    mg_printf(conn, "HTTP/1.1 200 OK\r\n"
 | 
	
		
			
				|  |  | +                    "Date: %s\r\n"
 | 
	
		
			
				|  |  | +                    "Connection: close\r\n"
 | 
	
		
			
				|  |  | +                    "Content-Type: text/html; charset=utf-8\r\n\r\n",
 | 
	
		
			
				|  |  | +                    date);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      conn->num_bytes_sent += mg_printf(conn,
 | 
	
		
			
				|  |  |                                        "<html><head><title>Index of %s</title>"
 | 
	
	
		
			
				|  | @@ -3260,19 +3279,6 @@ static int parse_range_header(const char *header, int64_t *a, int64_t *b)
 | 
	
		
			
				|  |  |      return sscanf(header, "bytes=%" INT64_FMT "-%" INT64_FMT, a, b);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    struct tm *tm;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    tm = gmtime(t);
 | 
	
		
			
				|  |  | -    if (tm != NULL) {
 | 
	
		
			
				|  |  | -        strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
 | 
	
		
			
				|  |  | -    } else {
 | 
	
		
			
				|  |  | -        strncpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
 | 
	
		
			
				|  |  | -        buf[buf_len - 1] = '\0';
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  static void construct_etag(char *buf, size_t buf_len,
 | 
	
		
			
				|  |  |                             const struct file *filep)
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -4189,16 +4195,21 @@ static void handle_ssi_file_request(struct mg_connection *conn,
 | 
	
		
			
				|  |  |                                      const char *path)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      struct file file = STRUCT_FILE_INITIALIZER;
 | 
	
		
			
				|  |  | +    char date[64];
 | 
	
		
			
				|  |  | +    time_t curtime = time(NULL);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if (!mg_fopen(conn, path, "rb", &file)) {
 | 
	
		
			
				|  |  |          send_http_error(conn, 500, http_500_error, "fopen(%s): %s", path,
 | 
	
		
			
				|  |  |                          strerror(ERRNO));
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  |          conn->must_close = 1;
 | 
	
		
			
				|  |  | +        gmt_time_string(date, sizeof(date), &curtime);
 | 
	
		
			
				|  |  |          fclose_on_exec(&file, conn);
 | 
	
		
			
				|  |  |          mg_printf(conn, "HTTP/1.1 200 OK\r\n"
 | 
	
		
			
				|  |  | -                  "Content-Type: text/html\r\nConnection: %s\r\n\r\n",
 | 
	
		
			
				|  |  | -                  suggest_connection_header(conn));
 | 
	
		
			
				|  |  | +                        "Date: %s\r\n"
 | 
	
		
			
				|  |  | +                        "Content-Type: text/html\r\n"
 | 
	
		
			
				|  |  | +                        "Connection: %s\r\n\r\n",
 | 
	
		
			
				|  |  | +                  date, suggest_connection_header(conn));
 | 
	
		
			
				|  |  |          send_ssi_file(conn, path, &file, 0);
 | 
	
		
			
				|  |  |          mg_fclose(&file);
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -5179,7 +5190,7 @@ static void handle_request(struct mg_connection *conn)
 | 
	
		
			
				|  |  |      } else if (match_prefix(conn->ctx->config[CGI_EXTENSIONS],
 | 
	
		
			
				|  |  |                              (int)strlen(conn->ctx->config[CGI_EXTENSIONS]),
 | 
	
		
			
				|  |  |                              path) > 0) {
 | 
	
		
			
				|  |  | -        /* TODO: check unsupported methods -> 501 
 | 
	
		
			
				|  |  | +        /* TODO: check unsupported methods -> 501
 | 
	
		
			
				|  |  |          if (strcmp(ri->request_method, "POST") &&
 | 
	
		
			
				|  |  |              strcmp(ri->request_method, "HEAD") &&
 | 
	
		
			
				|  |  |              strcmp(ri->request_method, "GET")) {
 |