Implement get handler
This commit is contained in:
@@ -1,6 +1,30 @@
|
|||||||
static enum MHD_Result handle_get(struct MHD_Connection *connection, SV url, SV base_path, SV username) {
|
static enum MHD_Result handle_get(struct MHD_Connection *connection, SV url, Settings settings, SV username) {
|
||||||
(void)url;
|
noh_arena_save(&temp);
|
||||||
(void)username;
|
Noh_String fs_path = build_path(false, &settings.base_path, &username, &url);
|
||||||
(void)base_path;
|
|
||||||
return send_response(connection, 200, sv("TODO: Get\n"), false);
|
noh_log(NOH_INFO, "Physical path: "Nsv_Fmt, Nsv_Arg(fs_path));
|
||||||
|
|
||||||
|
if (!noh_sv_ends_with(noh_sv_from_string(fs_path), sv(".epub"))) {
|
||||||
|
return send_response(connection, 400, sv("File is not an epub file."), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
noh_string_append_null(&fs_path);
|
||||||
|
|
||||||
|
// Try to open the file.
|
||||||
|
FILE *file = fopen(fs_path.elems, "r");
|
||||||
|
if (file == NULL) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
noh_arena_reset(&temp);
|
||||||
|
return send_response(connection, 404, sv("File does not exist."), false);
|
||||||
|
} else {
|
||||||
|
noh_log(NOH_ERROR, "Opening file failed.");
|
||||||
|
noh_arena_reset(&temp);
|
||||||
|
return send_response(connection, 500, sv(""), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(file, 0L, SEEK_END);
|
||||||
|
size_t file_size = ftell(file);
|
||||||
|
fseek(file, 0L, SEEK_SET);
|
||||||
|
return send_epub_file(connection, fileno(file), file_size);
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/main.c
13
src/main.c
@@ -36,6 +36,17 @@ static enum MHD_Result send_response(struct MHD_Connection *connection, int stat
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum MHD_Result send_epub_file(struct MHD_Connection *connection, int file, size_t size) {
|
||||||
|
struct MHD_Response *response = MHD_create_response_from_fd(size, file);
|
||||||
|
if (!response) return MHD_NO;
|
||||||
|
|
||||||
|
MHD_add_response_header(response, "content-type", "application/epub+zip");
|
||||||
|
|
||||||
|
enum MHD_Result ret = MHD_queue_response(connection, 200, response);
|
||||||
|
MHD_destroy_response(response);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#include "opds_handler.c"
|
#include "opds_handler.c"
|
||||||
#include "get_handler.c"
|
#include "get_handler.c"
|
||||||
|
|
||||||
@@ -76,7 +87,7 @@ static enum MHD_Result request_handler(
|
|||||||
SV controller = noh_sv_chop_by_delim(&url, '/');
|
SV controller = noh_sv_chop_by_delim(&url, '/');
|
||||||
|
|
||||||
if (noh_sv_eq_ci(controller, sv("opds"))) return handle_opds(connection, url, settings, username);
|
if (noh_sv_eq_ci(controller, sv("opds"))) return handle_opds(connection, url, settings, username);
|
||||||
if (noh_sv_eq_ci(controller, sv("get"))) return handle_get(connection, url, settings.base_path, username);
|
if (noh_sv_eq_ci(controller, sv("get"))) return handle_get(connection, url, settings, username);
|
||||||
return send_response(connection, 404, sv(""), false);
|
return send_response(connection, 404, sv(""), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,39 +62,40 @@ static enum MHD_Result handle_opds(struct MHD_Connection *connection, SV url, Se
|
|||||||
noh_log(NOH_INFO, "Physical path: "Nsv_Fmt, Nsv_Arg(self_entry.full_path));
|
noh_log(NOH_INFO, "Physical path: "Nsv_Fmt, Nsv_Arg(self_entry.full_path));
|
||||||
|
|
||||||
DIR *dir = opendir(fs_path_cstr.elems);
|
DIR *dir = opendir(fs_path_cstr.elems);
|
||||||
if (dir) {
|
if (!dir) {
|
||||||
Library_Entries list = {0};
|
if (errno == ENOENT) {
|
||||||
|
closedir(dir);
|
||||||
|
noh_arena_reset(&temp);
|
||||||
|
return send_response(connection, 404, sv(""), false);
|
||||||
|
|
||||||
// Build up list of entries.
|
} else {
|
||||||
struct dirent *entry = noh_arena_alloc(&temp, sizeof(struct dirent));
|
noh_log(NOH_ERROR, "Opening directory failed.");
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
noh_arena_reset(&temp);
|
||||||
Library_Entry result = {0};
|
return send_response(connection, 500, sv(""), false);
|
||||||
if (create_entry(entry, fs_path_cstr.elems, &result)) noh_da_append(&list, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort entries, folders first, then by name.
|
|
||||||
if (list.count > 1) qsort(list.elems, list.count, sizeof(list.elems[0]), compare_library_entries);
|
|
||||||
|
|
||||||
// Create and send response.
|
|
||||||
Noh_String response = create_feed_response(self_entry, url, list);
|
|
||||||
bool result = send_response(connection, 200, noh_sv_from_string(response), true);
|
|
||||||
|
|
||||||
// Cleanup.
|
|
||||||
noh_da_free(&list);
|
|
||||||
noh_string_free(&response);
|
|
||||||
noh_arena_reset(&temp);
|
|
||||||
closedir(dir);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} else if (errno == ENOENT) {
|
|
||||||
closedir(dir);
|
|
||||||
noh_arena_reset(&temp);
|
|
||||||
return send_response(connection, 404, sv(""), false);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
noh_log(NOH_ERROR, "Opening directory failed.");
|
|
||||||
noh_arena_reset(&temp);
|
|
||||||
return send_response(connection, 500, sv(""), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Library_Entries list = {0};
|
||||||
|
|
||||||
|
// Build up list of entries.
|
||||||
|
struct dirent *entry = noh_arena_alloc(&temp, sizeof(struct dirent));
|
||||||
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
|
Library_Entry result = {0};
|
||||||
|
if (create_entry(entry, fs_path_cstr.elems, &result)) noh_da_append(&list, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort entries, folders first, then by name.
|
||||||
|
if (list.count > 1) qsort(list.elems, list.count, sizeof(list.elems[0]), compare_library_entries);
|
||||||
|
|
||||||
|
// Create and send response.
|
||||||
|
Noh_String response = create_feed_response(self_entry, url, list);
|
||||||
|
bool result = send_response(connection, 200, noh_sv_from_string(response), true);
|
||||||
|
|
||||||
|
// Cleanup.
|
||||||
|
noh_da_free(&list);
|
||||||
|
noh_string_free(&response);
|
||||||
|
noh_arena_reset(&temp);
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user