mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
2.2.2.0 - Route CDN through proxy
This commit is contained in:
parent
5d916da1ab
commit
865a592e09
@ -1,5 +1,8 @@
|
|||||||
### Changelog
|
### Changelog
|
||||||
|
|
||||||
|
#### Version - 2.2.2.0 - 8/31/2020
|
||||||
|
* Route CDN requests through a reverse proxy to improve reliability
|
||||||
|
|
||||||
#### Version - 2.2.1.7 - 8/25/2020
|
#### Version - 2.2.1.7 - 8/25/2020
|
||||||
* HOTFIX - Fix 404 errors with mirrors
|
* HOTFIX - Fix 404 errors with mirrors
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<AssemblyName>wabbajack-cli</AssemblyName>
|
<AssemblyName>wabbajack-cli</AssemblyName>
|
||||||
<Company>Wabbajack</Company>
|
<Company>Wabbajack</Company>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<AssemblyVersion>2.2.1.7</AssemblyVersion>
|
<AssemblyVersion>2.2.2.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.1.7</FileVersion>
|
<FileVersion>2.2.2.0</FileVersion>
|
||||||
<Copyright>Copyright © 2019-2020</Copyright>
|
<Copyright>Copyright © 2019-2020</Copyright>
|
||||||
<Description>An automated ModList installer</Description>
|
<Description>An automated ModList installer</Description>
|
||||||
<PublishReadyToRun>true</PublishReadyToRun>
|
<PublishReadyToRun>true</PublishReadyToRun>
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<AssemblyVersion>2.2.1.7</AssemblyVersion>
|
<AssemblyVersion>2.2.2.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.1.7</FileVersion>
|
<FileVersion>2.2.2.0</FileVersion>
|
||||||
<Copyright>Copyright © 2019-2020</Copyright>
|
<Copyright>Copyright © 2019-2020</Copyright>
|
||||||
<Description>Wabbajack Application Launcher</Description>
|
<Description>Wabbajack Application Launcher</Description>
|
||||||
<PublishReadyToRun>true</PublishReadyToRun>
|
<PublishReadyToRun>true</PublishReadyToRun>
|
||||||
|
@ -138,6 +138,12 @@ namespace Wabbajack.Lib.Downloaders
|
|||||||
|
|
||||||
var tempFile = new TempFile();
|
var tempFile = new TempFile();
|
||||||
|
|
||||||
|
if (WabbajackCDNDownloader.DomainRemaps.TryGetValue(patchResult.Host, out var remap))
|
||||||
|
{
|
||||||
|
var builder = new UriBuilder(patchResult) {Host = remap};
|
||||||
|
patchResult = builder.Uri;
|
||||||
|
}
|
||||||
|
|
||||||
using var response = await (await ClientAPI.GetClient()).GetAsync(patchResult);
|
using var response = await (await ClientAPI.GetClient()).GetAsync(patchResult);
|
||||||
|
|
||||||
await tempFile.Path.WriteAllAsync(await response.Content.ReadAsStreamAsync());
|
await tempFile.Path.WriteAllAsync(await response.Content.ReadAsStreamAsync());
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.IO.MemoryMappedFiles;
|
using System.IO.MemoryMappedFiles;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AngleSharp;
|
||||||
using Wabbajack.Common;
|
using Wabbajack.Common;
|
||||||
using Wabbajack.Common.Exceptions;
|
using Wabbajack.Common.Exceptions;
|
||||||
using Wabbajack.Common.Serialization.Json;
|
using Wabbajack.Common.Serialization.Json;
|
||||||
@ -13,8 +15,18 @@ using Wabbajack.Lib.Validation;
|
|||||||
|
|
||||||
namespace Wabbajack.Lib.Downloaders
|
namespace Wabbajack.Lib.Downloaders
|
||||||
{
|
{
|
||||||
|
|
||||||
public class WabbajackCDNDownloader : IDownloader, IUrlDownloader
|
public class WabbajackCDNDownloader : IDownloader, IUrlDownloader
|
||||||
{
|
{
|
||||||
|
public static Dictionary<string, string> DomainRemaps = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"wabbajack.b-cdn.net", "authored-files.wabbajack.org"},
|
||||||
|
{"wabbajack-mirror.b-cdn.net", "mirror.wabbajack.org"},
|
||||||
|
{"wabbajack-patches.b-cdn-net", "patches.wabbajack.org"},
|
||||||
|
{"wabbajacktest.b-cdn.net", "test-files.wabbajack.org"}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
public string[]? Mirrors;
|
public string[]? Mirrors;
|
||||||
public long TotalRetries;
|
public long TotalRetries;
|
||||||
|
|
||||||
@ -65,16 +77,34 @@ namespace Wabbajack.Lib.Downloaders
|
|||||||
await using var fs = await destination.Create();
|
await using var fs = await destination.Create();
|
||||||
using var mmfile = MemoryMappedFile.CreateFromFile(fs, null, definition.Size, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);
|
using var mmfile = MemoryMappedFile.CreateFromFile(fs, null, definition.Size, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);
|
||||||
var client = new Wabbajack.Lib.Http.Client();
|
var client = new Wabbajack.Lib.Http.Client();
|
||||||
client.Headers.Add(("Host", Url.Host));
|
|
||||||
|
if (!DomainRemaps.ContainsKey(Url.Host))
|
||||||
|
client.Headers.Add(("Host", Url.Host));
|
||||||
|
|
||||||
using var queue = new WorkQueue();
|
using var queue = new WorkQueue();
|
||||||
await definition.Parts.PMap(queue, async part =>
|
await definition.Parts.PMap(queue, async part =>
|
||||||
{
|
{
|
||||||
Utils.Status($"Downloading {a.Name}", Percent.FactoryPutInRange(definition.Parts.Length - part.Index, definition.Parts.Length));
|
Utils.Status($"Downloading {a.Name}", Percent.FactoryPutInRange(definition.Parts.Length - part.Index, definition.Parts.Length));
|
||||||
await using var ostream = mmfile.CreateViewStream(part.Offset, part.Size);
|
await using var ostream = mmfile.CreateViewStream(part.Offset, part.Size);
|
||||||
using var response = await GetWithMirroredRetry(client, $"{Url}/parts/{part.Index}");
|
|
||||||
if (!response.IsSuccessStatusCode)
|
if (DomainRemaps.TryGetValue(Url.Host, out var remap))
|
||||||
throw new HttpException((int)response.StatusCode, response.ReasonPhrase);
|
{
|
||||||
await response.Content.CopyToAsync(ostream);
|
var builder = new UriBuilder(Url) {Host = remap};
|
||||||
|
using var response = await client.GetAsync($"{builder}/parts/{part.Index}");
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
throw new HttpException((int)response.StatusCode, response.ReasonPhrase);
|
||||||
|
await response.Content.CopyToAsync(ostream);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using var response = await GetWithMirroredRetry(client, $"{Url}/parts/{part.Index}");
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
throw new HttpException((int)response.StatusCode, response.ReasonPhrase);
|
||||||
|
await response.Content.CopyToAsync(ostream);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -121,14 +151,26 @@ namespace Wabbajack.Lib.Downloaders
|
|||||||
var builder = new UriBuilder(url) {Host = hosts[rnd.Next(0, hosts.Length)]};
|
var builder = new UriBuilder(url) {Host = hosts[rnd.Next(0, hosts.Length)]};
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<CDNFileDefinition> GetDefinition()
|
private async Task<CDNFileDefinition> GetDefinition()
|
||||||
{
|
{
|
||||||
var client = new Wabbajack.Lib.Http.Client();
|
var client = new Wabbajack.Lib.Http.Client();
|
||||||
client.Headers.Add(("Host", Url.Host));
|
if (DomainRemaps.TryGetValue(Url.Host, out var remap))
|
||||||
using var data = await GetWithMirroredRetry(client, Url + "/definition.json.gz");
|
{
|
||||||
await using var gz = new GZipStream(await data.Content.ReadAsStreamAsync(), CompressionMode.Decompress);
|
var builder = new UriBuilder(Url) {Host = remap};
|
||||||
return gz.FromJson<CDNFileDefinition>();
|
using var data = await client.GetAsync(builder + "/definition.json.gz");
|
||||||
|
await using var gz = new GZipStream(await data.Content.ReadAsStreamAsync(),
|
||||||
|
CompressionMode.Decompress);
|
||||||
|
return gz.FromJson<CDNFileDefinition>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client.Headers.Add(("Host", Url.Host));
|
||||||
|
using var data = await GetWithMirroredRetry(client, Url + "/definition.json.gz");
|
||||||
|
await using var gz = new GZipStream(await data.Content.ReadAsStreamAsync(),
|
||||||
|
CompressionMode.Decompress);
|
||||||
|
return gz.FromJson<CDNFileDefinition>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IDownloader GetDownloader()
|
public override IDownloader GetDownloader()
|
||||||
|
@ -61,8 +61,7 @@ namespace Wabbajack.BuildServer.Test
|
|||||||
|
|
||||||
await Assert.ThrowsAsync<HttpException>(async () => await state.Download(new Archive(state) {Name = "test"}, tmp.Path));
|
await Assert.ThrowsAsync<HttpException>(async () => await state.Download(new Archive(state) {Name = "test"}, tmp.Path));
|
||||||
var downloader = DownloadDispatcher.GetInstance<WabbajackCDNDownloader>();
|
var downloader = DownloadDispatcher.GetInstance<WabbajackCDNDownloader>();
|
||||||
Assert.Equal(servers, downloader.Mirrors);
|
Assert.Null(downloader.Mirrors); // Now works through a host remap
|
||||||
Assert.Equal(6, downloader.TotalRetries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<AssemblyVersion>2.2.1.7</AssemblyVersion>
|
<AssemblyVersion>2.2.2.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.1.7</FileVersion>
|
<FileVersion>2.2.2.0</FileVersion>
|
||||||
<Copyright>Copyright © 2019-2020</Copyright>
|
<Copyright>Copyright © 2019-2020</Copyright>
|
||||||
<Description>Wabbajack Server</Description>
|
<Description>Wabbajack Server</Description>
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
@ -43,12 +43,14 @@ namespace Wabbajack.Test
|
|||||||
_unsubMsgs.Dispose();
|
_unsubMsgs.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task TestAllPrepares()
|
public async Task TestAllPrepares()
|
||||||
{
|
{
|
||||||
foreach (var downloader in DownloadDispatcher.Downloaders)
|
foreach (var downloader in DownloadDispatcher.Downloaders)
|
||||||
await downloader.Prepare();
|
await downloader.Prepare();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task MegaDownload()
|
public async Task MegaDownload()
|
||||||
@ -330,6 +332,7 @@ namespace Wabbajack.Test
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task VectorPlexusDownload()
|
public async Task VectorPlexusDownload()
|
||||||
{
|
{
|
||||||
@ -341,10 +344,6 @@ namespace Wabbajack.Test
|
|||||||
|
|
||||||
Assert.NotNull(state);
|
Assert.NotNull(state);
|
||||||
|
|
||||||
/*var url_state = DownloadDispatcher.ResolveArchive("https://www.loverslab.com/files/file/11116-test-file-for-wabbajack-integration/?do=download&r=737123&confirm=1&t=1");
|
|
||||||
Assert.Equal("http://build.wabbajack.org/WABBAJACK_TEST_FILE.txt",
|
|
||||||
((HTTPDownloader.State)url_state).Url);
|
|
||||||
*/
|
|
||||||
var converted = RoundTripState(state);
|
var converted = RoundTripState(state);
|
||||||
Assert.True(await converted.Verify(new Archive(state: null!) { Size = 20}));
|
Assert.True(await converted.Verify(new Archive(state: null!) { Size = 20}));
|
||||||
await using var filename = new TempFile();
|
await using var filename = new TempFile();
|
||||||
@ -357,7 +356,7 @@ namespace Wabbajack.Test
|
|||||||
|
|
||||||
Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync());
|
Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync());
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task YandexDownloader()
|
public async Task YandexDownloader()
|
||||||
@ -408,6 +407,7 @@ namespace Wabbajack.Test
|
|||||||
Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync());
|
Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Site is down
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task TESAllDownloader()
|
public async Task TESAllDownloader()
|
||||||
{
|
{
|
||||||
@ -431,6 +431,7 @@ namespace Wabbajack.Test
|
|||||||
|
|
||||||
Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync());
|
Assert.Equal("Cheese for Everyone!", await filename.Path.ReadAllTextAsync());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* WAITING FOR APPROVAL BY MODERATOR
|
/* WAITING FOR APPROVAL BY MODERATOR
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -15,8 +15,6 @@ namespace Wabbajack.Test
|
|||||||
{
|
{
|
||||||
var results = (await NexusUpdatesFeeds.GetUpdates()).ToArray();
|
var results = (await NexusUpdatesFeeds.GetUpdates()).ToArray();
|
||||||
|
|
||||||
Assert.NotEmpty(results);
|
|
||||||
|
|
||||||
Utils.Log($"Loaded {results.Length} updates from the Nexus");
|
Utils.Log($"Loaded {results.Length} updates from the Nexus");
|
||||||
|
|
||||||
foreach (var result in results)
|
foreach (var result in results)
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||||
<AssemblyVersion>2.2.1.7</AssemblyVersion>
|
<AssemblyVersion>2.2.2.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.1.7</FileVersion>
|
<FileVersion>2.2.2.0</FileVersion>
|
||||||
<Copyright>Copyright © 2019-2020</Copyright>
|
<Copyright>Copyright © 2019-2020</Copyright>
|
||||||
<Description>An automated ModList installer</Description>
|
<Description>An automated ModList installer</Description>
|
||||||
<PublishReadyToRun>true</PublishReadyToRun>
|
<PublishReadyToRun>true</PublishReadyToRun>
|
||||||
|
Loading…
Reference in New Issue
Block a user