From 35a145fd161fb4d4f19aa9820b50438695b94414 Mon Sep 17 00:00:00 2001 From: Vincent Douillet Date: Thu, 5 Sep 2024 12:58:22 +0200 Subject: browse: add upload button --- Makefile | 4 +- browse.c | 156 +++++++++++++++++++++++++++++++++------------- download.c | 47 +++----------- download.h | 2 +- file.c | 74 ++++++++++++++++------ file.h | 27 +++++--- http.c | 13 +++- http.h | 4 +- mime.c | 8 +-- mime.h | 6 +- str.c | 2 +- str.h | 2 +- template.c | 4 +- template.h | 3 +- template/browse_head.html | 1 + upload.c | 66 ++++++++++++++++++++ upload.h | 54 ++++++++++++++++ url.c | 5 +- url.h | 2 +- 19 files changed, 349 insertions(+), 131 deletions(-) create mode 100644 upload.c create mode 100644 upload.h diff --git a/Makefile b/Makefile index 0c485c0..69c5b9b 100644 --- a/Makefile +++ b/Makefile @@ -47,10 +47,10 @@ all: main .c.o: $(CC) -o $@ -c $< $(CFLAGS) -main: str.o config.o mime.o url.o template.o file.o http.o download.o browse.o main.o +main: str.o config.o mime.o url.o template.o file.o http.o upload.o download.o browse.o main.o $(CC) -o $@ $> $(LDFLAGS) -test: str.o config.o mime.o url.o template.o file.o http.o download.o browse.o test.o +test: str.o config.o mime.o url.o template.o file.o http.o upload.o download.o browse.o test.o $(CC) -o $@ $> $(LDFLAGS) env: env.o diff --git a/browse.c b/browse.c index 868388f..ce76290 100644 --- a/browse.c +++ b/browse.c @@ -44,7 +44,9 @@ #include "download.h" #include "file.h" #include "http.h" +#include "str.h" #include "template.h" +#include "upload.h" #include "url.h" /* @@ -53,7 +55,7 @@ SLIST_HEAD(, file) list; /* - * browse url = r->pname / BROWSE_URL / file->path / file->name + * browse url = r->pname / BROWSE_URL / file->path */ static size_t build_browse_url(struct kreq * r, struct file * file) @@ -65,7 +67,7 @@ build_browse_url(struct kreq * r, struct file * file) return 0; action_url_len = url_build(action_url, PATH_MAX, r->pname, BROWSE_URL, - file->path, file->name, NULL); + file->path, NULL); if (action_url_len == 0 || action_url_len >= PATH_MAX) { kutil_warn(r, NULL, "browse: action URL overflow: %s", action_url); @@ -82,16 +84,25 @@ build_browse_url(struct kreq * r, struct file * file) } static int -build_file_list(struct kreq * r, const char *request_dir) +build_file_list(struct kreq * r, const struct file * request_dir) { bool action_url_ok; - char *file_name; + char file_path[PATH_MAX], request_dir_path[PATH_MAX]; DIR *data_dir; + size_t file_path_len, request_dir_len; struct dirent *dir; struct file *file; struct file *last_file; - data_dir = opendir(request_dir); + request_dir_len = file_get_data_path(request_dir, request_dir_path, + PATH_MAX); + if (request_dir_len == 0) { + kutil_warn(r, NULL, + "browse: Unable to build request dir path: %s", + request_dir_path); + return -1; + } + data_dir = opendir(request_dir_path); if (NULL == data_dir) return -1; @@ -99,16 +110,24 @@ build_file_list(struct kreq * r, const char *request_dir) last_file = NULL; while ((dir = readdir(data_dir)) != NULL) { /* ignore special . and .. folders */ - file_name = dir->d_name; - if (strcmp(".", file_name) == 0 || strcmp("..", file_name) == 0) + if (strcmp(".", dir->d_name) == 0 + || strcmp("..", dir->d_name) == 0) + continue; + /* build file path */ + file_path_len = url_build(file_path, PATH_MAX, r->path, + dir->d_name, NULL); + if (file_path_len == 0 || file_path_len >= PATH_MAX) { + kutil_warn(r, NULL, + "browse: unable to build file, skipping %s", + dir->d_name); continue; + } /* build file */ - file = file_new(r->path, strlen(r->path), dir->d_name, - dir->d_namlen); + file = file_new(file_path); if (file == NULL) { kutil_warn(r, NULL, "browse: unable to allocate file, skipping %s", - file_name); + dir->d_name); continue; } /* build action url */ @@ -119,7 +138,7 @@ build_file_list(struct kreq * r, const char *request_dir) if (!action_url_ok) { kutil_warn(r, NULL, "browse: unable to build action url, skipping %s", - file_name); + dir->d_name); file_free(file); continue; } @@ -136,10 +155,8 @@ build_file_list(struct kreq * r, const char *request_dir) return 0; } -static const char *const template_keys[] = {"icon", "name", "url", "size"}; - /* - * data required in the template function + * data required in the template functions */ struct template_data { struct kreq *r; @@ -147,9 +164,45 @@ struct template_data { struct file *f; }; +static const char *const header_template_keys[] = {"upload_url"}; + +static int +header_template_callback(size_t index, void *arg) +{ + struct kreq *r; + struct khtmlreq *html; + struct template_data *data; + + if (arg == NULL) { + kutil_warn(NULL, NULL, + "Invalid data for browse header template"); + return 0; + } + data = arg; + r = data->r; + html = data->html; + + switch (index) { + case 0: + /* upload_url */ + K_OK(khtml_puts(html, data->f->action_url), r); + break; + default: + kutil_warnx(r, NULL, + "Invalid key index for browse header template: %zd", + index); + return 0; + } + + return 1; +} + +static const char *const file_template_keys[] = {"icon", "name", "url", "size"}; + static int -template_callback(size_t index, void *arg) +file_template_callback(size_t index, void *arg) { + char *basename; struct kreq *r; struct khtmlreq *html; struct template_data *data; @@ -158,7 +211,7 @@ template_callback(size_t index, void *arg) char size_read[] = {'k', 'M', 'G'}; if (arg == NULL) { - kutil_warn(NULL, NULL, "Invalid data for browse template"); + kutil_warn(NULL, NULL, "Invalid data for browse file template"); return 0; } data = arg; @@ -172,7 +225,14 @@ template_callback(size_t index, void *arg) break; case 1: /* name */ - K_OK(khtml_puts(html, data->f->name), r); + basename = file_get_basename(data->f); + if (basename == NULL) { + kutil_warnx(r, NULL, + "browse: unable to get file name: %s", + data->f->path); + break; + } + K_OK(khtml_puts(html, basename), r); break; case 2: /* url */ @@ -195,7 +255,7 @@ template_callback(size_t index, void *arg) break; default: kutil_warnx(r, NULL, - "Invalid key index for browse template: %zd", + "Invalid key index for browse file template: %zd", index); return 0; } @@ -206,9 +266,6 @@ template_callback(size_t index, void *arg) struct http_ret browse(struct kreq * r) { - size_t url_len; - char current_dir[PATH_MAX]; - char *data_dir; struct file *file; struct page_template *tmpl; struct http_ret ret; @@ -217,6 +274,7 @@ browse(struct kreq * r) struct template_data data; /* initialize vars */ + file = NULL; tmpl = NULL; /* initialize return structure for success */ @@ -224,16 +282,6 @@ browse(struct kreq * r) KHTTP_200, "" }; - /* check that data dir is configured */ - data_dir = config_data_dir(); - if (data_dir == NULL) { - ret = (struct http_ret) { - KHTTP_400, - "browse: data dir is not configured" - }; - goto end; - } - /* check that the requested URL can be safely processed */ if (!check_request_path(r->path, r->suffix)) { ret = (struct http_ret) { @@ -243,28 +291,37 @@ browse(struct kreq * r) goto end; } /* list requested directory content */ - url_len = url_build(current_dir, PATH_MAX, data_dir, r->path, - NULL); - if (url_len == 0) { + file = file_new(r->path); + if (file == NULL) { + ret = (struct http_ret) { + KHTTP_404, + "browse: Unable to build data file" + }; + goto end; + } + if (!file->is_dir) { ret = (struct http_ret) { KHTTP_404, - "browse: Unable to build data path" + "browse: Invalid data file" }; goto end; } - if (url_len >= PATH_MAX) { + if (build_upload_url(r, file) == 0) { ret = (struct http_ret) { - KHTTP_414, "" + KHTTP_500, + "browse: Can't build upload url" }; goto end; } - if (build_file_list(r, current_dir) < 0) { + + if (build_file_list(r, file) < 0) { ret = (struct http_ret) { KHTTP_500, "browse: Unable to build file list" }; goto end; } + /* read template */ tmpl = page_template_new(BROWSE_URL); if (tmpl == NULL) { @@ -274,21 +331,29 @@ browse(struct kreq * r) }; goto end; } + /* we have all the data we need, we can start to write output page */ http_open(r, KHTTP_200, r->mime); K_OK(khttp_puts(r, tmpl->header), r); - K_OK(khttp_puts(r, tmpl->page_header), r); K_OK(khtml_open(&html, r, 0), r); - /* print file list */ - template.key = template_keys; - template.keysz = 4; - template.cb = template_callback; + /* print browse header with action buttons for current dir */ + template.key = header_template_keys; + template.keysz = 1; + template.cb = header_template_callback; template.arg = &data; data.r = r; data.html = &html; + data.f = file; + K_OK(khttp_template_buf(r, &template, tmpl->page_header, + strlen(tmpl->page_header)), r); + + /* print file list */ + template.key = file_template_keys; + template.keysz = 4; + template.cb = file_template_callback; SLIST_FOREACH(file, &list, files) { data.f = file; @@ -304,7 +369,10 @@ browse(struct kreq * r) /* free page template and file list */ end: page_template_free(tmpl); - file = NULL; + if (file != NULL) { + free(file); + file = NULL; + } while (!SLIST_EMPTY(&list)) { file = SLIST_FIRST(&list); SLIST_REMOVE_HEAD(&list, files); diff --git a/download.c b/download.c index a8f5947..15da06d 100644 --- a/download.c +++ b/download.c @@ -47,10 +47,10 @@ #include "util.h" /* - * download url = r->pname / DOWNLOAD_URL / file->path / file->name + * download url = r->pname / DOWNLOAD_URL / file->path */ size_t -build_download_url(struct kreq * r, struct file * file) +build_download_url(const struct kreq * r, struct file * file) { char action_url[PATH_MAX]; size_t action_url_len; @@ -60,7 +60,7 @@ build_download_url(struct kreq * r, struct file * file) return 0; action_url_len = url_build(action_url, PATH_MAX, r->pname, DOWNLOAD_URL, - file->path, file->name, NULL); + file->path, NULL); if (action_url_len == 0 || action_url_len >= PATH_MAX) { kutil_warn(r, NULL, "download: action URL overflow: %s", action_url); @@ -79,7 +79,6 @@ build_download_url(struct kreq * r, struct file * file) struct http_ret download(struct kreq * r) { - char *file_name, *data_dir; void *buffer; struct file *f; int fd; @@ -93,16 +92,6 @@ download(struct kreq * r) KHTTP_200, "" }; - /* check that data dir is configured */ - data_dir = config_data_dir(); - if (data_dir == NULL) { - ret = (struct http_ret) { - KHTTP_400, - "download: data dir not configured" - }; - goto end; - } - /* check that the requested URL can be safely processed */ if (strlen(r->path) == 0 || !check_request_path(r->path, r->suffix)) { ret = (struct http_ret) { @@ -131,36 +120,20 @@ download(struct kreq * r) goto end; } } - - path_size = url_build(file_path, PATH_MAX, data_dir, request_path, - NULL); - if (path_size == 0) { + /* build file metadata */ + f = file_new(request_path); + if (f == NULL) { ret = (struct http_ret) { KHTTP_404, - "download: unable to build file path" - }; - goto end; - } - if (path_size >= PATH_MAX) { - ret = (struct http_ret) { - KHTTP_414, - "download: request too long" + "download: file metadata failure" }; goto end; } - /* build file metadata */ - file_name = str_split(request_path, '/'); - if (file_name == NULL) - f = file_new("/", 1, request_path, strlen(request_path)); /* ROOT file */ - else { - f = file_new(request_path, strlen(request_path), file_name, - strlen(file_name)); - free(file_name);/* copied in file_new */ - } - if (f == NULL) { + path_size = file_get_data_path(f, file_path, PATH_MAX); + if (path_size == 0 || path_size >= PATH_MAX) { ret = (struct http_ret) { KHTTP_404, - "download: file metadata failure" + "download: unable to build file path" }; goto end; } diff --git a/download.h b/download.h index 94daff4..f602bd7 100644 --- a/download.h +++ b/download.h @@ -43,7 +43,7 @@ * Returns the length of the created URL, or 0 in case of failure. */ size_t -build_download_url(struct kreq *, struct file *); +build_download_url(const struct kreq *, struct file *); /* * Return a requested file. diff --git a/file.c b/file.c index 1a53b89..239f548 100644 --- a/file.c +++ b/file.c @@ -37,6 +37,7 @@ #include "config.h" #include "file.h" #include "mime.h" +#include "str.h" #include "url.h" #include "util.h" @@ -50,10 +51,6 @@ file_free(struct file * file) free(file->path); file->path = NULL; } - if (file->name != NULL) { - free(file->name); - file->name = NULL; - } if (file->action_url != NULL) { free(file->action_url); file->action_url = NULL; @@ -61,7 +58,7 @@ file_free(struct file * file) free(file); } -static bool +static bool fill_metadata(struct file * f) { char *ext, *data_dir; @@ -77,7 +74,7 @@ fill_metadata(struct file * f) f->mime = MIME_BIN; /* check if it is a directory */ - path_len = url_build(path, PATH_MAX, data_dir, f->path, f->name, NULL); + path_len = url_build(path, PATH_MAX, data_dir, f->path, NULL); if (path_len == 0 || path_len >= PATH_MAX) return false; @@ -88,8 +85,8 @@ fill_metadata(struct file * f) f->is_dir = S_ISDIR(sb.st_mode); /* find mime from file extension */ - ext = strrchr(f->name, '.'); - if (!ext || ext == f->name) { + ext = strrchr(f->path, '.'); + if (!ext || ext == f->path) { return true; } ext++; @@ -99,27 +96,68 @@ fill_metadata(struct file * f) } struct file * -file_new(char *dir, size_t dir_len, char *name, size_t name_len) +file_new(const char *path) { struct file *file; + if (path == NULL) + return NULL; + file = (struct file *) calloc(1, sizeof(struct file)); if (file == NULL) return NULL; - file->path = strndup(dir, dir_len); - if (file->path == NULL) { - file_free(file); - return NULL; - } - file->name = strndup(name, name_len); - if (file->name == NULL) { - file_free(file); - return NULL; + /* empty path is considered as root */ + if (strlen(path) == 0) { + file->path = malloc(sizeof(char) * 2); + if (file->path == NULL) { + file_free(file); + return NULL; + } + strlcpy(file->path, "/", 2); + } else { + file->path = strdup(path); + if (file->path == NULL) { + file_free(file); + return NULL; + } } + if (!fill_metadata(file)) { file_free(file); return NULL; } return file; } + +char * +file_get_basename(const struct file * f) +{ + if (f == NULL || f->path == NULL) + return NULL; + + /* is the path a basename itself? */ + if (strrchr(f->path, '/') == NULL) + return f->path; + + /* split for the basename */ + return str_split(f->path, '/'); +} + +size_t +file_get_data_path(const struct file * f, char *data_path, size_t data_path_len) +{ + char *data_dir; + size_t path_len; + + data_dir = config_data_dir(); + if (data_dir == NULL) + return 0; + + /* check if it is a directory */ + path_len = url_build(data_path, data_path_len, data_dir, f->path, NULL); + if (path_len == 0 || path_len >= PATH_MAX) + return 0; + + return path_len; +} diff --git a/file.h b/file.h index f6dd5f7..38ca06e 100644 --- a/file.h +++ b/file.h @@ -42,12 +42,11 @@ */ struct file { SLIST_ENTRY(file) files; - size_t size; - enum mime mime; - char *path; /* relative to DATA_DIR */ - char *name; - char *action_url; /* action URL for HTML page */ - bool is_dir; + size_t size; + enum mime mime; + char *path; /* relative to DATA_DIR */ + char *action_url; /* action URL for HTML page */ + bool is_dir; }; /* @@ -58,9 +57,21 @@ void file_free(struct file *); /* - * Build a new file + * Build a new file from its relative paÃth to the data dir. */ struct file * -file_new(char *, size_t, char *, size_t); +file_new(const char *); + +/* + * Get the file basename. + */ +char * +file_get_basename(const struct file *); + +/* + * Build the data path (on the filesystem) for a file. + */ +size_t +file_get_data_path(const struct file *, char *, size_t); #endif /* FILE_H */ diff --git a/http.c b/http.c index ef8d90c..5bad1d8 100644 --- a/http.c +++ b/http.c @@ -37,12 +37,19 @@ #include "str.h" bool -http_open_file(struct kreq * r, enum khttp code, struct file * f) +http_open_file(struct kreq * r, enum khttp code, const struct file * f) { char *filename; + if (f == NULL || f->path == NULL) + return false; + + filename = file_get_basename(f); + if (filename == NULL) + return false; + /* file name needs to be url encoded for special chars */ - filename = khttp_urlencode(f->name); + filename = khttp_urlencode(filename); if (filename == NULL) return false; @@ -69,7 +76,7 @@ http_open(struct kreq * r, enum khttp code, enum kmime mime) } void -http_exit(struct kreq * r, enum khttp code, char *content,...) +http_exit(const struct kreq * r, enum khttp code, const char *content,...) { va_list args; diff --git a/http.h b/http.h index 6ca25e9..71a5d61 100644 --- a/http.h +++ b/http.h @@ -48,7 +48,7 @@ struct http_ret { * All parameters are required. */ bool -http_open_file(struct kreq *, enum khttp, struct file *); +http_open_file(struct kreq *, enum khttp, const struct file *); /* * Initialize headers and start the document body with the provided http code. @@ -67,6 +67,6 @@ http_open(struct kreq *, enum khttp, enum kmime); * This function exits with EXIT_FAILURE. It never returns. */ void -http_exit(struct kreq *, enum khttp, char *,...); +http_exit(const struct kreq *, enum khttp, const char *,...); #endif /* HTTP_H */ diff --git a/mime.c b/mime.c index 7136a99..57a0d2c 100644 --- a/mime.c +++ b/mime.c @@ -34,7 +34,7 @@ #include "mime.h" struct mime_map { - char* str; + char *str; enum mime mime; }; @@ -119,11 +119,11 @@ char* mime_desc_list[MIME__MAX] = { }; enum mime -mime_from_ext(char * ext) +mime_from_ext(const char *ext) { struct mime_map *mime; - for(mime = mime_ext_list; mime->str != NULL; mime++) { + for (mime = mime_ext_list; mime->str != NULL; mime++) { if (strcasecmp(ext, mime->str) == 0) { return mime->mime; } @@ -132,7 +132,7 @@ mime_from_ext(char * ext) } -char * +const char * mime_str(enum mime mime) { return mime_desc_list[mime]; diff --git a/mime.h b/mime.h index 40ad66a..5a88917 100644 --- a/mime.h +++ b/mime.h @@ -74,12 +74,12 @@ enum mime { * Find mime from file extension */ enum mime -mime_from_ext(char *); +mime_from_ext(const char *); /* * Return the mime type description */ -char * +const char * mime_str(enum mime); -#endif /* MIME_H */ +#endif /* MIME_H */ diff --git a/str.c b/str.c index 88a83b4..6521fa6 100644 --- a/str.c +++ b/str.c @@ -32,7 +32,7 @@ #include char * -str_split(char *str, char c) +str_split(const char *str, char c) { char *right, *result; size_t right_len; diff --git a/str.h b/str.h index 4d02cfc..76fd186 100644 --- a/str.h +++ b/str.h @@ -32,7 +32,7 @@ * Returns a newly allocated string that contains the beginning of the * provided string up to the provided char. */ -char *str_split(char *, char); +char *str_split(const char *, char); /* * Replaces a char in-place in the provided string. diff --git a/template.c b/template.c index f6a55b2..4ac3e9f 100644 --- a/template.c +++ b/template.c @@ -43,7 +43,7 @@ * to be used in case of success). */ static int -read_file(char *path, char **output, size_t * read_size) +read_file(const char *path, char **output, size_t * read_size) { long file_size; FILE *fp; @@ -82,7 +82,7 @@ read_file(char *path, char **output, size_t * read_size) } struct page_template * -page_template_new(char *page) +page_template_new(const char *page) { struct page_template *tmpl; char template_path[PATH_MAX]; diff --git a/template.h b/template.h index 560465f..966ab36 100644 --- a/template.h +++ b/template.h @@ -45,7 +45,8 @@ struct page_template { /* * Build a new set of templates for a specific page. */ -struct page_template *page_template_new(char *); +struct page_template * +page_template_new(const char *); /* * Free a set of templates. Should be able to free a partially allocated set of diff --git a/template/browse_head.html b/template/browse_head.html index 48ffee4..7ed3c58 100644 --- a/template/browse_head.html +++ b/template/browse_head.html @@ -1,4 +1,5 @@

Vault

+Upload here diff --git a/upload.c b/upload.c new file mode 100644 index 0000000..03e4169 --- /dev/null +++ b/upload.c @@ -0,0 +1,66 @@ +/* + * Copyright 2023, Vincent Douillet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "upload.h" +#include "url.h" + +/* + * upload url = r->pname / UPLOAD_URL / file->path + */ +size_t +build_upload_url(const struct kreq * r, struct file * file) +{ + char action_url[PATH_MAX]; + size_t action_url_len; + + if (!file->is_dir) + return 0; + + action_url_len = url_build(action_url, PATH_MAX, r->pname, UPLOAD_URL, + file->path, NULL); + if (action_url_len == 0 || action_url_len >= PATH_MAX) { + kutil_warn(r, NULL, + "upload: action URL overflow: %s", action_url); + return 0; + } + file->action_url = strndup(action_url, action_url_len); + if (file->action_url == NULL) { + kutil_warn(r, NULL, + "upload: unable to allocate file url buffer: %s", + action_url); + return 0; + } + return action_url_len; +} diff --git a/upload.h b/upload.h new file mode 100644 index 0000000..69dcb4c --- /dev/null +++ b/upload.h @@ -0,0 +1,54 @@ +/* + * Copyright 2023, Vincent Douillet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UPLOAD_H +#define UPLOAD_H + +#include + +#include "file.h" + +#define UPLOAD_URL "upload" + +/* + * Build the URL to download a file and assigns it to the file's action_url. + * All parameters are required + * Returns the length of the created URL, or 0 in case of failure. + */ +size_t +build_upload_url(const struct kreq *, struct file *); + +/* + * Print an upload form (http GET) or handle an upload form submission (http + * POST). + */ +struct http_ret upload(struct kreq *); + +#endif /* UPLOAD_H */ diff --git a/url.c b/url.c index 3e82821..adcc95d 100644 --- a/url.c +++ b/url.c @@ -38,9 +38,9 @@ #include "url.h" bool -check_request_path(char *path, char *suffix) +check_request_path(const char *path, const char *suffix) { - char p[PATH_MAX], resolved[PATH_MAX]; + char p [PATH_MAX], resolved[PATH_MAX]; char *rp, *data_dir; data_dir = config_data_dir(); @@ -61,7 +61,6 @@ check_request_path(char *path, char *suffix) if (strlcat(p, suffix, sizeof(p)) >= sizeof(p)) return false; } - /* canonicalize the path */ rp = realpath(p, resolved); if (rp == NULL) diff --git a/url.h b/url.h index cd52a3e..e91925b 100644 --- a/url.h +++ b/url.h @@ -41,7 +41,7 @@ * The suffix is required but can be an empty string */ bool -check_request_path(char *, char *); +check_request_path(const char *, const char *); /* * Build an URL from the provided components. -- cgit v1.2.3