FileRecord *Dir_resolve_file(Dir *dir, bstring path) { FileRecord *file = NULL; bstring target = NULL; check(Dir_lazy_normalize_base(dir) == 0, "Failed to normalize base path when requesting %s", bdata(path)); check(bstrncmp(path, dir->prefix, blength(dir->prefix)) == 0, "Request for path %s does not start with %s prefix.", bdata(path), bdata(dir->prefix)); file = FileRecord_cache_check(dir, path); if(file) { // TODO: double check this gives the right users count file->users++; return file; } // We subtract one from the blengths below, because dir->prefix includes // a trailing '/'. If we skip over this in path->data, we drop the '/' // from the URI, breaking the target path if(bchar(path, blength(path) - 1) == '/') { target = bformat("%s%s%s", bdata(dir->normalized_base), path->data + blength(dir->prefix) - 1, bdata(dir->index_file)); } else { target = bformat("%s%s", bdata(dir->normalized_base), path->data + blength(dir->prefix) - 1); } check(target, "Couldn't construct target path for %s", bdata(path)); check_debug(normalize_path(target) == 0, "Failed to normalize target path."); check_debug(bstrncmp(target, dir->normalized_base, blength(dir->normalized_base)) == 0, "Request for path %s does not start with %s base after normalizing.", bdata(target), bdata(dir->base)); // the FileRecord now owns the target file = Dir_find_file(target, dir->default_ctype); check_debug(file, "Error opening file: %s", bdata(target)); // Increment the user count because we're adding it to the cache file->users++; file->request_path = bstrcpy(path); Cache_add(dir->fr_cache, file); return file; error: bdestroy(target); FileRecord_release(file); return NULL; }
char *test_Dir_find_file() { bstring ctype = NULL; FileRecord *file = Dir_find_file(bfromcstr("tests/sample.json"), ctype = bfromcstr("text/plain")); mu_assert(file != NULL, "Failed to find the file."); FileRecord_destroy(file); bdestroy(ctype); return NULL; }
char *test_Dir_find_file_isdir(){ bstring ctype = NULL; FileRecord *file = Dir_find_file(bfromcstr("tests/"), ctype = bfromcstr("text/plain")); mu_assert(file != NULL, "Failed to find the directory."); mu_assert(file->is_dir == 1, "Did not recognized it's a directory"); FileRecord_destroy(file); bdestroy(ctype); return NULL; }
FileRecord *Dir_resolve_file(Dir *dir, bstring pattern, bstring path) { FileRecord *file = NULL; bstring target = NULL; bstring prefix = NULL; check(Dir_lazy_normalize_base(dir) == 0, "Failed to normalize base path when requesting %s", bdata(path)); file = FileRecord_cache_check(dir, path); if(file) { // TODO: double check this gives the right users count file->users++; return file; } int paren = bstrchr(pattern, '('); prefix = (paren > 0) ? bHead(pattern, paren) : bstrcpy(pattern); check(bchar(prefix, 0) == '/', "Route '%s' pointing to directory must have pattern with leading '/'", bdata(pattern)); check(blength(prefix) < MAX_DIR_PATH, "Prefix is too long, must be less than %d", MAX_DIR_PATH); debug("Building target from base: %s pattern: %s prefix: %s path: %s index_file: %s", bdata(dir->normalized_base), bdata(pattern), bdata(prefix), bdata(path), bdata(dir->index_file)); if(bchar(path, blength(path) - 1) == '/') { // a directory so figureo out the index file target = bformat("%s%s%s", bdata(dir->normalized_base), path->data + blength(prefix) - 1, bdata(dir->index_file)); } else if(biseq(prefix, path)) { target = bformat("%s%s", bdata(dir->normalized_base), bdata(path)); } else { target = bformat("%s%s", bdata(dir->normalized_base), path->data + blength(prefix) - 1); } check(target, "Couldn't construct target path for %s", bdata(path)); check_debug(normalize_path(target) == 0, "Failed to normalize target path: %s", bdata(target)); check_debug(bstrncmp(target, dir->normalized_base, blength(dir->normalized_base)) == 0, "Request for path %s does not start with %s base after normalizing.", bdata(target), bdata(dir->base)); // the FileRecord now owns the target file = Dir_find_file(target, dir->default_ctype); check_debug(file, "Error opening file: %s", bdata(target)); // Increment the user count because we're adding it to the cache file->users++; file->request_path = bstrcpy(path); Cache_add(dir->fr_cache, file); return file; error: bdestroy(target); FileRecord_release(file); return NULL; }