summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--download.c37
-rw-r--r--http.c20
-rw-r--r--http.h2
-rw-r--r--str.c72
-rw-r--r--str.h40
-rw-r--r--template/head.html2
7 files changed, 142 insertions, 35 deletions
diff --git a/Makefile b/Makefile
index f24297e..7e84eea 100644
--- a/Makefile
+++ b/Makefile
@@ -47,10 +47,10 @@ all: main
.c.o:
$(CC) -o $@ -c $< $(CFLAGS)
-main: mime.o url.o template.o file.o http.o download.o browse.o main.o
+main: str.o mime.o url.o template.o file.o http.o download.o browse.o main.o
$(CC) -o $@ $> $(LDFLAGS)
-test: mime.o url.o template.o file.o http.o download.o browse.o test.o
+test: str.o mime.o url.o template.o file.o http.o download.o browse.o test.o
$(CC) -o $@ $> $(LDFLAGS)
env: env.o
diff --git a/download.c b/download.c
index f4a1881..bff1dd6 100644
--- a/download.c
+++ b/download.c
@@ -42,6 +42,7 @@
#include "download.h"
#include "file.h"
#include "http.h"
+#include "str.h"
#include "url.h"
#include "util.h"
@@ -75,32 +76,6 @@ 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;
-}
-
struct http_ret
download(struct kreq * r)
{
@@ -164,7 +139,7 @@ download(struct kreq * r)
goto end;
}
/* build file metadata */
- file_name = strsplit(request_path, '/');
+ file_name = str_split(request_path, '/');
if (file_name == NULL)
f = file_new("/", 1, request_path, strlen(request_path)); /* ROOT file */
else {
@@ -200,7 +175,13 @@ download(struct kreq * r)
}
}
/* write the file */
- http_open_file(r, KHTTP_200, f);
+ if (!http_open_file(r, KHTTP_200, f)) {
+ ret = (struct http_ret) {
+ KHTTP_500,
+ "download: filename url encoding failed"
+ };
+ goto end;
+ }
if (f->size > 0)
K_OK(khttp_write(r, (const char *) buffer, f->size), r);
diff --git a/http.c b/http.c
index b79b361..ef8d90c 100644
--- a/http.c
+++ b/http.c
@@ -34,16 +34,30 @@
#include "http.h"
#include "mime.h"
+#include "str.h"
-void
+bool
http_open_file(struct kreq * r, enum khttp code, struct file * f)
{
+ char *filename;
+
+ /* file name needs to be url encoded for special chars */
+ filename = khttp_urlencode(f->name);
+ if (filename == NULL)
+ return false;
+
+ /* but for some reason, spaces should remain spaces... */
+ str_replace(filename, '+', ' ');
+
khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[code]);
khttp_head(r, kresps[KRESP_CONTENT_DISPOSITION],
- "attachment;filename=\"%s\"", f->name);
+ "attachment;filename=\"%s\"", filename);
+ free(filename);
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 */
+ khttp_body_compress(r, 0); /* file is not compressed */
+
+ return true;
}
void
diff --git a/http.h b/http.h
index 5f09c88..6ca25e9 100644
--- a/http.h
+++ b/http.h
@@ -47,7 +47,7 @@ struct http_ret {
* Initialize headers and start the document body with the provided http code.
* All parameters are required.
*/
-void
+bool
http_open_file(struct kreq *, enum khttp, struct file *);
/*
diff --git a/str.c b/str.c
new file mode 100644
index 0000000..88a83b4
--- /dev/null
+++ b/str.c
@@ -0,0 +1,72 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+char *
+str_split(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
+str_replace(char *str, char a, char b)
+{
+ char *tmp;
+
+ tmp = str;
+ while (*tmp != '\0') {
+ if (*tmp == a)
+ *tmp = b;
+
+ tmp++;
+ }
+}
diff --git a/str.h b/str.h
new file mode 100644
index 0000000..4d02cfc
--- /dev/null
+++ b/str.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/*
+ * Returns a newly allocated string that contains the beginning of the
+ * provided string up to the provided char.
+ */
+char *str_split(char *, char);
+
+/*
+ * Replaces a char in-place in the provided string.
+ */
+void str_replace(char *, char, char);
diff --git a/template/head.html b/template/head.html
index d77eb49..51d0192 100644
--- a/template/head.html
+++ b/template/head.html
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="en">
-<meta charset=utf-8">
+<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Vault</title>
<head>