fix: improve file path handling in API routes

- Updated file reading and database querying logic to decode URL-encoded paths, ensuring proper handling of special characters.
- Refactored path usage in the GET requests for both media file listing and content retrieval, enhancing compatibility with various file names.
This commit is contained in:
tigeren 2025-09-02 17:14:32 +00:00
parent 89930b833c
commit fbeed219fc
3 changed files with 21 additions and 15 deletions

Binary file not shown.

View File

@ -13,20 +13,23 @@ export async function GET(request: Request) {
return NextResponse.json({ error: "Path is required" }, { status: 400 });
}
// Decode the URL-encoded path to handle special characters
const decodedFilePath = decodeURIComponent(filePath);
try {
// Validate file exists
if (!fs.existsSync(filePath)) {
if (!fs.existsSync(decodedFilePath)) {
return NextResponse.json({ error: "File not found" }, { status: 404 });
}
// Check if it's a file (not directory)
const stats = fs.statSync(filePath);
const stats = fs.statSync(decodedFilePath);
if (!stats.isFile()) {
return NextResponse.json({ error: "Path is not a file" }, { status: 400 });
}
// Check if it's a text file
const ext = path.extname(filePath).toLowerCase().replace('.', '');
const ext = path.extname(decodedFilePath).toLowerCase().replace('.', '');
if (!TEXT_EXTENSIONS.includes(ext)) {
return NextResponse.json({ error: "File type not supported" }, { status: 400 });
}
@ -41,10 +44,10 @@ export async function GET(request: Request) {
let content = '';
try {
if (encoding === 'utf8') {
content = fs.readFileSync(filePath, 'utf-8');
content = fs.readFileSync(decodedFilePath, 'utf-8');
} else {
// For non-UTF-8 encodings, read as buffer and convert
const buffer = fs.readFileSync(filePath);
const buffer = fs.readFileSync(decodedFilePath);
const iconv = require('iconv-lite');
content = iconv.decode(buffer, encoding);
}
@ -55,9 +58,9 @@ export async function GET(request: Request) {
for (const fallbackEncoding of fallbackEncodings) {
try {
if (fallbackEncoding === 'utf8') {
content = fs.readFileSync(filePath, 'utf-8');
content = fs.readFileSync(decodedFilePath, 'utf-8');
} else {
const buffer = fs.readFileSync(filePath);
const buffer = fs.readFileSync(decodedFilePath);
const iconv = require('iconv-lite');
content = iconv.decode(buffer, fallbackEncoding);
}
@ -74,13 +77,13 @@ export async function GET(request: Request) {
// If no encoding worked, try reading as buffer and return as base64
if (!content || content.length === 0) {
try {
const buffer = fs.readFileSync(filePath);
const buffer = fs.readFileSync(decodedFilePath);
content = buffer.toString('base64');
return NextResponse.json({
content,
size: stats.size,
path: filePath,
name: path.basename(filePath),
path: decodedFilePath,
name: path.basename(decodedFilePath),
encoding: 'base64'
});
} catch (err) {
@ -91,8 +94,8 @@ export async function GET(request: Request) {
return NextResponse.json({
content,
size: stats.size,
path: filePath,
name: path.basename(filePath),
path: decodedFilePath,
name: path.basename(decodedFilePath),
encoding: encoding
});
} catch (error: any) {

View File

@ -16,19 +16,22 @@ export async function GET(request: Request) {
return NextResponse.json({ error: "Path is required" }, { status: 400 });
}
// Decode the URL-encoded path to handle special characters like +, spaces, Chinese characters, etc.
const decodedPath = decodeURIComponent(dirPath);
try {
const db = getDatabase();
const files = fs.readdirSync(dirPath);
const files = fs.readdirSync(decodedPath);
// Get media files from database for this path
const mediaFiles = db.prepare(`
SELECT id, path, type, thumbnail, avg_rating, star_count
FROM media
WHERE path LIKE ?
`).all(`${dirPath}%`) as Array<{id: number, path: string, type: string, thumbnail: string | null, avg_rating: number, star_count: number}>;
`).all(`${decodedPath}%`) as Array<{id: number, path: string, type: string, thumbnail: string | null, avg_rating: number, star_count: number}>;
const result = files.map((file) => {
const filePath = path.join(dirPath, file);
const filePath = path.join(decodedPath, file);
const stats = fs.statSync(filePath);
const ext = path.extname(file).toLowerCase();