예제 #1
0
            private async Task <CDNFileDefinition> GetDefinition()
            {
                var client = new Wabbajack.Lib.Http.Client();

                if (DomainRemaps.TryGetValue(Url.Host, out var remap))
                {
                    var builder = new UriBuilder(Url)
                    {
                        Host = remap
                    };
                    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>());
                }
            }
예제 #2
0
            public override async Task <bool> Download(Archive a, AbsolutePath destination)
            {
                destination.Parent.CreateDirectory();
                var definition = await GetDefinition();

                await using var fs = await destination.Create();

                using var mmfile = MemoryMappedFile.CreateFromFile(fs, null, definition.Size, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);
                var client = new Wabbajack.Lib.Http.Client();

                if (!DomainRemaps.ContainsKey(Url.Host))
                {
                    client.Headers.Add(("Host", Url.Host));
                }

                using var queue = new WorkQueue();
                await definition.Parts.PMap(queue, async part =>
                {
                    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);

                    if (DomainRemaps.TryGetValue(Url.Host, out var remap))
                    {
                        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);
            }
예제 #3
0
            private async Task <HttpResponseMessage> GetWithCDNRetry(Http.Client client, string url, CancellationToken?token = null)
            {
                int retries = 0;

TOP:

                try
                {
                    return(await client.GetAsync(url, retry : false, token : token));
                }
                catch (Exception ex)
                {
                    if (retries > 2)
                    {
                        Utils.Log($"Trying CDN...");
                        var remap = url.Replace(new Uri(url).Host, DomainRemaps.FirstOrDefault(x => x.Value == new Uri(url).Host).Key);
                        return(await client.GetAsync(remap, retry : false, token : token));
                    }
                    retries += 1;
                    Utils.Log($"Error reading {url} retrying [{retries}]");
                    Utils.Log(ex.ToString());
                    goto TOP;
                }
            }