Compare commits
3 commits
856c205f31
...
07153f3588
Author | SHA1 | Date | |
---|---|---|---|
07153f3588 | |||
4e670d24c8 | |||
b9e4e3de5f |
5 changed files with 197 additions and 2 deletions
|
@ -38,3 +38,39 @@ HTML_FILE='''example_config/inner.html'''
|
||||||
VAR_FILE='''example_config/var.html'''
|
VAR_FILE='''example_config/var.html'''
|
||||||
|
|
||||||
PATH=/error
|
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'''
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
{{{VAR_FILE}}}
|
{{{VAR_FILE}}}
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<a href="..">Back.</a>
|
<a href="/inner/further">further</a><br>
|
||||||
|
<a href="/">Back.</a>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
// Standard library includes.
|
// Standard library includes.
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Third-party includes.
|
// Third-party includes.
|
||||||
#include <SimpleArchiver/src/data_structures/linked_list.h>
|
#include <SimpleArchiver/src/data_structures/linked_list.h>
|
||||||
|
@ -26,7 +27,7 @@
|
||||||
typedef struct C_SIMPLE_HTTP_String_Part {
|
typedef struct C_SIMPLE_HTTP_String_Part {
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t extra;
|
uintptr_t extra;
|
||||||
} C_SIMPLE_HTTP_String_Part;
|
} C_SIMPLE_HTTP_String_Part;
|
||||||
|
|
||||||
void c_simple_http_cleanup_attr_string_part(C_SIMPLE_HTTP_String_Part **);
|
void c_simple_http_cleanup_attr_string_part(C_SIMPLE_HTTP_String_Part **);
|
||||||
|
|
|
@ -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(
|
int c_simple_http_cache_path(
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *config_filename,
|
const char *config_filename,
|
||||||
|
|
80
src/test.c
80
src/test.c
|
@ -598,49 +598,129 @@ int main(void) {
|
||||||
// Test html_cache.
|
// Test html_cache.
|
||||||
{
|
{
|
||||||
char *ret = c_simple_http_path_to_cache_filename("/");
|
char *ret = c_simple_http_path_to_cache_filename("/");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "ROOT") == 0);
|
CHECK_TRUE(strcmp(ret, "ROOT") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("////");
|
ret = c_simple_http_path_to_cache_filename("////");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "ROOT") == 0);
|
CHECK_TRUE(strcmp(ret, "ROOT") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/inner");
|
ret = c_simple_http_path_to_cache_filename("/inner");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
|
CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/inner////");
|
ret = c_simple_http_path_to_cache_filename("/inner////");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
|
CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/outer/inner");
|
ret = c_simple_http_path_to_cache_filename("/outer/inner");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
|
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/outer/inner////");
|
ret = c_simple_http_path_to_cache_filename("/outer/inner////");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
|
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/outer///inner");
|
ret = c_simple_http_path_to_cache_filename("/outer///inner");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
|
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/outer/with_hex_0x2F_inner");
|
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);
|
CHECK_TRUE(strcmp(ret, "%2Fouter%2Fwith_hex_0x2F_inner") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/outer/0x2F_hex_inner");
|
ret = c_simple_http_path_to_cache_filename("/outer/0x2F_hex_inner");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "%2Fouter%2F0x2F_hex_inner") == 0);
|
CHECK_TRUE(strcmp(ret, "%2Fouter%2F0x2F_hex_inner") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename("/outer0x2F/inner_hex_0x2F");
|
ret = c_simple_http_path_to_cache_filename("/outer0x2F/inner_hex_0x2F");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "%2Fouter0x2F%2Finner_hex_0x2F") == 0);
|
CHECK_TRUE(strcmp(ret, "%2Fouter0x2F%2Finner_hex_0x2F") == 0);
|
||||||
free(ret);
|
free(ret);
|
||||||
|
|
||||||
ret = c_simple_http_path_to_cache_filename(
|
ret = c_simple_http_path_to_cache_filename(
|
||||||
"/0x2Fouter0x2F/0x2Finner_0x2F_hex_0x2F");
|
"/0x2Fouter0x2F/0x2Finner_0x2F_hex_0x2F");
|
||||||
|
ASSERT_TRUE(ret);
|
||||||
CHECK_TRUE(strcmp(ret, "%2F0x2Fouter0x2F%2F0x2Finner_0x2F_hex_0x2F") == 0);
|
CHECK_TRUE(strcmp(ret, "%2F0x2Fouter0x2F%2F0x2Finner_0x2F_hex_0x2F") == 0);
|
||||||
free(ret);
|
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()
|
RETURN()
|
||||||
|
|
Loading…
Reference in a new issue