Compare commits

...

4 commits

Author SHA1 Message Date
6d5a1d1bdd Minor fix
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 8s
2024-09-22 14:43:28 +09:00
ffc8e99f73 Add new arg for program: --enable-cache-dir=<DIR> 2024-09-22 14:42:41 +09:00
55d3a61c0c Update .gitignore 2024-09-22 14:26:50 +09:00
7a8582faac Change template generation: output used filenames 2024-09-22 14:26:07 +09:00
7 changed files with 117 additions and 12 deletions

2
.gitignore vendored
View file

@ -2,3 +2,5 @@
/objs/ /objs/
/unit_test /unit_test
/build*/ /build*/
/.cache/
/compile_commands.json

View file

@ -21,6 +21,14 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
// libc includes.
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
// Posix includes.
#include <sys/stat.h>
void print_usage(void) { void print_usage(void) {
puts("Usage:"); puts("Usage:");
puts(" -p <port> | --port <port>"); puts(" -p <port> | --port <port>");
@ -30,6 +38,7 @@ void print_usage(void) {
puts(" For example: --req-header-to-print=User-Agent"); puts(" For example: --req-header-to-print=User-Agent");
puts(" Note that this option is case-insensitive"); puts(" Note that this option is case-insensitive");
puts(" --enable-reload-config-on-change"); puts(" --enable-reload-config-on-change");
puts(" --enable-cache-dir=<DIR>");
} }
Args parse_args(int32_t argc, char **argv) { Args parse_args(int32_t argc, char **argv) {
@ -69,8 +78,38 @@ Args parse_args(int32_t argc, char **argv) {
} }
} else if (strcmp(argv[0], "--enable-reload-config-on-change") == 0) { } else if (strcmp(argv[0], "--enable-reload-config-on-change") == 0) {
args.flags |= 2; args.flags |= 2;
} else if (strncmp(argv[0], "--enable-cache-dir=", 19) == 0) {
args.cache_dir = argv[0] + 19;
// Check if it actually is an existing directory.
DIR *d = opendir(args.cache_dir);
if (d == NULL) {
if (errno == ENOENT) {
printf(
"Directory \"%s\" doesn't exist, creating it...\n",
args.cache_dir);
int ret = mkdir(
args.cache_dir,
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (ret == -1) {
fprintf(
stderr,
"ERROR Failed to create new directory (errno %d)\n",
errno);
exit(1);
}
} else {
fprintf(
stderr,
"ERROR Failed to open directory \"%s\" (errno %d)!\n",
args.cache_dir,
errno);
exit(1);
}
} else {
printf("Directory \"%s\" exists.\n", args.cache_dir);
}
} else { } else {
puts("ERROR: Invalid args!\n"); fprintf(stderr, "ERROR: Invalid args!\n");
print_usage(); print_usage();
exit(1); exit(1);
} }

View file

@ -34,6 +34,9 @@ typedef struct Args {
const char *config_file; const char *config_file;
// Needs to be free'd. // Needs to be free'd.
SDArchiverLinkedList *list_of_headers_to_log; SDArchiverLinkedList *list_of_headers_to_log;
// 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;
} Args; } Args;
void print_usage(void); void print_usage(void);

View file

