wabbajack/Wabbajack.Lib/Downloaders/HTTPDownloader.cs

155 lines
4.8 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using Ceras;
using Wabbajack.Common;
using Wabbajack.Lib.Validation;
using File = Alphaleonis.Win32.Filesystem.File;
namespace Wabbajack.Lib.Downloaders
{
public class HTTPDownloader : IDownloader, IUrlDownloader
{
2019-11-21 15:51:57 +00:00
public AbstractDownloadState GetDownloaderState(dynamic archiveINI)
{
2019-11-21 15:51:57 +00:00
var url = archiveINI?.General?.directURL;
return GetDownloaderState(url, archiveINI);
}
public AbstractDownloadState GetDownloaderState(string uri)
{
return GetDownloaderState(uri, null);
}
2019-11-21 15:51:57 +00:00
public AbstractDownloadState GetDownloaderState(string url, dynamic archiveINI)
{
if (url != null)
{
var tmp = new State
{
Url = url
};
2019-11-21 15:51:57 +00:00
if (archiveINI?.General?.directURLHeaders != null)
{
tmp.Headers = new List<string>();
2019-11-21 15:51:57 +00:00
tmp.Headers.AddRange(archiveINI?.General.directURLHeaders.Split('|'));
}
return tmp;
}
return null;
}
public void Prepare()
{
}
[MemberConfig(TargetMember.All)]
public class State : AbstractDownloadState
{
public string Url { get; set; }
public List<string> Headers { get; set; }
[Exclude]
public HttpClient Client { get; set; }
public override bool IsWhitelisted(ServerWhitelist whitelist)
{
return whitelist.AllowedPrefixes.Any(p => Url.StartsWith(p));
}
public override void Download(Archive a, string destination)
{
DoDownload(a, destination, true);
}
public bool DoDownload(Archive a, string destination, bool download)
{
var client = Client ?? new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", Consts.UserAgent);
if (Headers != null)
foreach (var header in Headers)
{
var idx = header.IndexOf(':');
var k = header.Substring(0, idx);
var v = header.Substring(idx + 1);
client.DefaultRequestHeaders.Add(k, v);
}
2019-11-21 15:51:57 +00:00
long totalRead = 0;
var bufferSize = 1024 * 32;
var response = client.GetSync(Url);
var stream = response.Content.ReadAsStreamAsync();
try
{
stream.Wait();
}
2019-10-16 21:36:14 +00:00
catch (Exception)
{
}
if (stream.IsFaulted || response.StatusCode != HttpStatusCode.OK)
{
Utils.Log($"While downloading {Url} - {stream.Exception.ExceptionToString()}");
return false;
}
if (!download)
return true;
2019-11-21 15:51:57 +00:00
var headerVar = a.Size == 0 ? "1" : a.Size.ToString();
if (response.Content.Headers.Contains("Content-Length"))
2019-11-21 15:51:57 +00:00
headerVar = response.Content.Headers.GetValues("Content-Length").FirstOrDefault();
2019-11-21 15:51:57 +00:00
var contentSize = headerVar != null ? long.Parse(headerVar) : 1;
FileInfo fileInfo = new FileInfo(destination);
if (!fileInfo.Directory.Exists)
{
Directory.CreateDirectory(fileInfo.Directory.FullName);
}
using (var webs = stream.Result)
using (var fs = File.OpenWrite(destination))
{
2019-11-21 15:51:57 +00:00
var buffer = new byte[bufferSize];
while (true)
{
2019-11-21 15:51:57 +00:00
var read = webs.Read(buffer, 0, bufferSize);
if (read == 0) break;
2019-11-21 15:51:57 +00:00
Utils.Status($"Downloading {a.Name}", (int)(totalRead * 100 / contentSize));
fs.Write(buffer, 0, read);
2019-11-21 15:51:57 +00:00
totalRead += read;
}
}
return true;
}
public override bool Verify()
{
return DoDownload(new Archive {Name = ""}, "", false);
}
public override IDownloader GetDownloader()
{
return DownloadDispatcher.GetInstance<HTTPDownloader>();
}
public override string GetReportEntry(Archive a)
{
2019-10-13 03:06:44 +00:00
return $"* [{a.Name} - {Url}]({Url})";
}
}
}
}