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:
parent
89930b833c
commit
fbeed219fc
BIN
data/media.db
BIN
data/media.db
Binary file not shown.
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue