]> git.seodisparate.com - c_simple_http/commitdiff
Impl. c_simple_http_cache_filename_to_path(...)
authorStephen Seo <seo.disparate@gmail.com>
Wed, 25 Sep 2024 04:10:44 +0000 (13:10 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Wed, 25 Sep 2024 04:10:44 +0000 (13:10 +0900)
src/html_cache.c
src/test.c

index d5dbc3c0cbdcbb2761ea1f7f324f43c5dd3d3577..0f114b57afa1b121322a76546f187cc48b4ae975 100644 (file)
@@ -104,6 +104,83 @@ char *c_simple_http_path_to_cache_filename(const char *path) {
   }
 }
 
+char *c_simple_http_cache_filename_to_path(const char *cache_filename) {
+  uint_fast8_t is_percent_encoded = 0;
+  if (!cache_filename) {
+    return NULL;
+  } else if (strcmp(cache_filename, "ROOT") == 0) {
+    char *buf = malloc(2);
+    buf[0] = '/';
+    buf[1] = 0;
+    return buf;
+  } else if (cache_filename[0] == '%') {
+    is_percent_encoded = 1;
+  }
+
+  __attribute__((cleanup(simple_archiver_list_free)))
+  SDArchiverLinkedList *parts = simple_archiver_list_init();
+
+  size_t idx = 0;
+  size_t prev_idx = 0;
+  const size_t size = strlen(cache_filename);
+  char *buf;
+  size_t buf_size;
+
+  for(; idx < size && cache_filename[idx] != 0; ++idx) {
+    if (is_percent_encoded && strncmp(cache_filename + idx, "%2F", 3) == 0) {
+      if (prev_idx < idx) {
+        buf_size = idx - prev_idx + 2;
+        buf = malloc(buf_size);
+        memcpy(buf, cache_filename + prev_idx, buf_size - 2);
+        buf[buf_size - 2] = '/';
+        buf[buf_size - 1] = 0;
+        c_simple_http_add_string_part(parts, buf, 0);
+        free(buf);
+      } else {
+        buf_size = 2;
+        buf = malloc(buf_size);
+        buf[0] = '/';
+        buf[1] = 0;
+        c_simple_http_add_string_part(parts, buf, 0);
+        free(buf);
+      }
+      idx += 2;
+      prev_idx = idx + 1;
+    } else if (!is_percent_encoded
+        && strncmp(cache_filename + idx, "0x2F", 4) == 0) {
+      if (prev_idx < idx) {
+        buf_size = idx - prev_idx + 2;
+        buf = malloc(buf_size);
+        memcpy(buf, cache_filename + prev_idx, buf_size - 2);
+        buf[buf_size - 2] = '/';
+        buf[buf_size - 1] = 0;
+        c_simple_http_add_string_part(parts, buf, 0);
+        free(buf);
+      } else {
+        buf_size = 2;
+        buf = malloc(buf_size);
+        buf[0] = '/';
+        buf[1] = 0;
+        c_simple_http_add_string_part(parts, buf, 0);
+        free(buf);
+      }
+      idx += 3;
+      prev_idx = idx + 1;
+    }
+  }
+
+  if (prev_idx < idx) {
+    buf_size = idx - prev_idx + 1;
+    buf = malloc(buf_size);
+    memcpy(buf, cache_filename + prev_idx, buf_size - 1);
+    buf[buf_size - 1] = 0;
+    c_simple_http_add_string_part(parts, buf, 0);
+    free(buf);
+  }
+
+  return c_simple_http_combine_string_parts(parts);
+}
+
 int c_simple_http_cache_path(
     const char *path,
     const char *config_filename,
index 7c807a7ebf06e850eb8f8bd8a6f55d9e76f346ba..e9a5da052e19143475bc876995669b2a20bfb462 100644 (file)
@@ -598,49 +598,129 @@ int main(void) {
   // Test html_cache.
   {
     char *ret = c_simple_http_path_to_cache_filename("/");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "ROOT") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("////");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "ROOT") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/inner");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/inner////");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/outer/inner");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/outer/inner////");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/outer///inner");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/outer/with_hex_0x2F_inner");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "%2Fouter%2Fwith_hex_0x2F_inner") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/outer/0x2F_hex_inner");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "%2Fouter%2F0x2F_hex_inner") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename("/outer0x2F/inner_hex_0x2F");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "%2Fouter0x2F%2Finner_hex_0x2F") == 0);
     free(ret);
 
     ret = c_simple_http_path_to_cache_filename(
         "/0x2Fouter0x2F/0x2Finner_0x2F_hex_0x2F");
