]> git.seodisparate.com - c_simple_http/commitdiff
Impl. cache file lifetime checking
authorStephen Seo <seo.disparate@gmail.com>
Thu, 26 Sep 2024 03:37:45 +0000 (12:37 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 26 Sep 2024 03:37:45 +0000 (12:37 +0900)
By default cache files are invalidated when the are aged for longer than
1 week. This "timeout-time" can be modified with a paramter/argument.

src/arg_parse.c
src/arg_parse.h
src/constants.h
src/html_cache.c
src/html_cache.h
src/http.c
src/http.h
src/main.c
src/test.c

index 7cb761191d90fc5d0a31efe97116b70dcf1ca4a2..7801ca2032a7fef3e2663ea34db2a1f19a6ccd2a 100644 (file)
@@ -29,6 +29,9 @@
 // Posix includes.
 #include <sys/stat.h>
 
+// Local includes.
+#include "constants.h"
+
 void print_usage(void) {
   puts("Usage:");
   puts("  -p <port> | --port <port>");
@@ -39,6 +42,7 @@ void print_usage(void) {
   puts("    Note that this option is case-insensitive");
   puts("  --enable-reload-config-on-change");
   puts("  --enable-cache-dir=<DIR>");
+  puts("  --cache-entry-lifetime-seconds=<SECONDS>");
 }
 
 Args parse_args(int32_t argc, char **argv) {
@@ -49,6 +53,7 @@ Args parse_args(int32_t argc, char **argv) {
   Args args;
   memset(&args, 0, sizeof(Args));
   args.list_of_headers_to_log = simple_archiver_list_init();
+  args.cache_lifespan_seconds = C_SIMPLE_HTTP_DEFAULT_CACHE_LIFESPAN_SECONDS;
 
   while (argc > 0) {
     if ((strcmp(argv[0], "-p") == 0 || strcmp(argv[0], "--port") == 0)
@@ -109,6 +114,20 @@ Args parse_args(int32_t argc, char **argv) {
         printf("Directory \"%s\" exists.\n", args.cache_dir);
       }
       closedir(d);
+    } else if (strncmp(argv[0], "--cache-entry-lifetime-seconds=", 31) == 0) {
+      args.cache_lifespan_seconds = strtoul(argv[0] + 31, NULL, 10);
+      if (args.cache_lifespan_seconds == 0) {
+        fprintf(
+          stderr,
+          "ERROR: Invalid --cache-entry-lifetime-seconds=%s entry!\n",
+          argv[0] + 31);
+        print_usage();
+        exit(1);
+      } else {
+        printf(
+          "NOTICE set cache-entry-lifetime to %lu\n",
+          args.cache_lifespan_seconds);
+      }
     } else {
       fprintf(stderr, "ERROR: Invalid args!\n");
       print_usage();
index c14ee905d254b81699f7ea4f538a1a34f5b0da5c..24ba5f7d7b7ce7caca31f1d38b944451841fdba3 100644 (file)
@@ -37,6 +37,7 @@ typedef struct Args {
   // Non-NULL if cache-dir is specified and cache is to be used.
   // Does not need to be free'd since it points to a string in argv.
   const char *cache_dir;
+  size_t cache_lifespan_seconds;
 } Args;
 
 void print_usage(void);
index c6ba24976f10f974bff682b7ef1e6bd6a0a4c216..b8d1ebf7045f1275ed97773c0ac0c74b7aa89a7e 100644 (file)
@@ -25,5 +25,6 @@
 #define C_SIMPLE_HTTP_CONFIG_BUF_SIZE 1024
 #define C_SIMPLE_HTTP_QUOTE_COUNT_MAX 3
 #define C_SIMPLE_HTTP_TRY_CONFIG_RELOAD_MAX_ATTEMPTS 20
+#define C_SIMPLE_HTTP_DEFAULT_CACHE_LIFESPAN_SECONDS 604800
 
 #endif
index 4ab6fabc23ff8c8bcd120e0ca8e0cb89d57e51e8..4b8403f1891345d1285a9797207503c935e5cba0 100644 (file)
@@ -25,6 +25,9 @@
 #include <sys/stat.h>
 #include <errno.h>
 
+// libc includes.
+#include <time.h>
+
 // Third-party includes.
 #include <SimpleArchiver/src/data_structures/linked_list.h>
 #include <SimpleArchiver/src/data_structures/hash_map.h>
@@ -208,6 +211,7 @@ int c_simple_http_cache_path(
     const char *config_filename,
     const char *cache_dir,
     C_SIMPLE_HTTP_HTTPTemplates *templates,
+    size_t cache_entry_lifespan,
     char **buf_out) {
   if (!path) {
     fprintf(stderr, "ERROR cache_path function: path is NULL!\n");
@@ -391,11 +395,17 @@ int c_simple_http_cache_path(
   }
 
   // Compare modification times.
+  struct timespec current_time;
+  if (clock_gettime(CLOCK_REALTIME, &current_time) != 0) {
+    memset(&current_time, 0, sizeof(struct timespec));
+  }
 CACHE_FILE_WRITE_CHECK:
   if (force_cache_update
       || cache_file_stat.st_mtim.tv_sec < config_file_stat.st_mtim.tv_sec
       || (cache_file_stat.st_mtim.tv_sec == config_file_stat.st_mtim.tv_sec
-         && cache_file_stat.st_mtim.tv_nsec < config_file_stat.st_mtim.tv_nsec))
+         && cache_file_stat.st_mtim.tv_nsec < config_file_stat.st_mtim.tv_nsec)
+      || (current_time.tv_sec - cache_file_stat.st_mtim.tv_sec
+         > (ssize_t)cache_entry_lifespan))
   {
     // Cache file is out of date.
 
index ebaa3850b1caf490cf313d3787dd66b4cea68421..516742554b037da9ff726670c4696cf7c84e2222 100644 (file)
@@ -37,6 +37,7 @@ int c_simple_http_cache_path(
   const char *config_filename,
   const char *cache_dir,
   C_SIMPLE_HTTP_HTTPTemplates *templates,
+  size_t cache_entry_lifespan,
   char **buf_out);
 
 #endif
index 9ced3989564681cac99aea512b1f6a2e0de21927..0e688aa143dce2ac4106b878a2f18bff6882b646 100644 (file)
@@ -65,8 +65,7 @@ char *c_simple_http_request_response(
     C_SIMPLE_HTTP_HTTPTemplates *templates,
     size_t *out_size,
     enum C_SIMPLE_HTTP_ResponseCode *out_response_code,
-    const char *cache_dir,
-    const char *config_filename) {
+    const Args *args) {
   if (out_size) {
     *out_size = 0;
   }
@@ -177,12 +176,13 @@ char *c_simple_http_request_response(
 
   char *generated_buf = NULL;
 
-  if (cache_dir) {
+  if (args->cache_dir) {
     int ret = c_simple_http_cache_path(
       stripped_path ? stripped_path : request_path_unescaped,
-      config_filename,
-      cache_dir,
+      args->config_file,
+      args->cache_dir,
       templates,
+      args->cache_lifespan_seconds,
       &generated_buf);
     if (ret < 0) {
       fprintf(stderr, "ERROR Failed to generate template with cache!\n");
index 87618c425151ecaf9b8ffaa403f9fc9422c51483..7b7a52a9a57ca9be00f1047432865218ca070a66 100644 (file)
@@ -25,6 +25,7 @@
 #include <SimpleArchiver/src/data_structures/hash_map.h>
 
 // Local includes.
+#include "arg_parse.h"
 #include "config.h"
 
 typedef C_SIMPLE_HTTP_ParsedConfig C_SIMPLE_HTTP_HTTPTemplates;
@@ -49,8 +50,7 @@ char *c_simple_http_request_response(
   C_SIMPLE_HTTP_HTTPTemplates *templates,
   size_t *out_size,
   enum C_SIMPLE_HTTP_ResponseCode *out_response_code,
-  const char *cache_dir,
-  const char *config_filename
+  const Args *args
 );
 
 /// Takes a PATH string and returns a "bare" path.
index 9c9f51c298cda06433e717917c4e3612230a2db5..976f245ac06e314ed4306e298213b329853bed53 100644 (file)
@@ -360,8 +360,7 @@ int main(int argc, char **argv) {
         &parsed_config,
         &response_size,
         &response_code,
-        args.cache_dir,
-        args.config_file);
+        &args);
       if (response && response_code == C_SIMPLE_HTTP_Response_200_OK) {
         CHECK_ERROR_WRITE(write(connection_fd, "HTTP/1.1 200 OK\n", 16));
         CHECK_ERROR_WRITE(write(connection_fd, "Allow: GET\n", 11));
index b3976792b1de313a3178d53fa8baecb920ba0982..d47079f4af053f22fce1a2fa145c452e40f97d24 100644 (file)
@@ -15,6 +15,7 @@
 #include "http_template.h"
 #include "http.h"
 #include "html_cache.h"
+#include "constants.h"
 
 // Third party includes.
 #include <SimpleArchiver/src/helpers.h>
@@ -808,6 +809,7 @@ int main(void) {
       test_http_template_filename5,
       "/tmp/c_simple_http_cache_dir",
       &templates,
+      0xFFFFFFFF,
       &buf);
 
     CHECK_TRUE(int_ret > 0);
@@ -830,6 +832,7 @@ int main(void) {
       test_http_template_filename5,
       "/tmp/c_simple_http_cache_dir",
       &templates,
+      0xFFFFFFFF,
       &buf);
     CHECK_TRUE(int_ret == 0);
     ASSERT_TRUE(buf);
@@ -870,6 +873,7 @@ int main(void) {
       test_http_template_filename5,
       "/tmp/c_simple_http_cache_dir",
       &templates,
+      0xFFFFFFFF,
       &buf);
     CHECK_TRUE(int_ret > 0);
     ASSERT_TRUE(buf);
@@ -892,6 +896,7 @@ int main(void) {
       test_http_template_filename5,
       "/tmp/c_simple_http_cache_dir",
       &templates,
+      0xFFFFFFFF,
       &buf);
     CHECK_TRUE(int_ret == 0);
     ASSERT_TRUE(buf);
@@ -909,6 +914,10 @@ int main(void) {
     CHECK_TRUE(cache_file_size_2 == cache_file_size_3);
 
     // Edit config file.
+    puts("Sleeping for two seconds to ensure edited file's timestamp has "
+      "changed...");
+    sleep(2);
+    puts("Done sleeping.");
     test_file = fopen(test_http_template_filename5, "w");
     ASSERT_TRUE(test_file);
 
@@ -935,6 +944,24 @@ int main(void) {
       test_http_template_filename5,
       "/tmp/c_simple_http_cache_dir",
       &templates,
+      0xFFFFFFFF,
+      &buf);
+    CHECK_TRUE(int_ret > 0);
+    ASSERT_TRUE(buf);
+    CHECK_TRUE(strcmp(buf, "<h1>Alternate test text.<br>Yep.</h1>") == 0);
+    free(buf);
+    buf = NULL;
+
+    puts("Sleeping for two seconds to ensure cache file has aged...");
+    sleep(2);
+    puts("Done sleeping.");
+    // Re-run cache function, checking that it is invalidated.
+    int_ret = c_simple_http_cache_path(
+      "/",
+      test_http_template_filename5,
+      "/tmp/c_simple_http_cache_dir",
+      &templates,
+      1,
       &buf);
     CHECK_TRUE(int_ret > 0);
     ASSERT_TRUE(buf);