115 lines
3.4 KiB
C#
115 lines
3.4 KiB
C#
using System.Net;
|
|
using System.Text;
|
|
using FluentFTP;
|
|
using HeyRed.Mime;
|
|
|
|
namespace Shoko;
|
|
|
|
[Protocol("ftp")]
|
|
[Protocol("ftps")]
|
|
class FtpProtoHandler : ProtoHandler
|
|
{
|
|
public FtpProtoHandler(Uri url)
|
|
{
|
|
URL = url;
|
|
}
|
|
long _totalBytes = -1;
|
|
public override long TotalBytes => _totalBytes;
|
|
|
|
public override async Task Load()
|
|
{
|
|
var file = URL.AbsolutePath;
|
|
|
|
var conn = new FtpClient
|
|
{
|
|
Host = URL.Host,
|
|
Port = URL.Port
|
|
};
|
|
|
|
if (URL.UserInfo.Length > 0)
|
|
{
|
|
var userinfo = URL.UserInfo.Split(":",2);
|
|
var user = userinfo[0];
|
|
var pass = userinfo.Length > 1 ? userinfo[1] : "";
|
|
conn.Credentials = new NetworkCredential(user, pass);
|
|
}
|
|
|
|
if(URL.Scheme == "ftps")
|
|
{
|
|
conn.Config.EncryptionMode = FtpEncryptionMode.Explicit;
|
|
conn.Config.ValidateAnyCertificate = true;
|
|
}
|
|
|
|
conn.Config.LogToConsole = false;
|
|
conn.Config.LogHost = true;
|
|
conn.Config.LogUserName = true;
|
|
conn.Config.LogPassword = true;
|
|
|
|
conn.Connect();
|
|
|
|
MediaType = "text/plain";
|
|
Status = "OK";
|
|
|
|
var info = conn.GetObjectInfo(file);
|
|
|
|
if(info is not null)
|
|
{
|
|
switch(info.Type)
|
|
{
|
|
case FtpObjectType.File:
|
|
_totalBytes = info.Size;
|
|
var stream = conn.OpenRead(file);
|
|
Content = await Download(stream);
|
|
MediaType = MimeGuesser.GuessMimeType(Content);
|
|
break;
|
|
case FtpObjectType.Directory:
|
|
MediaType = "text/gemini";
|
|
var entries = conn.GetListing(info.FullName);
|
|
var str = "# "+file+"\r\n";
|
|
|
|
foreach(var entry in entries)
|
|
{
|
|
var path = entry.Name;
|
|
if(entry.Type == FtpObjectType.Directory) path += "/";
|
|
var target = new Uri(URL, path).ToString();
|
|
if(entry.Type == FtpObjectType.Link) target = new Uri(URL, info.LinkTarget).ToString();
|
|
str += string.Format("=>{0} {1}\r\n", target, path);
|
|
}
|
|
|
|
Content = new MemoryStream(Encoding.UTF8.GetBytes(str));
|
|
break;
|
|
case FtpObjectType.Link:
|
|
MediaType = "text/gemini";
|
|
Content = new MemoryStream(Encoding.UTF8.GetBytes("=>"+new Uri(URL, info.LinkTarget).ToString()));
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(conn.DirectoryExists(file))
|
|
{
|
|
MediaType = "text/gemini";
|
|
var entries = conn.GetListing(file);
|
|
var str = "# "+file+"\r\n";
|
|
|
|
foreach(var entry in entries)
|
|
{
|
|
var path = entry.Name;
|
|
if(entry.Type == FtpObjectType.Directory) path += "/";
|
|
str += string.Format("=>{0} {1}\r\n", new Uri(URL, path).ToString(), path);
|
|
}
|
|
|
|
Content = new MemoryStream(Encoding.UTF8.GetBytes(str));
|
|
}
|
|
else
|
|
{
|
|
Content = new MemoryStream(Encoding.UTF8.GetBytes("file not found"));
|
|
Status = "not found";
|
|
}
|
|
}
|
|
OnLoaded();
|
|
}
|
|
public override void Render()
|
|
{
|
|
}
|
|
} |