]> git.seodisparate.com - c_simple_http/commitdiff
backport: remove extra '/' in URI, config changes
authorStephen Seo <seo.disparate@gmail.com>
Tue, 24 Sep 2024 05:53:28 +0000 (14:53 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Tue, 24 Sep 2024 05:53:28 +0000 (14:53 +0900)
example_config/example.config
example_config/inner.html
src/http.c

index 77b8d1736b28e050c8f41d885698b6f9b535399c..768af8c58c0af9dad20c6cb045e9b1a4000b00de 100644 (file)
@@ -38,3 +38,39 @@ HTML_FILE='''example_config/inner.html'''
 VAR_FILE='''example_config/var.html'''
 
 PATH=/error
+
+PATH=/inner/further
+HTML='''
+  <html>
+  <head>
+  <style>
+    body {
+    color: #FFF;
+    background-color: #333;
+  }
+  a {
+    color: #AAF;
+  }
+  a:link {
+    color: #AAF;
+  }
+  a:visited {
+    color: #88B;
+  }
+  a:focus a:hover {
+    color: #DDF;
+  }
+  a:active {
+    color: #FFF;
+  }
+  </style>
+  </head>
+  <body>
+  <h1>Nested inner: further<h1>
+  {{{VAR}}}
+  <br>
+  <a href="/inner">back</a>
+  </body>
+  </html>
+'''
+VAR='''yep'''
index 7de1791e5744a6b79c101987f65838d2a0a3618e..cdf8566db99e189aececbe0f41a7a9c4c6442584 100644 (file)
@@ -28,6 +28,7 @@
 {{{VAR_FILE}}}
 
 <br>
-<a href="..">Back.</a>
+<a href="/inner/further">further</a><br>
+<a href="/">Back.</a>
 </body>
 </html>
index 710ea73f0711c407fbc0e190f6e2b1aa4d171136..93761dddfba5b1572e73109921e089a6919b48bb 100644 (file)
@@ -200,6 +200,14 @@ char *c_simple_http_request_response(
 }
 
 char *c_simple_http_strip_path(const char *path, size_t path_size) {
+  if (path_size == 1 && path[0] == '/') {
+    // Edge case: root path.
+    char *buf = malloc(2);
+    buf[0] = '/';
+    buf[1] = 0;
+    return buf;
+  }
+
   size_t idx = 0;
   for (; idx < path_size && path[idx] != 0; ++idx) {
     if (path[idx] == '?' || path[idx] == '#') {
@@ -211,7 +219,72 @@ char *c_simple_http_strip_path(const char *path, size_t path_size) {
   memcpy(stripped_path, path, idx);
   stripped_path[idx] = 0;
 
+  // Strip multiple '/' into one.
+  __attribute((cleanup(simple_archiver_list_free)))
+  SDArchiverLinkedList *parts = simple_archiver_list_init();
+
+  idx = 0;
+  size_t prev_idx = 0;
+  size_t size;
+  char *buf;
+  uint_fast8_t slash_visited = 0;
+
+  for (; stripped_path[idx] != 0; ++idx) {
+    if (stripped_path[idx] == '/') {
+      if (slash_visited) {
+        // Intentionally left blank.
+      } else {
+        slash_visited = 1;
+
+        if (idx > prev_idx) {
+          size = idx - prev_idx + 1;
+          buf = malloc(size);
+          memcpy(buf, stripped_path + prev_idx, size - 1);
+          buf[size - 1] = 0;
+
+          c_simple_http_add_string_part(parts, buf, 0);
+          free(buf);
+        }
+      }
+    } else {
+      if (slash_visited) {
+        buf = malloc(2);
+        buf[0] = '/';
+        buf[1] = 0;
+
+        c_simple_http_add_string_part(parts, buf, 0);
+        free(buf);
+
+        prev_idx = idx;
+      }
+
+      slash_visited = 0;
+    }
+  }
+
+  if (!slash_visited && idx > prev_idx) {
+    size = idx - prev_idx + 1;
+    buf = malloc(size);
+    memcpy(buf, stripped_path + prev_idx, size - 1);
+    buf[size - 1] = 0;
+
+    c_simple_http_add_string_part(parts, buf, 0);
+    free(buf);
+  } else if (slash_visited && prev_idx == 0) {
+    buf = malloc(2);
+    buf[0] = '/';
+    buf[1] = 0;
+
+    c_simple_http_add_string_part(parts, buf, 0);
+    free(buf);
+  }
+
+  free(stripped_path);
+
+  stripped_path = c_simple_http_combine_string_parts(parts);
+
   // Strip trailing '/'.
+  idx = strlen(stripped_path);
   while (idx-- > 1) {
     if (stripped_path[idx] == '/' || stripped_path[idx] == 0) {
       stripped_path[idx] = 0;