diff --git a/Makefile.pc b/Makefile.pc
index 32b8978..e1d164c 100644
--- a/Makefile.pc
+++ b/Makefile.pc
@@ -20,7 +20,7 @@ BIN := websrv.pc
SRCS := src/main.c src/websrv.c src/asset.c src/fs.c
SRCS += src/pc/sys.c
-LDADD := -lmicrohttpd
+LDADD := -lmicrohttpd -lmagic
ASSETS := $(wildcard assets/*)
GEN_SRCS := $(patsubst assets/%,gen/%, $(ASSETS:=.c))
diff --git a/Makefile.ps5 b/Makefile.ps5
index e03f5a2..f5a575b 100644
--- a/Makefile.ps5
+++ b/Makefile.ps5
@@ -29,7 +29,8 @@ BIN := websrv.elf
SRCS := src/main.c src/websrv.c src/asset.c src/fs.c
SRCS += src/ps5/sys.c src/ps5/pt.c src/ps5/elfldr.c src/ps5/hbldr.c
CFLAGS := -Wall -Werror -Isrc
-LDADD := -lkernel_sys -lmicrohttpd -lSceSystemService -lSceUserService
+LDADD := -lkernel_sys -lSceSystemService -lSceUserService
+LDADD += -lmagic -lmicrohttpd
ASSETS := $(wildcard assets/*)
GEN_SRCS := $(patsubst assets/%,gen/%, $(ASSETS:=.c))
diff --git a/libmagic.sh b/libmagic.sh
new file mode 100755
index 0000000..8f46b46
--- /dev/null
+++ b/libmagic.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+# Copyright (C) 2024 John Törnblom
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not see
+# .
+
+LIB_URL="https://astron.com/pub/file/"
+LIB_VER="5.45"
+
+if [[ -z "$PS5_PAYLOAD_SDK" ]]; then
+ echo "error: PS5_PAYLOAD_SDK is not set"
+ exit 1
+fi
+
+source ${PS5_PAYLOAD_SDK}/toolchain/prospero.sh || exit 1
+
+TEMPDIR=$(mktemp -d)
+trap 'rm -rf -- "$TEMPDIR"' EXIT
+
+wget -O $TEMPDIR/lib.tar.gz $LIB_URL/file-$LIB_VER.tar.gz || exit 1
+tar xf $TEMPDIR/lib.tar.gz -C $TEMPDIR || exit 1
+
+cd $TEMPDIR/file-$LIB_VER
+./configure --prefix="${PS5_SYSROOT}" --host=x86_64 \
+ --disable-shared --enable-static
+${MAKE} install DESTDIR="/"
diff --git a/src/asset.c b/src/asset.c
index 39170b0..fbd1b29 100644
--- a/src/asset.c
+++ b/src/asset.c
@@ -17,6 +17,7 @@ along with this program; see the file COPYING. If not, see
#include
#include
+#include
#include
#include "asset.h"
@@ -38,6 +39,7 @@ along with this program; see the file COPYING. If not, see
typedef struct asset {
const char *path;
+ const char *mime;
void *data;
size_t size;
struct asset *next;
@@ -50,12 +52,23 @@ static asset_t* g_asset_head = 0;
void
asset_register(const char* path, void* data, size_t size) {
asset_t* a = calloc(1, sizeof(asset_t));
+ const char* mime;
+ magic_t m;
a->path = path;
a->data = data;
a->size = size;
a->next = g_asset_head;
+ if((m=magic_open(MAGIC_MIME))) {
+ if(!magic_load(m, NULL)) {
+ if((mime=magic_buffer(m, data, size))) {
+ a->mime = strdup(mime);
+ }
+ }
+ magic_close(m);
+ }
+
g_asset_head = a;
}
@@ -67,11 +80,13 @@ asset_request(struct MHD_Connection *conn, const char* url) {
size_t size = strlen(PAGE_404);
struct MHD_Response *resp;
void* data = PAGE_404;
+ const char* mime = 0;
for(asset_t* a=g_asset_head; a!=0; a=a->next) {
if(!strcmp(url, a->path)) {
data = a->data;
size = a->size;
+ mime = a->mime;
status = MHD_HTTP_OK;
break;
}
@@ -79,6 +94,9 @@ asset_request(struct MHD_Connection *conn, const char* url) {
if((resp=MHD_create_response_from_buffer(size, data,
MHD_RESPMEM_PERSISTENT))) {
+ if(mime) {
+ MHD_add_response_header(resp, "Content-Type", mime);
+ }
ret = websrv_queue_response(conn, status, resp);
MHD_destroy_response(resp);
}
diff --git a/src/fs.c b/src/fs.c
index 4099f67..92d0181 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -25,6 +25,7 @@ along with this program; see the file COPYING. If not, see
#include
#include
+#include
#include
#include "fs.h"
@@ -217,8 +218,10 @@ static enum MHD_Result
file_request(struct MHD_Connection *conn, const char* path) {
enum MHD_Result ret = MHD_NO;
struct MHD_Response *resp;
+ const char* mime;
struct stat st;
FILE *file = 0;
+ magic_t m;
if(!stat(path, &st)) {
file = fopen(path, "rb");
@@ -236,6 +239,15 @@ file_request(struct MHD_Connection *conn, const char* path) {
if((resp=MHD_create_response_from_callback(st.st_size, 32 * PAGE_SIZE,
&file_read, file,
&file_close))) {
+ if((m=magic_open(MAGIC_MIME))) {
+ if(!magic_load(m, NULL)) {
+ if((mime=magic_file(m, path))) {
+ MHD_add_response_header(resp, "Content-Type", mime);
+ }
+ }
+ magic_close(m);
+ }
+
ret = websrv_queue_response (conn, MHD_HTTP_OK, resp);
MHD_destroy_response(resp);
return ret;