Impl. cache file lifetime checking

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.
This commit is contained in:
Stephen Seo 2024-09-26 12:37:45 +09:00
parent 9459ec9313
commit 700adf2f7b
9 changed files with 68 additions and 10 deletions

View 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();

View 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);

View 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

View 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.

View 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

View 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");

View 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.

View 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));

View 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);