@ -162,7 +162,8 @@ char *c_simple_http_request_response(
char *generated_buf = c_simple_http_path_to_generated( char *generated_buf = c_simple_http_path_to_generated(
stripped_path ? stripped_path : request_path, stripped_path ? stripped_path : request_path,
templates, templates,
&generated_size); &generated_size,
NULL); // TODO Use the output parameter "filenames list" here.
if (!generated_buf || generated_size == 0) { if (!generated_buf || generated_size == 0) {
fprintf(stderr, "ERROR Unable to generate response html for path \"%s\"!\n", fprintf(stderr, "ERROR Unable to generate response html for path \"%s\"!\n",

View file

@ -96,10 +96,14 @@ int c_simple_http_internal_ends_with_FILE(const char *c_string) {
char *c_simple_http_path_to_generated( char *c_simple_http_path_to_generated(
const char *path, const char *path,
const C_SIMPLE_HTTP_HTTPTemplates *templates, const C_SIMPLE_HTTP_HTTPTemplates *templates,
size_t *output_buf_size) { size_t *output_buf_size,
SDArchiverLinkedList **files_list_out) {
if (output_buf_size) { if (output_buf_size) {
*output_buf_size = 0; *output_buf_size = 0;
} }
if (files_list_out) {
*files_list_out = simple_archiver_list_init();
}
size_t path_len_size_t = strlen(path) + 1; size_t path_len_size_t = strlen(path) + 1;
if (path_len_size_t > 0xFFFFFFFF) { if (path_len_size_t > 0xFFFFFFFF) {
fprintf(stderr, "ERROR: Path string is too large!\n"); fprintf(stderr, "ERROR: Path string is too large!\n");
@ -139,6 +143,11 @@ char *c_simple_http_path_to_generated(
} }
html_buf[html_file_size] = 0; html_buf[html_file_size] = 0;
html_buf_size = (size_t)html_file_size; html_buf_size = (size_t)html_file_size;
if (files_list_out) {
char *html_filename_copy = malloc(strlen(html_filename) + 1);
strcpy(html_filename_copy, html_filename);
simple_archiver_list_add(*files_list_out, html_filename_copy, NULL);
}
} else { } else {
char *stored_html = char *stored_html =
simple_archiver_hash_map_get(wrapped_hash_map->hash_map, "HTML", 5); simple_archiver_hash_map_get(wrapped_hash_map->hash_map, "HTML", 5);
@ -258,6 +267,12 @@ char *c_simple_http_path_to_generated(
value_c_str); value_c_str);
return NULL; return NULL;
} }
if (files_list_out) {
char *variable_filename = malloc(strlen(value_c_str) + 1);
strcpy(variable_filename, value_c_str);
simple_archiver_list_add(
*files_list_out, variable_filename, NULL);
}
} else { } else {
// Variable data is "value_c_str". // Variable data is "value_c_str".
template_node = template_node =

View file

@ -22,14 +22,20 @@
// Standard library includes. // Standard library includes.
#include <stddef.h> #include <stddef.h>
// Returns non-NULL on success, which must be free'd after use. // Third-party includes.
// Takes a path string and templates and returns the generated HTML. #include <SimpleArchiver/src/data_structures/linked_list.h>
// If "output_buf_size" is non-NULL, it will be set to the size of the returned
// buffer. // Returns non-NULL on success, which must be free'd after use. Takes a path
// string and templates and returns the generated HTML. If "output_buf_size" is
// non-NULL, it will be set to the size of the returned buffer. If
// "files_list_out" is non-NULL, then the pointer will be set to a newly
// allocated linked-list containing filenames used in generating the HTML. This
// newly allocated linked-list must be freed after use.
char *c_simple_http_path_to_generated( char *c_simple_http_path_to_generated(
const char *path, const char *path,
const C_SIMPLE_HTTP_HTTPTemplates *templates, const C_SIMPLE_HTTP_HTTPTemplates *templates,
size_t *output_buf_size); size_t *output_buf_size,
SDArchiverLinkedList **files_list_out);
#endif #endif

View file

@ -5,6 +5,7 @@
#include <stdint.h> #include <stdint.h>
// Local includes. // Local includes.
#include "SimpleArchiver/src/data_structures/linked_list.h"
#include "config.h" #include "config.h"
#include "http_template.h" #include "http_template.h"
#include "http.h" #include "http.h"
@ -89,6 +90,15 @@ void test_internal_cleanup_delete_temporary_file(const char **filename) {
} }
} }
int test_internal_check_matching_string_in_list(void *value, void *ud) {
if (value && ud) {
if (strcmp(value, ud) == 0) {
return 1;
}
}
return 0;
}
int main(void) { int main(void) {
// Test config. // Test config.
{ {
@ -252,12 +262,18 @@ int main(void) {
size_t output_buf_size; size_t output_buf_size;
__attribute__((cleanup(simple_archiver_list_free)))
SDArchiverLinkedList *filenames_list = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string))) __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *buf = c_simple_http_path_to_generated("/", &config, &output_buf_size); char *buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
ASSERT_TRUE(strcmp(buf, "<h1>Test</h1>") == 0); ASSERT_TRUE(strcmp(buf, "<h1>Test</h1>") == 0);
CHECK_TRUE(output_buf_size == 13); CHECK_TRUE(output_buf_size == 13);
CHECK_TRUE(filenames_list->count == 0);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
simple_archiver_list_free(&filenames_list);
__attribute__((cleanup(test_internal_cleanup_delete_temporary_file))) __attribute__((cleanup(test_internal_cleanup_delete_temporary_file)))
const char *test_http_template_filename2 = const char *test_http_template_filename2 =
@ -288,7 +304,8 @@ int main(void) {
); );
ASSERT_TRUE(config.paths != NULL); ASSERT_TRUE(config.paths != NULL);
buf = c_simple_http_path_to_generated("/", &config, &output_buf_size); buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
printf("%s\n", buf); printf("%s\n", buf);
ASSERT_TRUE( ASSERT_TRUE(
@ -297,7 +314,9 @@ int main(void) {
"<h1> Some text. </h1><br><h2> More text. </h2>") "<h1> Some text. </h1><br><h2> More text. </h2>")
== 0); == 0);
CHECK_TRUE(output_buf_size == 46); CHECK_TRUE(output_buf_size == 46);
CHECK_TRUE(filenames_list->count == 0);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
simple_archiver_list_free(&filenames_list);
__attribute__((cleanup(test_internal_cleanup_delete_temporary_file))) __attribute__((cleanup(test_internal_cleanup_delete_temporary_file)))
const char *test_http_template_filename3 = const char *test_http_template_filename3 =
@ -351,7 +370,8 @@ int main(void) {
); );
ASSERT_TRUE(config.paths != NULL); ASSERT_TRUE(config.paths != NULL);
buf = c_simple_http_path_to_generated("/", &config, &output_buf_size); buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
printf("%s\n", buf); printf("%s\n", buf);
ASSERT_TRUE( ASSERT_TRUE(
@ -360,7 +380,14 @@ int main(void) {
"<h1> testVar text. </h1><br><h2> testVar2 text. </h2>") "<h1> testVar text. </h1><br><h2> testVar2 text. </h2>")
== 0); == 0);
CHECK_TRUE(output_buf_size == 53); CHECK_TRUE(output_buf_size == 53);
CHECK_TRUE(filenames_list->count == 1);
CHECK_TRUE(simple_archiver_list_get(
filenames_list,
test_internal_check_matching_string_in_list,
(void*)test_http_template_html_filename)
!= NULL);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
simple_archiver_list_free(&filenames_list);
__attribute__((cleanup(test_internal_cleanup_delete_temporary_file))) __attribute__((cleanup(test_internal_cleanup_delete_temporary_file)))
const char *test_http_template_filename4 = const char *test_http_template_filename4 =
@ -434,7 +461,8 @@ int main(void) {
); );
ASSERT_TRUE(config.paths != NULL); ASSERT_TRUE(config.paths != NULL);
buf = c_simple_http_path_to_generated("/", &config, &output_buf_size); buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL); ASSERT_TRUE(buf != NULL);
printf("%s\n", buf); printf("%s\n", buf);
ASSERT_TRUE( ASSERT_TRUE(
@ -443,6 +471,17 @@ int main(void) {
"<h1> some test text in test var file. </h1>") "<h1> some test text in test var file. </h1>")
== 0); == 0);
CHECK_TRUE(output_buf_size == 43); CHECK_TRUE(output_buf_size == 43);
CHECK_TRUE(filenames_list->count == 2);
CHECK_TRUE(simple_archiver_list_get(
filenames_list,
test_internal_check_matching_string_in_list,
(void*)test_http_template_html_filename2)
!= NULL);
CHECK_TRUE(simple_archiver_list_get(
filenames_list,
test_internal_check_matching_string_in_list,
(void*)test_http_template_html_var_filename)
!= NULL);
simple_archiver_helper_cleanup_c_string(&buf); simple_archiver_helper_cleanup_c_string(&buf);
} }