// Helper methods protected void LoadOuterManifest() { if (InnerProxy.Manifest.RootDirectory.Files.ContainsKey( DefaultOuterManifestFileName) == false) { throw new Exception("Encrypted manifest is not present."); } ManifestFileInfo outerManifestManifestFileInfo = InnerProxy.Manifest.RootDirectory.Files[ DefaultOuterManifestFileName]; FileInfo outerManifestFileInfo = InnerProxy.GetFile(outerManifestManifestFileInfo); Stream outerManifestFileStream = outerManifestFileInfo.OpenRead(); byte[] outerKeyBytes = CryptUtilities.MakeKeyBytesFromString( OuterKeyString, InnerProxy.Manifest.Guid.ToByteArray()); Stream outerManifestCryptoStream = CryptUtilities.MakeDecryptionReadStreamFrom( outerManifestFileStream, outerKeyBytes); OuterManifest = Manifest.ReadManifestStream(outerManifestCryptoStream); outerManifestCryptoStream.Close(); }
protected void SetManifestFileInfo( ManifestFileInfo manFileInfo, HttpRequest request, FileInfo file) { manFileInfo.FileLength = file.Length; long lastModifiedUtcTicks = long.Parse( request.Headers[RemoteRepositoryProxy.LastModifiedUtcHeaderName]); manFileInfo.LastModifiedUtc = new DateTime(lastModifiedUtcTicks, DateTimeKind.Utc); long registeredUtcTicks = long.Parse( request.Headers[RemoteRepositoryProxy.RegisteredUtcHeaderName]); manFileInfo.RegisteredUtc = new DateTime(registeredUtcTicks, DateTimeKind.Utc); string[] fileHashParts = request.Headers[RemoteRepositoryProxy.FileHashHeaderName].Split( new char[] { ':' }); manFileInfo.FileHash = new FileHash( fileHashParts[1], fileHashParts[0]); }
protected void RemoveFileHelper( IRepositoryProxy destRepository, ManifestFileInfo destFile) { if (Preview == false) { Exception exception; do { exception = null; try { destRepository.RemoveFile(destFile); } catch (Exception ex) { exception = ex; ErrorFiles.Add(destFile); WriteLine(" [ERROR]"); WriteLine(ex.ToString()); if (Retry == true) { // Wait a minute... System.Threading.Thread.Sleep( theRetryMilliseconds); } } } while (exception != null & Retry == true); } }
public FileInfo GetInnerFile(ManifestFileInfo readFile) { // We don't have an encrypted copy, so we must make a temp clone // and supply that instead. The clone will be removed eventually // during cleanup when the temp directory is deleted. return(CloneFile(readFile, TempDirectory)); }
// Helper methods protected void SetFileDates(ManifestFileInfo file) { FileInfo fileInfo = new FileInfo(MakeNativePath(file)); fileInfo.LastWriteTimeUtc = file.LastModifiedUtc; }
private static ManifestFileInfo ToManifestFileInfo(string s) { ManifestFileInfo ret = null; if (s.Length > 9 && s.Substring(0, 9) != "SourceUrl" && s.Substring(0, 10) != "MainModule" && s.Substring(0, 10) != "TargetPath" && s.Substring(0, 10) != "ServiceUrl") { string a = s; try { var i = a.IndexOf(separator); var name = a.Substring(0, i); a = a.Substring(i + 1); i = a.IndexOf(separator); var size = a.Substring(0, i); a = a.Substring(i + 1); i = a.IndexOf(separator); var version = a.Substring(0, i); var dateCreate = a.Substring(i + 1); ret = new ManifestFileInfo { Name = name, Size = Convert.ToInt32(size), Version = version, DateCreate = dateCreate }; } catch (Exception e) { throw new Exception(e.Message + " Module=ToManifestFileInfo"); } } return(ret); }
// Implement IRepositoryProxy public void PutFile( IRepositoryProxy sourceRepository, ManifestFileInfo sourceManifestFile) { FileInfo fileCopy = sourceRepository.CloneFile( sourceManifestFile, TempDirectory); String newFilePath = MakeNativePath(sourceManifestFile); String directoryPath = Path.GetDirectoryName(newFilePath); if (Directory.Exists(directoryPath) == false) { Directory.CreateDirectory(directoryPath); } if (File.Exists(newFilePath)) { File.Delete(newFilePath); } fileCopy.MoveTo(newFilePath); ManifestFileInfo newFileInfo = Manifest.PutFileFromOtherManifest( sourceManifestFile); SetFileDates(newFileInfo); SetManifestChanged(); }
public void CopyOrMoveFile( ManifestFileInfo fileToBeCopied, ManifestFileInfo otherFileWithNewLocation, String method, int timeout) { Uri requestUri = MakeRemoteUri(fileToBeCopied); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri); request.Method = method; request.Timeout = timeout; SetStandardFileHeaders(request, otherFileWithNewLocation); String destPathString = Manifest.MakeStandardPathString(otherFileWithNewLocation); String escapedDestPathString = System.Uri.EscapeDataString(destPathString); request.Headers[RemoteRepositoryProxy.DestinationPathHeaderName] = escapedDestPathString; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); response.Close(); }
public void MoveFile( ManifestFileInfo fileToBeMoved, ManifestFileInfo otherFileWithNewLocation) { String oldFilePath = MakeNativePath(fileToBeMoved); String newFilePath = MakeNativePath(otherFileWithNewLocation); String directoryPath = Path.GetDirectoryName(newFilePath); if (Directory.Exists(directoryPath) == false) { Directory.CreateDirectory(directoryPath); } File.Move(oldFilePath, newFilePath); RemoveEmptyParentDirectories(oldFilePath); fileToBeMoved.ParentDirectory.Files.Remove( fileToBeMoved.Name); ManifestFileInfo newFileInfo = Manifest.PutFileFromOtherManifest( otherFileWithNewLocation); SetFileDates(newFileInfo); SetManifestChanged(); }
public FileInfo CloneFile( ManifestFileInfo copyFile, DirectoryInfo copyToDirectory) { ManifestFileInfo innerManifestFileInfo = HashToInnerFileMap[copyFile.FileHash]; FileInfo innerFileInfo = InnerProxy.GetFile(innerManifestFileInfo); byte[] keyData = CryptUtilities.MakeKeyBytesFromString( OuterKeyString, copyFile.FileHash.HashData); String destFilePath = Path.Combine( copyToDirectory.FullName, DefaultDecryptedTempFileName); ReadCryptFile( innerFileInfo, keyData, destFilePath); FileInfo fileInfo = new FileInfo(destFilePath); // Make sure that the last-modified date matches that of the // expected outer file. This is necessary because one inner file // may correspond to several outer files - each of which might // have separate dates. fileInfo.LastWriteTimeUtc = copyFile.LastModifiedUtc; return(fileInfo); }
public void Add(ManifestFileInfo manFileInfo) { if (Dict.ContainsKey(manFileInfo.FileHash) == false) { Dict.Add(manFileInfo.FileHash, new List <ManifestFileInfo>()); } Dict[manFileInfo.FileHash].Add(manFileInfo); }
protected void SaveOuterManifest() { // Serialize the manifest to memory MemoryStream serializedManifestStream = new MemoryStream(); OuterManifest.WriteManifestStream(serializedManifestStream); serializedManifestStream.Position = 0; String tempFilePath = Path.Combine( InnerProxy.TempDirectory.FullName, DefaultOuterManifestFileName); // We use the inner GUID as salt for the outer manifest, so update // it each time we write the outer manifest. The inner GUID is // really useless anyways. InnerProxy.Manifest.ChangeGUID(); byte[] outerKeyData = CryptUtilities.MakeKeyBytesFromString( OuterKeyString, InnerProxy.Manifest.Guid.ToByteArray()); byte[] cryptHash = WriteCryptFileAndHash( serializedManifestStream, outerKeyData, tempFilePath); // The new ManifestFileInfo is actually rooted in the inner // Manifest object, but that is ok - although it is kind of a // hack. The fact is that we don't maintain an actual Manifest // object to mirror the inner manifest - and we know that the // implementation of PutFile won't be affected by doing this. ManifestDirectoryInfo parentDirectory = InnerProxy.Manifest.RootDirectory; ManifestFileInfo destManifestFile = new ManifestFileInfo( DefaultOuterManifestFileName, parentDirectory); destManifestFile.RegisteredUtc = DateTime.Now; FileInfo outerManifestFileInfo = new FileInfo(tempFilePath); destManifestFile.LastModifiedUtc = outerManifestFileInfo.LastWriteTimeUtc; destManifestFile.FileLength = outerManifestFileInfo.Length; destManifestFile.FileHash = new FileHash(cryptHash, CryptUtilities.DefaultHashType); InnerProxy.PutFile(ProxyToInner, destManifestFile); }
protected void CompareManifestsRecursiveSource( ManifestDirectoryInfo sourceDir, ManifestDirectoryInfo destDir, HashSet <ManifestFileInfo> destFileMatch) { foreach (ManifestFileInfo sourceFile in sourceDir.Files.Values) { if (destDir != null && destDir.Files.ContainsKey(sourceFile.Name)) { ManifestFileInfo destFile = destDir.Files[sourceFile.Name]; destFileMatch.Add(destFile); if (sourceFile.FileHash.Equals(destFile.FileHash) == false) { ChangedFiles.Add(sourceFile, destFile); } else { if (Manifest.CompareManifestDates( sourceFile.LastModifiedUtc, destFile.LastModifiedUtc) == false) { LastModifiedDateFiles.Add(sourceFile, destFile); } if (Manifest.CompareManifestDates( sourceFile.RegisteredUtc, destFile.RegisteredUtc) == false) { RegisteredDateFiles.Add(sourceFile, destFile); } } } else { SourceOnlyFiles.Add(sourceFile); } } foreach (ManifestDirectoryInfo nextSourceDir in sourceDir.Subdirectories.Values) { ManifestDirectoryInfo nextDestDir = null; if (destDir != null && destDir.Subdirectories.ContainsKey(nextSourceDir.Name)) { nextDestDir = destDir.Subdirectories[nextSourceDir.Name]; } CompareManifestsRecursiveSource( nextSourceDir, nextDestDir, destFileMatch); } }
public void CopyFile( ManifestFileInfo fileToBeCopied, ManifestFileInfo otherFileWithNewLocation) { CopyOrMoveFile( fileToBeCopied, otherFileWithNewLocation, "COPY", RequestTimeout); }
public void MoveFile( ManifestFileInfo fileToBeMoved, ManifestFileInfo otherFileWithNewLocation) { CopyOrMoveFile( fileToBeMoved, otherFileWithNewLocation, "MOVE", RequestTimeout); }
public void RemoveFile( ManifestFileInfo removeManifestFile) { // Just remove the file from the outer manifest for now. // When we clean up, we'll remove the actual file if there // are no longer any references to it. removeManifestFile.ParentDirectory.Files.Remove( removeManifestFile.Name); myManifestChanged = true; }
protected void HandleDeleteRequest( HttpClientContext context, HttpRequest request) { try { LocalRepositoryState repoState = GetRepositoryFromRequest(request); // TODO: Authenticate based on request address String filePath = GetLocalFilePathFromRequest(request); File.Delete(filePath); HttpResponse response = (HttpResponse)request.CreateResponse(context); response.ContentType = "application/octet-stream"; lock (repoState.Manifest) { ManifestFileInfo manFileInfo = GetOrMakeManifestFileInfoFromRequest( repoState.Manifest, request, false); if (manFileInfo == null) { throw new Exception( "File not registered: " + filePath); } manFileInfo.ParentDirectory.Files.Remove( manFileInfo.Name); repoState.SetManifestChanged(); } context.Respond( "HTTP/1.0", HttpStatusCode.OK, "File accepted", "", "text/plain"); } catch (Exception ex) { context.Respond( "HTTP/1.0", HttpStatusCode.InternalServerError, "Internal server error", ex.ToString(), "text/plain"); } }
public FileInfo CloneFile( ManifestFileInfo copyFile, DirectoryInfo copyToDirectory) { Uri requestUri = MakeRemoteUri(copyFile); int retries = 0; bool success = false; string tempFilePath = null; do { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri); request.Method = "GET"; request.Timeout = RequestTimeout; request.ReadWriteTimeout = RequestReadWriteTimeout; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); tempFilePath = Path.Combine( TempDirectory.FullName, copyFile.FileHash.ToString()); using (FileStream fileStream = new FileStream( tempFilePath, FileMode.Create)) { StreamUtilities.CopyStream(response.GetResponseStream(), fileStream); response.GetResponseStream().Close(); } success = true; } catch (System.Net.WebException ex) { System.Console.WriteLine("RETRY: " + ++numRetries); if (++retries > MaxNumberOfRequestRetries) { throw ex; } System.Threading.Thread.Sleep(RequestRetryWaitInterval); } } while (success == false); return(new FileInfo(tempFilePath)); }
public void CopyFile( ManifestFileInfo fileToBeCopied, ManifestFileInfo otherFileWithNewLocation) { // No need to actually copy a file, just copy it in the // outer manifest. ManifestFileInfo newFileInfo = Manifest.PutFileFromOtherManifest( otherFileWithNewLocation); myManifestChanged = true; }
public void RemoveFile(ManifestFileInfo removeManifestFile) { String removeFilePath = MakeNativePath(removeManifestFile); File.Delete(removeFilePath); RemoveEmptyParentDirectories(removeFilePath); removeManifestFile.ParentDirectory.Files.Remove( removeManifestFile.Name); SetManifestChanged(); }
public void CopyFileInformation( ManifestFileInfo fileToBeUpdated, ManifestFileInfo otherFileWithNewFileInfo) { // No need to actually change the file information, just change // it in the outer manifest. fileToBeUpdated.LastModifiedUtc = otherFileWithNewFileInfo.LastModifiedUtc; fileToBeUpdated.RegisteredUtc = otherFileWithNewFileInfo.RegisteredUtc; myManifestChanged = true; }
public void CopyFileInformation( ManifestFileInfo fileToBeUpdated, ManifestFileInfo otherFileWithNewFileInfo) { fileToBeUpdated.LastModifiedUtc = otherFileWithNewFileInfo.LastModifiedUtc; fileToBeUpdated.RegisteredUtc = otherFileWithNewFileInfo.RegisteredUtc; SetFileDates(fileToBeUpdated); SetManifestChanged(); }
public void PutFile( IRepositoryProxy sourceRepository, ManifestFileInfo sourceManifestFile) { FileInfo sourceFile = sourceRepository.GetFile(sourceManifestFile); Uri requestUri = MakeRemoteUri(sourceManifestFile); int retries = 0; bool success = false; do { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri); request.Method = "PUT"; request.Timeout = RequestTimeout; request.ReadWriteTimeout = RequestReadWriteTimeout; request.AllowWriteStreamBuffering = false; SetStandardFileHeaders(request, sourceManifestFile); using (FileStream fileStream = sourceFile.OpenRead()) { request.ContentLength = fileStream.Length; StreamUtilities.CopyStream(fileStream, request.GetRequestStream()); request.GetRequestStream().Close(); } HttpWebResponse response = (HttpWebResponse)request.GetResponse(); response.Close(); success = true; } catch (System.Net.WebException ex) { if (++retries > MaxNumberOfRequestRetries) { throw ex; } System.Threading.Thread.Sleep(RequestRetryWaitInterval); } } while (success == false); }
protected void HandleSetFileInfoRequest( HttpClientContext context, HttpRequest request) { try { LocalRepositoryState repoState = GetRepositoryFromRequest(request); // TODO: Authenticate based on request address // ...delete temp file if not authenticated... // Better to authenticate when the headers are received... String newFilePath = GetLocalFilePathFromRequest(request); FileInfo newFile = new FileInfo(newFilePath); lock (repoState.Manifest) { ManifestFileInfo manFileInfo = GetOrMakeManifestFileInfoFromRequest( repoState.Manifest, request, false); SetManifestFileInfo(manFileInfo, request, newFile); newFile.LastWriteTimeUtc = manFileInfo.LastModifiedUtc; repoState.SetManifestChanged(); } context.Respond( "HTTP/1.0", HttpStatusCode.OK, "Info accepted", "", "text/plain"); } catch (Exception ex) { context.Respond( "HTTP/1.0", HttpStatusCode.InternalServerError, "Internal server error", ex.ToString(), "text/plain"); System.Console.WriteLine(ex.ToString()); } }
protected void SetStandardFileHeaders( HttpWebRequest request, ManifestFileInfo file) { request.Headers[RemoteRepositoryProxy.LastModifiedUtcHeaderName] = file.LastModifiedUtc.Ticks.ToString(); request.Headers[RemoteRepositoryProxy.RegisteredUtcHeaderName] = file.RegisteredUtc.Ticks.ToString(); request.Headers[RemoteRepositoryProxy.FileHashHeaderName] = file.FileHash.HashType + ":" + file.FileHash.ToString(); }
public void RemoveFile(ManifestFileInfo removeManifestFile) { Uri requestUri = MakeRemoteUri(removeManifestFile); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri); request.Method = "DELETE"; request.Timeout = RequestTimeout; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); response.Close(); }
protected Uri MakeRemoteUri(ManifestFileInfo remoteFile) { String manifestPath = Manifest.MakeStandardPathString(remoteFile); // Remove the leading '.' from the relative path String uriPathString = manifestPath.Substring(1, manifestPath.Length - 1); String escapedUriPathString = System.Uri.EscapeDataString(uriPathString); Uri uri = new Uri(BaseUri.ToString() + escapedUriPathString); return(uri); }
protected void ValidateFile( ManifestFileInfo outerManFileInfo, Utilities.Console console) { ManifestFileInfo innerManifestFileInfo = null; try { innerManifestFileInfo = HashToInnerFileMap[outerManFileInfo.FileHash]; FileInfo innerFileInfo = InnerProxy.GetFile(innerManifestFileInfo); byte[] keyData = CryptUtilities.MakeKeyBytesFromString( OuterKeyString, outerManFileInfo.FileHash.HashData); Stream sourceFileStream = innerFileInfo.OpenRead(); Stream cryptoStream = CryptUtilities.MakeDecryptionReadStreamFrom( sourceFileStream, keyData); FileHash computedHash = FileHash.ComputeHash( cryptoStream, outerManFileInfo.FileHash.HashType); if (computedHash.Equals(outerManFileInfo.FileHash) == false) { throw new Exception("FAILED VALIDATION"); } } catch (Exception e) { console.WriteLine( Manifest.MakeStandardPathString(outerManFileInfo)); console.WriteLine( Manifest.MakeNativePathString(innerManifestFileInfo)); console.WriteLine(e.Message); console.WriteLine(); } }
public void MoveFile( ManifestFileInfo fileToBeMoved, ManifestFileInfo otherFileWithNewLocation) { // No need to actually move a file, just move it in the // outer manifest. fileToBeMoved.ParentDirectory.Files.Remove( fileToBeMoved.Name); ManifestFileInfo newFileInfo = Manifest.PutFileFromOtherManifest( otherFileWithNewLocation); myManifestChanged = true; }
public FileInfo CloneFile( ManifestFileInfo copyFile, DirectoryInfo copyToDirectory) { String originalFilePath = MakeNativePath(copyFile); // Name the file according to its unique hash code String copyFilePath = Path.Combine( copyToDirectory.FullName, copyFile.FileHash.ToString()); File.Copy(originalFilePath, copyFilePath); return(new FileInfo(copyFilePath)); }