]> git.seodisparate.com - c_simple_http/commitdiff
Impl. ".*_FILE" variables for templates
authorStephen Seo <seo.disparate@gmail.com>
Thu, 5 Sep 2024 05:02:25 +0000 (14:02 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 5 Sep 2024 05:02:25 +0000 (14:02 +0900)
If there exists a "{{{something_FILE}}}" (a variable ending with
"_FILE"), then the loaded variable will be treated as a filename and its
contents will be put in the html template.

src/http_template.c
src/test.c

index 091eb135c5129f74c4c0f7ffdd653f1ca6119d96..5b6e21d44cc81a5421a55c99539b44cd50210f49 100644 (file)
@@ -76,6 +76,26 @@ int c_simple_http_internal_fill_buf_fn(void *data, void *ud) {
   return 0;
 }
 
+/// Returns 0 if "c_string" ends with "_FILE".
+int c_simple_http_internal_ends_with_FILE(const char *c_string) {
+  if (!c_string) {
+    return 1;
+  }
+
+  const char *comparison_string = "_FILE";
+
+  const size_t c_string_size = strlen(c_string);
+
+  if (strcmp(
+      comparison_string,
+      c_string + (c_string_size - strlen(comparison_string)))
+        == 0) {
+    return 0;
+  }
+
+  return 2;
+}
+
 char *c_simple_http_path_to_generated(
     const char *path,
     const C_SIMPLE_HTTP_HTTPTemplates *templates) {
@@ -192,17 +212,58 @@ char *c_simple_http_path_to_generated(
               wrapped_hash_map->hash_map,
               var,
               var_size + 1);
-          // TODO Impl. loading from file instead of directly from value.
-          // Perhaps do this if "var" ends with "_FILE".
           if (value_c_str) {
-            template_node =
-              malloc(sizeof(C_SIMPLE_HTTP_INTERNAL_Template_Node));
-            size_t size = strlen(value_c_str);
-            template_node->html = malloc(size);
-            memcpy(template_node->html, value_c_str, size);
-            template_node->html_size = size;
-            template_node->orig_end_idx = idx + 1;
-            template_node->forced_next = NULL;
+            if (c_simple_http_internal_ends_with_FILE(var) == 0) {
+              // Load from file specified by "value_c_str".
+              __attribute__((cleanup(simple_archiver_helper_cleanup_FILE)))
+              FILE *f = fopen(value_c_str, "r");
+              if (!f) {
+                fprintf(stderr, "ERROR Failed to open file \"%s\"!\n",
+                        value_c_str);
+                return NULL;
+              } else if (fseek(f, 0, SEEK_END) != 0) {
+                fprintf(stderr, "ERROR Failed to seek to end of file \"%s\"!\n",
+                        value_c_str);
+                return NULL;
+              }
+              long file_size = ftell(f);
+              if (file_size <= 0) {
+                fprintf(stderr, "ERROR Size of file \"%s\" is invalid!\n",
+                        value_c_str);
+                return NULL;
+              } else if (fseek(f, 0, SEEK_SET) != 0) {
+                fprintf(stderr, "ERROR Failed to seek to start of file "
+                        "\"%s\"!\n",
+                        value_c_str);
+                return NULL;
+              }
+              template_node =
+                malloc(sizeof(C_SIMPLE_HTTP_INTERNAL_Template_Node));
+              template_node->html_size = (size_t)file_size;
+              template_node->html = malloc(template_node->html_size);
+              template_node->orig_end_idx = idx + 1;
+              template_node->forced_next = NULL;
+
+              if (fread(template_node->html,
+                        template_node->html_size,
+                        1,
+                        f)
+                    != 1) {
+                fprintf(stderr, "ERROR Failed to read from file \"%s\"!\n",
+                        value_c_str);
+                return NULL;
+              }
+            } else {
+              // Variable data is "value_c_str".
+              template_node =
+                malloc(sizeof(C_SIMPLE_HTTP_INTERNAL_Template_Node));
+              size_t size = strlen(value_c_str);
+              template_node->html = malloc(size);
+              memcpy(template_node->html, value_c_str, size);
+              template_node->html_size = size;
+              template_node->orig_end_idx = idx + 1;
+              template_node->forced_next = NULL;
+            }
           } else {
             template_node =
               malloc(sizeof(C_SIMPLE_HTTP_INTERNAL_Template_Node));
index 661540e4b78e79d430a4c5a02ede4a96cd45554c..cdfebbeb19a42de47cc8d74b370c0bb743cbc564 100644 (file)
@@ -341,6 +341,85 @@ int main(void) {
         "<h1> testVar text. </h1><br><h2> testVar2 text. </h2>")
       == 0);
     simple_archiver_helper_cleanup_c_string(&buf);
+
+    const char *test_http_template_filename4 =
+      "/tmp/c_simple_http_template_test4.config";
+    const char *test_http_template_html_filename2 =
+      "/tmp/c_simple_http_template_test2.html";
+    const char *test_http_template_html_var_filename =
+      "/tmp/c_simple_http_template_test_var.html";
+    test_file = fopen(test_http_template_filename4, "w");
+    ASSERT_TRUE(test_file);
+
+    ASSERT_TRUE(
+        fwrite(
+          "PATH=/\nHTML_FILE=/tmp/c_simple_http_template_test2.html\n",
+          1,
+          56,
+          test_file)
+        == 56);
+    ASSERT_TRUE(
+        fwrite(
+          "testVar_FILE=/tmp/c_simple_http_template_test_var.html\n",
+          1,
+          55,
+          test_file)
+        == 55);
+    simple_archiver_helper_cleanup_FILE(&test_file);
+
+    test_file = fopen(test_http_template_html_filename2, "w");
+    ASSERT_TRUE(test_file);
+
+    ASSERT_TRUE(
+        fwrite(
+          "<h1>{{{testVar_FILE}}}</h1>",
+          1,
+          27,
+          test_file)
+        == 27);
+    simple_archiver_helper_cleanup_FILE(&test_file);
+
+    test_file = fopen(test_http_template_html_var_filename, "w");
+    ASSERT_TRUE(test_file);
+
+    ASSERT_TRUE(
+        fwrite(
+          " some test text in test var file. ",
+          1,
+          34,
+          test_file)
+        == 34);
+    simple_archiver_helper_cleanup_FILE(&test_file);
+
+    simple_archiver_list_free(&required_names);
+    required_names = simple_archiver_list_init();
+    simple_archiver_list_add(
+      required_names,
+      "HTML_FILE",
+      simple_archiver_helper_datastructure_cleanup_nop);
+    simple_archiver_list_add(
+      required_names,
+      "testVar_FILE",
+      simple_archiver_helper_datastructure_cleanup_nop);
+
+    c_simple_http_clean_up_parsed_config(&config);
+
+    config = c_simple_http_parse_config(
+      test_http_template_filename4,
+      "PATH",
+      required_names
+    );
+    ASSERT_TRUE(config.paths != NULL);
+
+    buf = c_simple_http_path_to_generated("/", &config);
+    ASSERT_TRUE(buf != NULL);
+    printf("%s\n", buf);
+    ASSERT_TRUE(
+      strcmp(
+        buf,
+        "<h1> some test text in test var file. </h1>")
+      == 0);
+    simple_archiver_helper_cleanup_c_string(&buf);
   }
 
   RETURN()