+    ASSERT_TRUE(ret);
     CHECK_TRUE(strcmp(ret, "%2F0x2Fouter0x2F%2F0x2Finner_0x2F_hex_0x2F") == 0);
     free(ret);
+
+    ret = c_simple_http_cache_filename_to_path("0x2Fouter0x2Finner");
+    ASSERT_TRUE(ret);
+    printf("%s\n", ret);
+    CHECK_TRUE(strcmp(ret, "/outer/inner") == 0);
+    free(ret);
+
+    ret = c_simple_http_cache_filename_to_path("0x2Fouter0x2Finner0x2F%2F0x2Fmore_inner");
+    ASSERT_TRUE(ret);
+    CHECK_TRUE(strcmp(ret, "/outer/inner/%2F/more_inner") == 0);
+    free(ret);
+
+    ret = c_simple_http_cache_filename_to_path("%2Fouter%2Finner");
+    ASSERT_TRUE(ret);
+    CHECK_TRUE(strcmp(ret, "/outer/inner") == 0);
+    free(ret);
+
+    ret = c_simple_http_cache_filename_to_path("%2Fouter%2Finner%2F0x2F%2Fmore_inner");
+    ASSERT_TRUE(ret);
+    CHECK_TRUE(strcmp(ret, "/outer/inner/0x2F/more_inner") == 0);
+    free(ret);
+
+    const char *uri0 = "/a/simple/url/with/inner/paths";
+    ret =
+      c_simple_http_path_to_cache_filename(uri0);
+    ASSERT_TRUE(ret);
+    CHECK_TRUE(
+      strcmp(ret, "0x2Fa0x2Fsimple0x2Furl0x2Fwith0x2Finner0x2Fpaths")
+      == 0);
+    char *ret2 = c_simple_http_cache_filename_to_path(ret);
+    free(ret);
+    ASSERT_TRUE(ret2);
+    CHECK_TRUE(strcmp(ret2, uri0) == 0);
+    free(ret2);
+
+    const char *uri1 = "/a/url/with/0x2F/in/it";
+    ret =
+      c_simple_http_path_to_cache_filename(uri1);
+    ASSERT_TRUE(ret);
+    CHECK_TRUE(
+      strcmp(ret, "%2Fa%2Furl%2Fwith%2F0x2F%2Fin%2Fit")
+      == 0);
+    ret2 = c_simple_http_cache_filename_to_path(ret);
+    free(ret);
+    ASSERT_TRUE(ret2);
+    CHECK_TRUE(strcmp(ret2, uri1) == 0);
+    free(ret2);
+
+    const char *uri2 = "/";
+    ret =
+      c_simple_http_path_to_cache_filename(uri2);
+    ASSERT_TRUE(ret);
+    CHECK_TRUE(strcmp(ret, "ROOT") == 0);
+    ret2 = c_simple_http_cache_filename_to_path(ret);
+    free(ret);
+    ASSERT_TRUE(ret2);
+    CHECK_TRUE(strcmp(ret2, uri2) == 0);
+    free(ret2);
+
+    const char *uri3 = "/a";
+    ret =
+      c_simple_http_path_to_cache_filename(uri3);
+    ASSERT_TRUE(ret);
+    CHECK_TRUE(strcmp(ret, "0x2Fa") == 0);
+    ret2 = c_simple_http_cache_filename_to_path(ret);
+    free(ret);
+    ASSERT_TRUE(ret2);
+    CHECK_TRUE(strcmp(ret2, uri3) == 0);
+    free(ret2);
   }
 
   RETURN()