Added support for changing Uri to the same file in case iold one expires.

This commit is contained in:
Michael Bucari-Tovo 2021-07-03 17:15:35 -06:00
parent da7af895fb
commit 6efe064ca7

View File

@ -15,13 +15,20 @@ namespace AaxDecrypter
/// </summary> /// </summary>
public class SingleUriCookieContainer : CookieContainer public class SingleUriCookieContainer : CookieContainer
{ {
public SingleUriCookieContainer(Uri uri) private Uri baseAddress;
{ public Uri Uri
Uri = uri; {
get => baseAddress;
set
{
baseAddress = new UriBuilder(value.Scheme, value.Host).Uri;
}
} }
public Uri Uri { get; }
public CookieCollection GetCookies() => base.GetCookies(Uri); public CookieCollection GetCookies()
{
return base.GetCookies(Uri);
}
} }
/// <summary> /// <summary>
@ -43,7 +50,7 @@ namespace AaxDecrypter
/// Http(s) address of the file to download. /// Http(s) address of the file to download.
/// </summary> /// </summary>
[JsonProperty(Required = Required.Always)] [JsonProperty(Required = Required.Always)]
public Uri Uri { get; } public Uri Uri { get; private set; }
/// <summary> /// <summary>
/// All cookies set by caller or by the remote server. /// All cookies set by caller or by the remote server.
@ -73,7 +80,7 @@ namespace AaxDecrypter
#region Private Properties #region Private Properties
private HttpWebRequest HttpRequest { get; } private HttpWebRequest HttpRequest { get; set; }
private FileStream _writeFile { get; } private FileStream _writeFile { get; }
private FileStream _readFile { get; } private FileStream _readFile { get; }
private Stream _networkStream { get; set; } private Stream _networkStream { get; set; }
@ -118,9 +125,35 @@ namespace AaxDecrypter
Uri = uri; Uri = uri;
WritePosition = writePosition; WritePosition = writePosition;
RequestHeaders = requestHeaders ?? new WebHeaderCollection(); RequestHeaders = requestHeaders ?? new WebHeaderCollection();
CookieContainer = cookies ?? new SingleUriCookieContainer(uri); CookieContainer = cookies ?? new SingleUriCookieContainer { Uri = uri };
_writeFile = new FileStream(SaveFilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
{
Position = WritePosition
};
HttpRequest = WebRequest.CreateHttp(uri); _readFile = new FileStream(SaveFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
SetUriForSameFile(uri);
}
#endregion
/// <summary>
/// Set a different <see cref="System.Uri"/> to the same file targeted by this instance of <see cref="NetworkFileStream"/>
/// </summary>
/// <param name="uriToSameFile">New <see cref="System.Uri"/> host must match existing host.</param>
public void SetUriForSameFile(Uri uriToSameFile)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(uriToSameFile?.AbsoluteUri, nameof(uriToSameFile));
if (uriToSameFile.Host != Uri.Host)
throw new ArgumentException($"New uri to the same file must have the same host.\r\n Old Host :{Uri.Host}\r\nNew Host: {uriToSameFile.Host}");
if (hasBegunDownloading && !finishedDownloading)
throw new Exception("Cannot change Uri during a download operation.");
Uri = uriToSameFile;
HttpRequest = WebRequest.CreateHttp(Uri);
HttpRequest.CookieContainer = CookieContainer; HttpRequest.CookieContainer = CookieContainer;
HttpRequest.Headers = RequestHeaders; HttpRequest.Headers = RequestHeaders;
@ -128,16 +161,8 @@ namespace AaxDecrypter
HttpRequest.Headers.Remove("Range"); HttpRequest.Headers.Remove("Range");
HttpRequest.AddRange(WritePosition); HttpRequest.AddRange(WritePosition);
_writeFile = new FileStream(SaveFilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
{
Position = WritePosition
};
_readFile = new FileStream(SaveFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
} }
#endregion
#region Downloader #region Downloader
/// <summary> /// <summary>
@ -152,7 +177,7 @@ namespace AaxDecrypter
/// <summary> /// <summary>
/// Begins downloading <see cref="Uri"/> to <see cref="SaveFilePath"/> in a background thread. /// Begins downloading <see cref="Uri"/> to <see cref="SaveFilePath"/> in a background thread.
/// </summary> /// </summary>
public async Task BeginDownloading() private void BeginDownloading()
{ {
if (ContentLength != 0 && WritePosition == ContentLength) if (ContentLength != 0 && WritePosition == ContentLength)
{ {
@ -164,7 +189,7 @@ namespace AaxDecrypter
if (ContentLength != 0 && WritePosition > ContentLength) if (ContentLength != 0 && WritePosition > ContentLength)
throw new Exception($"Specified write position (0x{WritePosition:X10}) is larger than the file size."); throw new Exception($"Specified write position (0x{WritePosition:X10}) is larger than the file size.");
var response = await HttpRequest.GetResponseAsync() as HttpWebResponse; var response = HttpRequest.GetResponse() as HttpWebResponse;
if (response.StatusCode != HttpStatusCode.PartialContent) if (response.StatusCode != HttpStatusCode.PartialContent)
throw new Exception($"Server at {Uri.Host} responded with unexpected status code: {response.StatusCode}."); throw new Exception($"Server at {Uri.Host} responded with unexpected status code: {response.StatusCode}.");
@ -249,8 +274,9 @@ namespace AaxDecrypter
{ {
var jObj = JObject.Load(reader); var jObj = JObject.Load(reader);
var result = new SingleUriCookieContainer(new Uri(jObj["Uri"].Value<string>())) var result = new SingleUriCookieContainer()
{ {
Uri = new Uri(jObj["Uri"].Value<string>()),
Capacity = jObj["Capacity"].Value<int>(), Capacity = jObj["Capacity"].Value<int>(),
MaxCookieSize = jObj["MaxCookieSize"].Value<int>(), MaxCookieSize = jObj["MaxCookieSize"].Value<int>(),
PerDomainCapacity = jObj["PerDomainCapacity"].Value<int>() PerDomainCapacity = jObj["PerDomainCapacity"].Value<int>()
@ -360,7 +386,7 @@ namespace AaxDecrypter
public override int Read(byte[] buffer, int offset, int count) public override int Read(byte[] buffer, int offset, int count)
{ {
if (!hasBegunDownloading) if (!hasBegunDownloading)
throw new Exception($"Must call {nameof(BeginDownloading)} before attempting to read {nameof(NetworkFileStream)};"); BeginDownloading();
long toRead = Math.Min(count, Length - Position); long toRead = Math.Min(count, Length - Position);
long requiredPosition = Position + toRead; long requiredPosition = Position + toRead;