From 4e921ffa31fdca2425d326efda1c6d9ad190359a Mon Sep 17 00:00:00 2001
From: Vincent Douillet
Date: Mon, 9 Sep 2024 13:52:35 +0200
Subject: upload: handle form submission
---
README.md | 27 +++++----
browse.c | 4 +-
browse.h | 11 ++++
config.c | 4 +-
download.c | 2 +-
file.c | 6 +-
file.h | 6 +-
main.c | 2 +-
template/upload_head.html | 2 +-
test.c | 39 ++++++++++++-
upload.c | 139 +++++++++++++++++++++++++++++++++++++---------
11 files changed, 191 insertions(+), 51 deletions(-)
diff --git a/README.md b/README.md
index a140bc0..26597bf 100644
--- a/README.md
+++ b/README.md
@@ -32,16 +32,19 @@ By default on OpenBSD, the `slowcgi(8)` daemon allows a timeout of 2 minutes for
## Sample httpd.conf
server "server" {
- listen on * port 80
- connection timeout 540
- location "/vault/*" {
- root "/cgi-bin/vault"
- fastcgi param VAULT_DATA_DIR "/vault-data"
- request strip 1
- }
- location "/static/*" {
- root "/vault-static"
- request strip 1
- gzip-static
- }
+ listen on * port 80
+ connection {
+ # allow up to 512M uploads
+ max request body 536870912
+ }
+ location "/vault/*" {
+ root "/cgi-bin/vault"
+ fastcgi param VAULT_DATA_DIR "/vault-data"
+ request strip 1
+ }
+ location "/static/*" {
+ root "/vault-static"
+ request strip 1
+ gzip-static
+ }
}
diff --git a/browse.c b/browse.c
index ce76290..b233c8b 100644
--- a/browse.c
+++ b/browse.c
@@ -57,7 +57,7 @@ SLIST_HEAD(, file) list;
/*
* browse url = r->pname / BROWSE_URL / file->path
*/
-static size_t
+size_t
build_browse_url(struct kreq * r, struct file * file)
{
char action_url[PATH_MAX];
@@ -95,7 +95,7 @@ build_file_list(struct kreq * r, const struct file * request_dir)
struct file *last_file;
request_dir_len = file_get_data_path(request_dir, request_dir_path,
- PATH_MAX);
+ PATH_MAX, NULL);
if (request_dir_len == 0) {
kutil_warn(r, NULL,
"browse: Unable to build request dir path: %s",
diff --git a/browse.h b/browse.h
index 68d8c45..144eada 100644
--- a/browse.h
+++ b/browse.h
@@ -33,8 +33,19 @@
#include
+#include "file.h"
+
#define BROWSE_URL "browse"
+/*
+ * Build the URL to browse to a directory and assign 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_browse_url(struct kreq *, struct file *);
+
/*
* Print a browse page that allows to browse through the folder hierarchy.
* The KCGI request is required.
diff --git a/config.c b/config.c
index 4401d31..6e4061e 100644
--- a/config.c
+++ b/config.c
@@ -37,10 +37,10 @@ extern char **environ;
char *
config_data_dir()
{
- char *key;
+ char *key, **var;
key = "VAULT_DATA_DIR";
- for (char **var = environ; *var; var++) {
+ for (var = environ; *var; var++) {
if (strncmp(key, *var, strlen(key)) == 0) {
if (strlen(*var) <= strlen(key))
return NULL;
diff --git a/download.c b/download.c
index 15da06d..c18dcc1 100644
--- a/download.c
+++ b/download.c
@@ -129,7 +129,7 @@ download(struct kreq * r)
};
goto end;
}
- path_size = file_get_data_path(f, file_path, PATH_MAX);
+ path_size = file_get_data_path(f, file_path, PATH_MAX, NULL);
if (path_size == 0 || path_size >= PATH_MAX) {
ret = (struct http_ret) {
KHTTP_404,
diff --git a/file.c b/file.c
index 239f548..24fb557 100644
--- a/file.c
+++ b/file.c
@@ -145,7 +145,8 @@ file_get_basename(const struct file * f)
}
size_t
-file_get_data_path(const struct file * f, char *data_path, size_t data_path_len)
+file_get_data_path(const struct file * f, char *data_path, size_t data_path_len,
+ char *append)
{
char *data_dir;
size_t path_len;
@@ -155,7 +156,8 @@ file_get_data_path(const struct file * f, char *data_path, size_t data_path_len)
return 0;
/* check if it is a directory */
- path_len = url_build(data_path, data_path_len, data_dir, f->path, NULL);
+ path_len = url_build(data_path, data_path_len, data_dir, f->path,
+ append, NULL);
if (path_len == 0 || path_len >= PATH_MAX)
return 0;
diff --git a/file.h b/file.h
index 38ca06e..f6aac76 100644
--- a/file.h
+++ b/file.h
@@ -69,9 +69,11 @@ char *
file_get_basename(const struct file *);
/*
- * Build the data path (on the filesystem) for a file.
+ * Build the data path (on the filesystem) for a file and optionally append
+ * another component to the path. If no additional component is needed, it
+ * should be NULL.
*/
size_t
-file_get_data_path(const struct file *, char *, size_t);
+file_get_data_path(const struct file *, char *, size_t, char *);
#endif /* FILE_H */
diff --git a/main.c b/main.c
index 137ac14..430bc6a 100644
--- a/main.c
+++ b/main.c
@@ -74,7 +74,7 @@ main(void)
http_exit(NULL, KHTTP_500, "Data dir not configured");
/* A bit of security cannot hurt */
- if (-1 == unveil(data_dir, "r")
+ if (-1 == unveil(data_dir, "rwc")
|| -1 == unveil(TEMPLATE_DIR, "r")
|| -1 == unveil(NULL, NULL))
http_exit(&r, KHTTP_500, "Unveil failed: %s", strerror(errno));
diff --git a/template/upload_head.html b/template/upload_head.html
index fbdb209..542bc78 100644
--- a/template/upload_head.html
+++ b/template/upload_head.html
@@ -1,6 +1,6 @@
Uploading
to
@@path@@
-