Impl. path-to-cache-filename, fixes to strip-path
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 8s

This commit is contained in:
Stephen Seo 2024-09-23 14:58:28 +09:00
parent 0956ae165e
commit abc61a5504
3 changed files with 184 additions and 7 deletions

View file

@ -14,14 +14,73 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// Standard library includes.
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
// Third-party includes.
//#include <SimpleArchiver/src/data_structures/linked_list.h>
#include <SimpleArchiver/src/data_structures/linked_list.h>
#include <SimpleArchiver/src/helpers.h>
// Local includes.
#include "http.h"
#include "helpers.h"
char *c_simple_http_path_to_cache_filename(const char *path) {
// SDArchiverLinkedList *parts = simple_archiver_list_init();
// TODO
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *stripped_path = c_simple_http_strip_path(path, strlen(path));
return 0;
if (!stripped_path) {
return NULL;
}
if (strcmp(stripped_path, "/") == 0) {
char *buf = malloc(5);
memcpy(buf, "ROOT", 5);
return buf;
}
__attribute__((cleanup(simple_archiver_list_free)))
SDArchiverLinkedList *parts = simple_archiver_list_init();
size_t idx = 0;
size_t prev_idx = 0;
const size_t path_len = strlen(stripped_path);
size_t size;
for (; idx < path_len && stripped_path[idx] != 0; ++idx) {
if (stripped_path[idx] == '/') {
size = idx - prev_idx + 1;
char *temp_buf = malloc(size);
memcpy(temp_buf, stripped_path + prev_idx, size - 1);
temp_buf[size - 1] = 0;
c_simple_http_add_string_part(parts, temp_buf, 0);
free(temp_buf);
temp_buf = malloc(5);
memcpy(temp_buf, "0x2F", 5);
c_simple_http_add_string_part(parts, temp_buf, 0);
free(temp_buf);
prev_idx = idx + 1;
}
}
if (idx > prev_idx) {
size = idx - prev_idx + 1;
char *temp_buf = malloc(size);
memcpy(temp_buf, stripped_path + prev_idx, size - 1);
temp_buf[size - 1] = 0;
c_simple_http_add_string_part(parts, temp_buf, 0);
free(temp_buf);
}
if (prev_idx == 0) {
return stripped_path;
} else {
return c_simple_http_combine_string_parts(parts);
}
}
int c_simple_http_cache_path(

View file

@ -23,8 +23,10 @@
// Third party includes.
#include <SimpleArchiver/src/helpers.h>
#include <SimpleArchiver/src/data_structures/linked_list.h>
// Local includes
#include "SimpleArchiver/src/data_structures/priority_heap.h"
#include "constants.h"
#include "http_template.h"
#include "helpers.h"
@ -193,6 +195,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] == '#') {
@ -204,7 +214,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;

View file

@ -9,6 +9,7 @@
#include "helpers.h"
#include "http_template.h"
#include "http.h"
#include "html_cache.h"
// Third party includes.
#include <SimpleArchiver/src/helpers.h>
@ -308,7 +309,7 @@ int main(void) {
buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL);
printf("%s\n", buf);
//printf("%s\n", buf);
ASSERT_TRUE(
strcmp(
buf,
@ -374,7 +375,7 @@ int main(void) {
buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL);
printf("%s\n", buf);
//printf("%s\n", buf);
ASSERT_TRUE(
strcmp(
buf,
@ -465,7 +466,7 @@ int main(void) {
buf = c_simple_http_path_to_generated(
"/", &config, &output_buf_size, &filenames_list);
ASSERT_TRUE(buf != NULL);
printf("%s\n", buf);
//printf("%s\n", buf);
ASSERT_TRUE(
strcmp(
buf,
@ -519,28 +520,39 @@ int main(void) {
free(stripped_path_buf);
stripped_path_buf = c_simple_http_strip_path("/someurl/", 9);
//printf("stripped path: %s\n", stripped_path_buf);
CHECK_STREQ(stripped_path_buf, "/someurl");
free(stripped_path_buf);
stripped_path_buf = c_simple_http_strip_path("/someurl/////", 13);
//printf("stripped path: %s\n", stripped_path_buf);
CHECK_STREQ(stripped_path_buf, "/someurl");
free(stripped_path_buf);
stripped_path_buf = c_simple_http_strip_path("/someurl?key=value", 18);
//printf("stripped path: %s\n", stripped_path_buf);
CHECK_STREQ(stripped_path_buf, "/someurl");
free(stripped_path_buf);
stripped_path_buf = c_simple_http_strip_path("/someurl#client_data", 20);
//printf("stripped path: %s\n", stripped_path_buf);
CHECK_STREQ(stripped_path_buf, "/someurl");
free(stripped_path_buf);
stripped_path_buf = c_simple_http_strip_path("/someurl////?key=value", 22);
//printf("stripped path: %s\n", stripped_path_buf);
CHECK_STREQ(stripped_path_buf, "/someurl");
free(stripped_path_buf);
stripped_path_buf = c_simple_http_strip_path("/someurl///#client_data", 23);
//printf("stripped path: %s\n", stripped_path_buf);
CHECK_STREQ(stripped_path_buf, "/someurl");
free(stripped_path_buf);
stripped_path_buf = c_simple_http_strip_path("/someurl/////inner", 18);
//printf("stripped path: %s\n", stripped_path_buf);
CHECK_STREQ(stripped_path_buf, "/someurl/inner");
free(stripped_path_buf);
}
// Test helpers.
@ -558,6 +570,37 @@ int main(void) {
ASSERT_TRUE(strcmp(buf, "one\ntwo\nthree\n") == 0);
}
// Test html_cache.
{
char *ret = c_simple_http_path_to_cache_filename("/");
CHECK_TRUE(strcmp(ret, "ROOT") == 0);
free(ret);
ret = c_simple_http_path_to_cache_filename("////");
CHECK_TRUE(strcmp(ret, "ROOT") == 0);
free(ret);
ret = c_simple_http_path_to_cache_filename("/inner");
CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
free(ret);
ret = c_simple_http_path_to_cache_filename("/inner////");
CHECK_TRUE(strcmp(ret, "0x2Finner") == 0);
free(ret);
ret = c_simple_http_path_to_cache_filename("/outer/inner");
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
free(ret);
ret = c_simple_http_path_to_cache_filename("/outer/inner////");
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
free(ret);
ret = c_simple_http_path_to_cache_filename("/outer///inner");
CHECK_TRUE(strcmp(ret, "0x2Fouter0x2Finner") == 0);
free(ret);
}
RETURN()
}