shoko/Protocols/FtpProtoHandler.cs

115 lines
3.4 KiB
C#
Raw Normal View History

2023-10-09 02:27:47 +00:00
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;
}
2023-10-20 04:59:28 +00:00
long _totalBytes = -1;
public override long TotalBytes => _totalBytes;
2023-10-09 02:27:47 +00:00
2023-10-20 04:59:28 +00:00
public override async Task Load()
2023-10-09 02:27:47 +00:00
{
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;
}
2023-10-20 05:41:54 +00:00
conn.Config.LogToConsole = false;
2023-10-09 02:27:47 +00:00
conn.Config.LogHost = true;
conn.Config.LogUserName = true;
conn.Config.LogPassword = true;
conn.Connect();
2023-10-20 04:59:28 +00:00
MediaType = "text/plain";
2023-10-09 02:27:47 +00:00
Status = "OK";
var info = conn.GetObjectInfo(file);
if(info is not null)
{
switch(info.Type)
{
case FtpObjectType.File:
2023-10-20 04:59:28 +00:00
_totalBytes = info.Size;
var stream = conn.OpenRead(file);
Content = await Download(stream);
MediaType = MimeGuesser.GuessMimeType(Content);
2023-10-09 02:27:47 +00:00
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";
}
}
2023-10-20 04:59:28 +00:00
OnLoaded();
2023-10-09 02:27:47 +00:00
}
public override void Render()
{
}
}