///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Threading.Tasks;
using wasDAVClient;
using wasDAVClient.Model;
using wasSharp;
using wasSharpNET.IO.Utilities;
namespace wasStitchNET.Repository
{
public class Hashing
{
///
/// Hash local files inside a directory.
///
/// the path to a directory to hash
/// the partial hash buffer (default: 16384)
/// a SHA1 hash of all files in a directory ordered by name
public static async Task HashLocalFiles(string path, int bufferSize = 16384)
{
return await new Task(() =>
{
using (var sha1managed = new SHA1Managed())
{
foreach (var stream in Directory
.GetFiles(path, "*.*", SearchOption.AllDirectories)
.OrderBy(o => o.Split(Path.DirectorySeparatorChar).Last())
.Select(file => IOExtensions.GetWriteStream(file, FileMode.Open,
FileAccess.Read, FileShare.Read, STITCH_CONSTANTS.LOCAL_FILE_ACCESS_TIMEOUT)))
using (var binaryReader = new BinaryReader(stream))
{
var buff = new byte[bufferSize];
int read;
while ((read = binaryReader.Read(buff, 0, buff.Length)) != 0)
sha1managed.TransformBlock(buff, 0, read, null, 0);
}
sha1managed.TransformFinalBlock(new byte[] { }, 0, 0);
return sha1managed.Hash.ToHexString();
}
});
}
///
/// Hash the files of a Stitch remote repository release.
///
/// the server to hash the release for
/// the Stitch release to hash
/// the timeout in milliseconds to allow the server to respond
/// a SHA1 hash of all files in the release directory ordered by name
public static async Task HashRemoteFiles(string server, string update, int timeout)
{
using (var client = new Client(new NetworkCredential())
{
Timeout = timeout,
UserAgent = STITCH_CONSTANTS.USER_AGENT.Product.Name,
UserAgentVersion = STITCH_CONSTANTS.USER_AGENT.Product.Version,
Server = server,
BasePath = string.Join(@"/", STITCH_CONSTANTS.UPDATE_PATH,
STITCH_CONSTANTS.PROGRESSIVE_PATH)
})
{
return $"{await HashRemoteFiles(client, string.Join(@"/", update, STITCH_CONSTANTS.UPDATE_DATA_PATH))}";
}
}
///
/// Hash the files of a Stitch remote repository release using an existing was DAV client.
///
/// the was DAV client to use
/// the path to the repository release folder
/// the partial hash buffer (default: 16384)
/// a SHA1 hash of all files in the release directory ordered by name
public static async Task HashRemoteFiles(Client client, string path, int bufferSize = 16384)
{
using (var sha1managed = new SHA1Managed())
{
//var list = new List- ();
foreach (var stream in (await client.List(path, Constants.DavDepth.ALL))
.OrderBy(o => o.DisplayName)
.Where(item => !item.IsCollection)
.Select(file => client.Download(file.Href)))
using (var binaryReader = new BinaryReader(await stream))
{
var buff = new byte[bufferSize];
int read;
while ((read = binaryReader.Read(buff, 0, buff.Length)) != 0)
sha1managed.TransformBlock(buff, 0, read, null, 0);
}
sha1managed.TransformFinalBlock(new byte[] { }, 0, 0);
return sha1managed.Hash.ToHexString();
}
}
}
}