// 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(
// 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"
}
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] == '#') {
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;
#include "helpers.h"
#include "http_template.h"
#include "http.h"
+#include "html_cache.h"
// Third party includes.
#include <SimpleArchiver/src/helpers.h>
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,
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,
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,
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.
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()
}