fixes
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
const dns = require('dns');
|
||||
|
||||
class WTVFTP {
|
||||
wtvshared = null;
|
||||
wtvmime = null;
|
||||
@@ -14,18 +16,15 @@ class WTVFTP {
|
||||
const WTVMime = require("./WTVMime.js");
|
||||
this.url = require('url');
|
||||
this.ftp = require('ftp');
|
||||
this.wtvshared = new WTVShared();
|
||||
this.wtvmime = new WTVMime();
|
||||
this.wtvshared = new WTVShared(minisrv_config);
|
||||
this.wtvmime = new WTVMime(minisrv_config);
|
||||
}
|
||||
|
||||
handleFTPRequest(socket, request_headers) {
|
||||
// Handle the FTP request here
|
||||
// Assume request_headers.url contains the FTP URL
|
||||
this.request_headers = request_headers;
|
||||
const ftpUrl = request_headers.request_url;
|
||||
const parsed = this.url.parse(ftpUrl);
|
||||
|
||||
// Extract user, pass, and host
|
||||
let user = null;
|
||||
let pass = null;
|
||||
let host = parsed.hostname;
|
||||
@@ -36,10 +35,6 @@ class WTVFTP {
|
||||
pass = password || null;
|
||||
}
|
||||
|
||||
// Example usage: log the parsed values
|
||||
|
||||
|
||||
// You can now use user, pass, and host as needed
|
||||
if (!user && !pass) {
|
||||
user = "anonymous";
|
||||
pass = "anonymous@eff.org";
|
||||
@@ -51,73 +46,70 @@ class WTVFTP {
|
||||
let dir = path;
|
||||
let filename = null;
|
||||
|
||||
// Determine if path is a file or directory
|
||||
if (path && path !== '/') {
|
||||
const parts = path.split('/');
|
||||
if (parts[parts.length - 1] && !path.endsWith('/')) {
|
||||
filename = parts.pop();
|
||||
dir = parts.join('/') || '/';
|
||||
filename = parts.pop();
|
||||
dir = parts.join('/') || '/';
|
||||
}
|
||||
}
|
||||
|
||||
ftpClient.on('ready', () => {
|
||||
if (filename) {
|
||||
var totalsize = 0;
|
||||
// Change to directory and get file
|
||||
ftpClient.cwd(dir, (err) => {
|
||||
if (err) {
|
||||
this.sendToClient(socket, { 'Status': '500 Failed to change directory', 'Content-Type': 'text/plain' }, 'Failed to change directory');
|
||||
ftpClient.end();
|
||||
return;
|
||||
}
|
||||
ftpClient.get(filename, (err, stream) => {
|
||||
if (err) {
|
||||
this.sendToClient(socket, { 'Status': '404 File not found', 'Content-Type': 'text/plain' }, 'File not found');
|
||||
ftpClient.end();
|
||||
return;
|
||||
}
|
||||
const chunks = [];
|
||||
stream.on('data', (chunk) => {
|
||||
chunks.push(chunk);
|
||||
totalsize += chunk.length;
|
||||
if (totalsize > 1024 * 1024 * 4) {
|
||||
this.sendToClient(socket, { 'Status': '413 The file chosen contains too much information to be used.', 'Content-Type': 'text/plain' }, 'File too large');
|
||||
ftpClient.cwd(dir, (err) => {
|
||||
if (err) {
|
||||
this.sendToClient(socket, { 'Status': '500 Failed to change directory', 'Content-Type': 'text/plain' }, 'Failed to change directory');
|
||||
ftpClient.end();
|
||||
return;
|
||||
}
|
||||
ftpClient.get(filename, (err, stream) => {
|
||||
if (err) {
|
||||
this.sendToClient(socket, { 'Status': '404 File not found', 'Content-Type': 'text/plain' }, 'File not found');
|
||||
ftpClient.end();
|
||||
return;
|
||||
}
|
||||
const chunks = [];
|
||||
stream.on('data', (chunk) => {
|
||||
chunks.push(chunk);
|
||||
totalsize += chunk.length;
|
||||
if (totalsize > 1024 * 1024 * 4) {
|
||||
this.sendToClient(socket, { 'Status': '413 The file chosen contains too much information to be used.', 'Content-Type': 'text/plain' }, 'File too large');
|
||||
ftpClient.end();
|
||||
return;
|
||||
}
|
||||
});
|
||||
stream.on('end', () => {
|
||||
const buffer = Buffer.concat(chunks);
|
||||
const mime = this.wtvmime.detectMimeTypeFromBuffer(buffer);
|
||||
this.sendToClient(
|
||||
socket,
|
||||
{
|
||||
'Status': 200,
|
||||
'Content-Type': mime || 'application/octet-stream',
|
||||
'Content-Disposition': `attachment; filename="${filename}"`
|
||||
},
|
||||
buffer
|
||||
);
|
||||
ftpClient.end();
|
||||
});
|
||||
stream.on('error', () => {
|
||||
this.sendToClient(socket, { 'Status': '500 Error reading file', 'Content-Type': 'text/plain' }, 'Error reading file');
|
||||
ftpClient.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
stream.on('end', () => {
|
||||
const buffer = Buffer.concat(chunks);
|
||||
const mime = this.wtvmime.detectMimeTypeFromBuffer(buffer);
|
||||
this.sendToClient(
|
||||
socket,
|
||||
{
|
||||
'Status': 200,
|
||||
'Content-Type': mime || 'application/octet-stream',
|
||||
'Content-Disposition': `attachment; filename="${filename}"`
|
||||
},
|
||||
buffer
|
||||
);
|
||||
ftpClient.end();
|
||||
});
|
||||
stream.on('error', () => {
|
||||
this.sendToClient(socket, { 'Status': '500 Error reading file', 'Content-Type': 'text/plain' }, 'Error reading file');
|
||||
ftpClient.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// List directory
|
||||
ftpClient.list(dir, (err, list) => {
|
||||
if (err) {
|
||||
this.sendToClient(socket, { 'Status': '500 Failed to list directory', 'Content-Type': 'text/plain' }, 'Failed to list directory');
|
||||
ftpClient.end();
|
||||
return;
|
||||
}
|
||||
const html = this.formatDirectoryListing(list);
|
||||
this.sendToClient(socket, { 'Status': '200 OK', 'Content-Type': 'text/html' }, html);
|
||||
ftpClient.end();
|
||||
});
|
||||
ftpClient.list(dir, (err, list) => {
|
||||
if (err) {
|
||||
this.sendToClient(socket, { 'Status': '500 Failed to list directory', 'Content-Type': 'text/plain' }, 'Failed to list directory');
|
||||
ftpClient.end();
|
||||
return;
|
||||
}
|
||||
const html = this.formatDirectoryListing(list);
|
||||
this.sendToClient(socket, { 'Status': '200 OK', 'Content-Type': 'text/html' }, html);
|
||||
ftpClient.end();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -125,16 +117,23 @@ class WTVFTP {
|
||||
this.sendToClient(socket, { 'Status': '500 FTP connection error', 'Content-Type': 'text/plain' }, 'FTP connection error');
|
||||
});
|
||||
|
||||
ftpClient.connect({
|
||||
host: host,
|
||||
port: port,
|
||||
user: user,
|
||||
password: pass
|
||||
// FIX: Resolve host to IPv4 address before connecting
|
||||
dns.lookup(host, { family: 4 }, (err, address) => {
|
||||
if (err) {
|
||||
this.sendToClient(socket, { 'Status': '500 DNS resolution error', 'Content-Type': 'text/plain' }, 'DNS resolution error');
|
||||
return;
|
||||
}
|
||||
|
||||
ftpClient.connect({
|
||||
host: address,
|
||||
port: port,
|
||||
user: user,
|
||||
password: pass
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
formatDirectoryListing(list) {
|
||||
// Format the directory listing as needed
|
||||
let html = `<html>
|
||||
<head>
|
||||
<title>FTP Directory Listing</title>
|
||||
@@ -183,4 +182,4 @@ class WTVFTP {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WTVFTP;
|
||||
module.exports = WTVFTP;
|
||||
|
||||
Reference in New Issue
Block a user