summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Douillet <vincent@vdouillet.fr>2024-01-23 09:22:00 +0100
committerVincent Douillet <vincent@vdouillet.fr>2024-02-08 09:27:54 +0100
commit42f538cc66546997a166dbe67e489c9afabbb908 (patch)
tree718bb6b7161892c4b964499c1818c6d7bf0bd6a6
parent760031b4a74d70bdeaab4ce9aedfe772acd05bd3 (diff)
download files
-rw-r--r--Makefile2
-rw-r--r--README.md4
-rw-r--r--browse.c4
-rw-r--r--download.c99
-rw-r--r--file.c41
-rw-r--r--file.h20
-rw-r--r--http.c12
-rw-r--r--http.h15
-rw-r--r--main.c4
-rw-r--r--mime.c139
-rw-r--r--mime.h85
-rw-r--r--url.c11
-rw-r--r--url.h3
-rw-r--r--util.c18
-rw-r--r--util.h14
15 files changed, 365 insertions, 106 deletions
diff --git a/Makefile b/Makefile
index 2b4d51c..2b91662 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ all: main
.c.o:
$(CC) -o $@ -c $< $(CFLAGS)
-main: util.o url.o http.o file.o download.o browse.o main.o
+main: util.o mime.o url.o file.o http.o download.o browse.o main.o
$(CC) -o $@ $> $(LDFLAGS)
env: env.o
diff --git a/README.md b/README.md
index decf0e5..231cc51 100644
--- a/README.md
+++ b/README.md
@@ -24,3 +24,7 @@ The vault binary will be installed as `/var/www/cgi-bin/vault`. You need to conf
# mkdir -p /var/www/var/log
# touch /var/www/var/log/vault.log
# chown www /var/www/var/log/vault.log
+
+By default on OpenBSD, the `slowcgi(8)` daemon allows a timeout of 2 minutes for CGI programs. This might not be enough if you want to allow users to download large files. This timeout can be increased by changing the `slowcgi(8)` parameters in `/etc/rc.conf.local`, for example to allow up to 10 minutes :
+
+ slowcgi_flags="-t 600"
diff --git a/browse.c b/browse.c
index 79b3f9c..849f571 100644
--- a/browse.c
+++ b/browse.c
@@ -71,7 +71,7 @@ build_browse_url(struct kreq * r, struct file * file)
"browse: action URL overflow: %s", action_url);
return 0;
}
- file->action_url = v_strcpy(action_url, action_url_len);
+ file->action_url = strndup(action_url, action_url_len);
if (file->action_url == NULL) {
kutil_warn(r, NULL,
"browse: unable to allocate file url buffer: %s",
@@ -188,7 +188,7 @@ browse(struct kreq * r)
struct template_data data;
/* check that the requested URL can be safely processed */
- if (!check_request_path(r->path))
+ if (!check_request_path(r->path, r->suffix))
http_exit(r, KHTTP_400, "browse: Invalid request path");
/* list requested directory content */
diff --git a/download.c b/download.c
index f506466..af490e1 100644
--- a/download.c
+++ b/download.c
@@ -33,6 +33,8 @@
#include <fcntl.h>
#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "cgi.h"
@@ -63,7 +65,7 @@ build_download_url(struct kreq * r, struct file * file)
"download: action URL overflow: %s", action_url);
return 0;
}
- file->action_url = v_strcpy(action_url, action_url_len);
+ file->action_url = strndup(action_url, action_url_len);
if (file->action_url == NULL) {
kutil_warn(r, NULL,
"download: unable to allocate file url buffer: %s",
@@ -73,50 +75,95 @@ build_download_url(struct kreq * r, struct file * file)
return action_url_len;
}
+static char *
+strsplit(char * str, char c) {
+ char *right, *result;
+ size_t right_len;
+
+ right = strrchr(str, c);
+ if(!right || right == str)
+ return NULL;
+
+ // move right part to new buffer
+ right_len = strlen(right);
+ result = malloc(sizeof(char) * right_len);
+ if(result == NULL)
+ return NULL;
+
+ if(strlcpy(result, right + 1, right_len) >= right_len) {
+ free(result);
+ return NULL;
+ }
+
+ // remove right part from src buffer
+ *right = '\0';
+
+ return result;
+}
+
void
download(struct kreq * r)
{
+ char *file_name;
void *buffer;
- struct stat st;
- int st_ret, fd;
- char file_path[PATH_MAX];
+ struct file* f;
+ int fd;
+ char file_path[PATH_MAX], request_path[PATH_MAX];
size_t path_size;
/* check that the requested URL can be safely processed */
- if (!check_request_path(r->path))
- http_exit(r, KHTTP_400, "download: Invalid request path");
+ if (strlen(r->path) == 0 || !check_request_path(r->path, r->suffix))
+ http_exit(r, KHTTP_400, "download: invalid request path");
/* build requested file path */
- path_size = url_build(file_path, PATH_MAX, DATA_DIR, r->path,
+ if(strlen(r->suffix) > 0) {
+ /* request with suffix */
+ if(snprintf(request_path, sizeof(request_path), "%s.%s", r->path, r->suffix)
+ >= (int) sizeof(request_path))
+ http_exit(r, KHTTP_414, NULL);
+ }
+ else {
+ if(snprintf(request_path, sizeof(request_path), "%s", r->path) >= (int) sizeof(request_path))
+ http_exit(r, KHTTP_414, NULL);
+ }
+
+ path_size = url_build(file_path, PATH_MAX, DATA_DIR, request_path,
NULL);
if (path_size == 0)
- http_exit(r, KHTTP_404, "download: Unable to build file path");
+ http_exit(r, KHTTP_404, "download: unable to build file path");
if (path_size >= PATH_MAX)
http_exit(r, KHTTP_414, NULL);
- /* check that it is a file */
-
+ /* build file metadata */
+ file_name = strsplit(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)
+ http_exit(r, KHTTP_404, "download: file metadata failure");
/* memory map the file */
fd = open(file_path, O_RDONLY);
- if (fd < 0)
- http_exit(r, KHTTP_404, "download: Unable to open file");
- st_ret = fstat(fd, &st);
- if (st_ret != 0)
- http_exit(r, KHTTP_404, "download: Unable to open file");
-
- /* TODO mmap does not work with empty file: st_size = 0 */
- buffer = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (buffer == MAP_FAILED)
- http_exit(r, KHTTP_500, "download: mmap failed");
+ if(fd < 0)
+ http_exit(r, KHTTP_404, "download: unable to open file");
+ /* mmap does not work with empty file: st_size = 0 */
+ if(f->size > 0) {
+ buffer = mmap(NULL, f->size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (buffer == MAP_FAILED)
+ http_exit(r, KHTTP_500, "download: mmap failed");
+ }
/* write the file */
- /* TODO proper filename & MIME type detection */
- K_OK(khttp_head(r, kresps[KRESP_CONTENT_DISPOSITION], "attachment; filename=\"File.txt\""), r);
- http_open(r, KHTTP_200, KMIME_TEXT_PLAIN);
- K_OK(khttp_write(r, (const char *) buffer, st.st_size), r);
+ http_open_file(r, KHTTP_200, f);
+ if(f->size > 0)
+ K_OK(khttp_write(r, (const char *) buffer, f->size), r);
/* cleanup */
- munmap(buffer, st.st_size);
- close(fd);
+ if(f->size > 0)
+ munmap(buffer, f->size);
+ free(f);
}
diff --git a/file.c b/file.c
index fba9682..be044ca 100644
--- a/file.c
+++ b/file.c
@@ -36,6 +36,7 @@
#include "config.h"
#include "file.h"
+#include "mime.h"
#include "url.h"
#include "util.h"
@@ -61,29 +62,17 @@ file_free(struct file * file)
}
static bool
-ext_cmp(char *ext, char **ext_list)
-{
- int i;
-
- for (i = 0; ext_list[i] != NULL; i++) {
- if (strcmp(ext, ext_list[i]) == 0)
- return true;
- }
-
- return false;
-}
-
-static bool
-find_type(struct file * f)
+fill_metadata(struct file * f)
{
char *ext;
- char *video_ext[] = {"mp4", "mkv", "avi", NULL};
- char *audio_ext[] = {"mp3", "flac", "aac", NULL};
- char *text_ext[] = {"txt", "doc", "docx", "odt", NULL};
char path[PATH_MAX];
struct stat sb;
size_t path_len;
+ /* default mime */
+ f->mime = MIME__MAX;
+
+ /* check if it is a directory */
path_len = url_build(path, PATH_MAX, DATA_DIR, f->path, f->name, NULL);
if (path_len == 0 || path_len >= PATH_MAX)
return false;
@@ -91,22 +80,16 @@ find_type(struct file * f)
if (stat(path, &sb) != 0)
return false;
+ f->size = sb.st_size;
f->is_dir = S_ISDIR(sb.st_mode);
+ /* find mime from file extension */
ext = strrchr(f->name, '.');
if (!ext || ext == f->name) {
- f->type = OTHER;
return true;
}
ext++;
- if (ext_cmp(ext, audio_ext))
- f->type = AUDIO;
- else if (ext_cmp(ext, video_ext))
- f->type = VIDEO;
- else if (ext_cmp(ext, text_ext))
- f->type = TEXT;
- else
- f->type = OTHER;
+ f->mime = mime_from_ext(ext);
return true;
}
@@ -120,17 +103,17 @@ file_new(char *dir, size_t dir_len, char *name, size_t name_len)
if (file == NULL)
return NULL;
- file->path = v_strcpy(dir, dir_len);
+ file->path = strndup(dir, dir_len);
if (file->path == NULL) {
file_free(file);
return NULL;
}
- file->name = v_strcpy(name, name_len);
+ file->name = strndup(name, name_len);
if (file->name == NULL) {
file_free(file);
return NULL;
}
- if (!find_type(file)) {
+ if (!fill_metadata(file)) {
file_free(file);
return NULL;
}
diff --git a/file.h b/file.h
index 27b8a19..f6dd5f7 100644
--- a/file.h
+++ b/file.h
@@ -35,23 +35,19 @@
#include <stdbool.h>
-enum file_type {
- AUDIO,
- VIDEO,
- TEXT,
- OTHER
-};
+#include "mime.h"
/*
* a file
*/
struct file {
- char *path; /* relative to DATA_DIR */
- char *name;
- char *action_url; /* action URL for HTML page */
- bool is_dir;
- enum file_type type;
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;
};
/*
@@ -65,6 +61,6 @@ file_free(struct file *);
* Build a new file
*/
struct file *
-file_new(char *dir, size_t dir_len, char *name, size_t name_len);
+file_new(char *, size_t, char *, size_t);
#endif /* FILE_H */
diff --git a/http.c b/http.c
index 4df7d93..b79b361 100644
--- a/http.c
+++ b/http.c
@@ -33,6 +33,18 @@
#include <stdlib.h>
#include "http.h"
+#include "mime.h"
+
+void
+http_open_file(struct kreq * r, enum khttp code, struct file * f)
+{
+ khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[code]);
+ khttp_head(r, kresps[KRESP_CONTENT_DISPOSITION],
+ "attachment;filename=\"%s\"", f->name);
+ khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", mime_str(f->mime));
+ khttp_head(r, kresps[KRESP_CONTENT_LENGTH], "%zu", f->size);
+ khttp_body_compress(r, 0); /* file is not compressed */
+}
void
http_open(struct kreq * r, enum khttp code, enum kmime mime)
diff --git a/http.h b/http.h
index 64ce472..1112f74 100644
--- a/http.h
+++ b/http.h
@@ -33,11 +33,21 @@
#include <kcgi.h>
+#include "file.h"
+
+/*
+ * Initialize headers and start the document body with the provided http code.
+ * All parameters are required.
+ */
+void
+http_open_file(struct kreq *, enum khttp, struct file *);
+
/*
* Initialize headers and start the document body with the provided http code.
* All parameters are required.
*/
-void http_open(struct kreq * r, enum khttp code, enum kmime mime);
+void
+http_open(struct kreq *, enum khttp, enum kmime);
/*
* Send a plain text error response.
@@ -48,6 +58,7 @@ void http_open(struct kreq * r, enum khttp code, enum kmime mime);
*
* This function exits with EXIT_FAILURE. It never returns.
*/
-void http_exit(struct kreq *, enum khttp, char *,...);
+void
+http_exit(struct kreq *, enum khttp, char *,...);
#endif /* HTTP_H */
diff --git a/main.c b/main.c
index 8f2e541..7a203c8 100644
--- a/main.c
+++ b/main.c
@@ -78,13 +78,13 @@ main(void)
*/
if (r.method != KMETHOD_GET && r.method != KMETHOD_POST)
http_exit(&r, KHTTP_405, NULL);
- if (r.mime != KMIME_TEXT_HTML)
- http_exit(&r, KHTTP_406, NULL); /* Not Acceptable */
if (r.page == PAGE__MAX)
http_exit(&r, KHTTP_404, NULL);
switch (r.page) {
case PAGE_BROWSE:
+ if (r.mime != KMIME_TEXT_HTML)
+ http_exit(&r, KHTTP_406, NULL); /* Not Acceptable */
browse(&r);
break;
case PAGE_DOWNLOAD:
diff --git a/mime.c b/mime.c
new file mode 100644
index 0000000..7136a99
--- /dev/null
+++ b/mime.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2023, Vincent Douillet <vincent@vdouillet.fr>
+ *
+ * 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 <stddef.h>
+#include <strings.h>
+
+#include "mime.h"
+
+struct mime_map {
+ char* str;
+ enum mime mime;
+};
+
+struct mime_map mime_ext_list[] = {
+ { "aac", MIME_AAC },
+ { "avi", MIME_AVI },
+ { "bin", MIME_BIN },
+ { "bz2", MIME_BZ2 },
+ { "csv", MIME_CSV },
+ { "doc", MIME_DOC },
+ { "docx", MIME_DOCX },
+ { "epub", MIME_EPUB },
+ { "gz", MIME_GZ },
+ { "gif", MIME_GIF },
+ { "html", MIME_HTML },
+ { "jar", MIME_JAR },
+ { "jpg", MIME_JPG },
+ { "jpeg", MIME_JPG },
+ { "log", MIME_TXT },
+ { "mkv", MIME_MKV },
+ { "mp3", MIME_MP3 },
+ { "mp4", MIME_MP4 },
+ { "odp", MIME_ODP },
+ { "ods", MIME_ODS },
+ { "odt", MIME_ODT },
+ { "png", MIME_PNG },
+ { "pdf", MIME_PDF },
+ { "ppt", MIME_PPT },
+ { "pptx", MIME_PPTX },
+ { "tar", MIME_TAR },
+ { "rar", MIME_RAR },
+ { "sh", MIME_SH },
+ { "svg", MIME_SVG },
+ { "svg", MIME_SVG },
+ { "txt", MIME_TXT },
+ { "webm", MIME_WEBM },
+ { "webp", MIME_WEBP },
+ { "xls", MIME_XLS },
+ { "xlsx", MIME_XLSX },
+ { "xml", MIME_XML },
+ { "zip", MIME_ZIP },
+ { "7z", MIME_7Z },
+ { NULL, MIME__MAX }
+};
+
+char* mime_desc_list[MIME__MAX] = {
+ "audio/aac", /* MIME_AAC */
+ "video/x-msvideo", /* MIME_AVI */
+ "application/octet-stream", /* MIME_BIN */
+ "application/x-bzip2", /* MIME_BZ2 */
+ "text/csv", /* MIME_CSV */
+ "application/msword", /* MIME_DOC */
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document", /* MIME_DOCX */
+ "application/epub+zip", /* MIME_EPUB */
+ "application/gzip", /* MIME_GZ */
+ "image/gif", /* MIME_GIF */
+ "text/html", /* MIME_HTML */
+ "application/java-archive", /* MIME_JAR */
+ "image/jpeg", /* MIME_JPG */
+ "video/x-matroska", /* MIME_MKV */
+ "audio/mpeg", /* MIME_MP3 */
+ "video/mp4", /* MIME_MP4 */
+ "application/vnd.oasis.opendocument.presentation", /* MIME_ODP */
+ "application/vnd.oasis.opendocument.spreadsheet", /* MIME_ODS */
+ "application/vnd.oasis.opendocument.text", /* MIME_ODT */
+ "image/png", /* MIME_PNG */
+ "application/pdf", /* MIME_PDF */
+ "application/vnd.ms-powerpoint", /* MIME_PPT */
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation", /* MIME_PPTX */
+ "application/vnd.rar", /* MIME_RAR */
+ "application/x-sh", /* MIME_SH */
+ "image/svg+xml", /* MIME_SVG */
+ "application/x-tar", /* MIME_TAR */
+ "text/plain", /* MIME_TXT */
+ "video/webm", /* MIME_WEBM */
+ "image/webp", /* MIME_WEBP */
+ "application/vnd.ms-excel", /* MIME_XLS */
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", /* MIME_XLSX */
+ "application/xml", /* MIME_XML */
+ "application/zip", /* MIME_ZIP */
+ "application/x-7z-compressed", /* MIME_7Z */
+};
+
+enum mime
+mime_from_ext(char * ext)
+{
+ struct mime_map *mime;
+
+ for(mime = mime_ext_list; mime->str != NULL; mime++) {
+ if (strcasecmp(ext, mime->str) == 0) {
+ return mime->mime;
+ }
+ }
+ return MIME_BIN;
+}
+
+
+char *
+mime_str(enum mime mime)
+{
+ return mime_desc_list[mime];
+}
diff --git a/mime.h b/mime.h
new file mode 100644
index 0000000..40ad66a
--- /dev/null
+++ b/mime.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2023, Vincent Douillet <vincent@vdouillet.fr>
+ *
+ * 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 MIME_H
+#define MIME_H
+
+enum mime {
+ MIME_AAC,
+ MIME_AVI,
+ MIME_BIN,
+ MIME_BZ2,
+ MIME_CSV,
+ MIME_DOC,
+ MIME_DOCX,
+ MIME_EPUB,
+ MIME_GZ,
+ MIME_GIF,
+ MIME_HTML,
+ MIME_JAR,
+ MIME_JPG,
+ MIME_MKV,
+ MIME_MP3,
+ MIME_MP4,
+ MIME_ODP,
+ MIME_ODS,
+ MIME_ODT,
+ MIME_PNG,
+ MIME_PDF,
+ MIME_PPT,
+ MIME_PPTX,
+ MIME_RAR,
+ MIME_SH,
+ MIME_SVG,
+ MIME_TAR,
+ MIME_TXT,
+ MIME_WEBM,
+ MIME_WEBP,
+ MIME_XLS,
+ MIME_XLSX,
+ MIME_XML,
+ MIME_ZIP,
+ MIME_7Z,
+ MIME__MAX,
+};
+
+/*
+ * Find mime from file extension
+ */
+enum mime
+mime_from_ext(char *);
+
+/*
+ * Return the mime type description
+ */
+char *
+mime_str(enum mime);
+
+#endif /* MIME_H */
diff --git a/url.c b/url.c
index 72c02a0..228efeb 100644
--- a/url.c
+++ b/url.c
@@ -38,9 +38,9 @@
#include "url.h"
bool
-check_request_path(char *path)
+check_request_path(char *path, char *suffix)
{
- char p [PATH_MAX], resolved[PATH_MAX];
+ char p[PATH_MAX], resolved[PATH_MAX];
char *rp;
/* build absolute path from DATA_DIR */
@@ -50,6 +50,13 @@ check_request_path(char *path)
return false;
if (strlcat(p, path, sizeof(p)) >= sizeof(p))
return false;
+ if (strlen(suffix) > 0) {
+ /* add suffix */
+ if(strlcat(p, ".", sizeof(p)) >= sizeof(p))
+ return false;
+ if(strlcat(p, suffix, sizeof(p)) >= sizeof(p))
+ return false;
+ }
/* canonicalize the path */
rp = realpath(p, resolved);
diff --git a/url.h b/url.h
index 63e487e..cd52a3e 100644
--- a/url.h
+++ b/url.h
@@ -38,9 +38,10 @@
* Checks that the path can be safely processed. Namely, it should not contain
* "..", which denotes an attempt to get out of the DATA_DIR root folder.
* The path is required.
+ * The suffix is required but can be an empty string
*/
bool
-check_request_path(char *);
+check_request_path(char *, char *);
/*
* Build an URL from the provided components.
diff --git a/util.c b/util.c
index f36ee4e..2822c89 100644
--- a/util.c
+++ b/util.c
@@ -42,21 +42,3 @@ read_file(char *path, char **output, size_t * read_size)
return 0;
}
-
-char *
-v_strcpy(char *str, size_t len)
-{
- char *new_str;
- size_t new_len;
-
- new_str = (char *) malloc(sizeof(char) * (len + 1));
- if (new_str == NULL)
- return NULL;
-
- new_len = strlcpy(new_str, str, len + 1);
- if (new_len >= len + 1) {
- free(new_str);
- return NULL;
- }
- return new_str;
-}
diff --git a/util.h b/util.h
index 460ed9e..2205808 100644
--- a/util.h
+++ b/util.h
@@ -3,18 +3,10 @@
/*
* Reads the file denoted by path into a newly allocated output buffer. Returns
- * 0 for success, -1 for error. read_size is the size of output buffer (only to
- * be used in case of success).
+ * 0 for success, -1 for error. The size_t is the size of output buffer (only
+ * to be used in case of success).
*/
int
-read_file(char *path, char **output, size_t * read_size);
-
-/*
- * Copies the provided string to a newly allocated buffer. Length of the
- * created string is the same as the provided string.
- * Returns the new string or NULL in case of failure.
- */
-char *
-v_strcpy(char *str, size_t len);
+read_file(char *, char **, size_t *);
#endif /* UTIL_H */