/// <summary> /// Treats this file as a zip file and extracts it to the specified target directory. This file and /// the target directory do NOT need to be in the same file system. /// If this file is not a valid zip archive, or any error occurs, then false is returned. /// </summary> public static bool ExtractZip(this FSFile zipFile, FSDir targetDir, ZipExtractionOptions options) { // First open the FSFile for reading Stream fsFileStream = zipFile.OpenReadOnly(); // Create a zip archive (for reading) from the stream ZipArchive zipA = null; try { zipA = new ZipArchive(fsFileStream, ZipArchiveMode.Read); } catch (Exception) { fsFileStream.Dispose(); return(false); } // Call the utility function to do the actual extraction ExtractZip(zipA, targetDir, options); // Clean up and return zipA.Dispose(); fsFileStream.Dispose(); return(true); }
/// <summary> /// Copies the entity interfaces assembly and it's associated satellite assemblies. /// </summary> private void CopyEntityInterfacesAssembly() { var service = (Platforms)ExtensionManager.Default.GetService(typeof(Platforms)); RegisteredPlatform commonPlatform; if (service.TryGetPlatform(PlatformGuids.CommonGuid, out commonPlatform)) { try { string srcPath = Project.CommonPaths["DEPLOYMENTPATH"] + commonPlatform.Platform.RootDeploymentPath + "\\bin\\" + "Sage.Entity.Interfaces.dll"; string dstPath = Path.Combine(LibraryPath, "Sage.Entity.Interfaces.dll"); FSFile.Copy(Project.Drive.GetFileInfo(srcPath), FileSystem.GetFileInfo(dstPath), true); } catch (Exception ex) { // couldn't copy from VFS so try local output folder if ((ex.InnerException is InvalidOperationException && ex.Source == "Sage.Platform.VirtualFileSystem") || ex is DirectoryNotFoundException) { string path = Sage.Platform.Extensibility.BuildSettings.CurrentBuildSettings.SolutionFolder; path = Path.Combine(path, "interfaces\\bin\\sage.entity.interfaces.dll"); if (File.Exists(path)) { File.Copy(path, Path.Combine(LibraryPath, "Sage.Entity.Interfaces.dll"), true); } } else { throw; } } } }
private void WriteFileResponse(WebRequest req, FSFile file) { Stream fileStream = file.OpenReadOnly(); if (null == fileStream) { m_logger.WriteLine(string.Format( "{0}:ERROR:Failed to open file \"" + file.Name + "\"", DateTime.Now)); // Send a 500. We should only enter this method when the file DOES // exist, so we shouldn't treat this as a 404. req.WriteInternalServerErrorResponse(); return; } // Log info before sending var range = req.GetRangeHeader(file.Size - 1); string msg = " Sending file contents for " + file.Name; if (range != null) { msg += string.Format(" ({0}-{1})", range.Item1, range.Item2); } m_logger.WriteLine(msg); // Send the file data as a response. This function will handle the Range header, if present. req.WriteFileResponse(file.Name, fileStream, false); // Clean up fileStream.Dispose(); }
public static FSFile AddContent(this FSFile file, List <object> content) { FSFile cloned = file.DeepClone(); cloned.Content = content; return(cloned); }
public static FSFile RemoveContent(this FSFile file) { FSFile cloned = file.DeepClone(); cloned.Content = new List <object>(); return(cloned); }
public FSFile FindFile(string fileName) { string[] directoryPath = fileName.Split('/'); var fs = TerminalNetwork.GetCurrentDevice().GetComponent <FileSystem>(); FSDirectory current = fs.CurrentDirectory; if (directoryPath.Length == 0) { directoryPath = new string[] { fileName } } ; bool found = false; for (int i = 0; i < directoryPath.Length; i++) { if (i == directoryPath.Length - 1) { if (current.Files != null && current.Files.Count > 0) { FSFile file = current.Files.Single(a => a.Name.ToUpper() == directoryPath[i].ToUpper()); return(file); } } else { bool f = false; directoryPath[i] = directoryPath[i].Replace("/", ""); foreach (FSDirectory dir in current.Directories) { if (dir.Name.ToUpper() == directoryPath[i].ToUpper()) { current = dir; if (i == directoryPath.Length) { found = true; } f = true; break; } } if (!f) { break; } } } return(null); } }
public static int GetChildIndex(FSFile dir) { FSDirectory cur = dir.Parent; int index = 1; while (cur.Parent != null) { index++; cur = cur.Parent; } return(index); }
public static string GetFilePath(FSFile fS) { FSDirectory dir = fS.Parent; string text = fS.Name; while (dir != null) { text = dir.Name + "/" + text; dir = dir.Parent; } return(text); }
public static byte[] ContentsAsByteArray(this FSFile bhomFile) { byte[] contents = null; try { using (var stream = System.IO.File.OpenRead(bhomFile.IFullPath())) { byte[] buff = new byte[stream.Length]; int read = stream.Read(buff, 0, (int)stream.Length); contents = buff; } } catch { Engine.Base.Compute.RecordError("Unable to read file: " + bhomFile.IFullPath()); } return(contents); }
public static string ContentsAsString(this FSFile file, Encodings encoding = Encodings.FromFile) { byte[] contents = file.ContentsAsByteArray(); System.Text.Encoding sysEncoding = null; if (encoding == Encodings.FromFile) { sysEncoding = file.Encoding(); if (sysEncoding == null) { Base.Compute.RecordNote($"Could not determine encoding for file {file.Name}, assuming UTF-8."); sysEncoding = System.Text.Encoding.UTF8; } } else { sysEncoding = FromEnum(encoding); } return(sysEncoding.GetString(contents)); }
public void PrintCommand(string[] args) { string reason; if (!TerminalNetwork.GetCurrentDevice().networkNode.HasAccess(out reason)) { TerminalCore.AddMessage(TerminalColourScheme.FormatText(reason, TerminalStyle.DANGER)); return; } var fs = TerminalNetwork.GetCurrentDevice().GetComponent <FileSystem>(); if (fs != null && !fs.HasPermission()) { NotifyBlocked(); return; } string fileName = ""; for (int i = 0; i < args.Length; i++) { fileName += args[i]; if (i != args.Length - 1) { fileName += " "; } } FSFile file = FindFile(fileName); if (file != null) { string fileType = file.fileType.ToString(); TerminalCore.AddMessage("File:" + "\t" + file.Name + ": \n\tType: " + fileType + "\n\t\"" + file.Data + "\""); } }
public static Encoding Encoding(this FSFile file) { byte[] contents = file.ContentsAsByteArray(); if (contents == null) { return(null); } foreach (EncodingInfo candidate in System.Text.Encoding.GetEncodings()) { byte[] pre = candidate.GetEncoding().GetPreamble(); int len = pre.Length; if (len == 0) { continue; } byte[] check = new byte[len]; Array.ConstrainedCopy(contents, 0, check, 0, len); if (pre.SequenceEqual(check)) { return(candidate.GetEncoding()); } } return(null); }
public string GetHREF(FSFile file, bool urlEncoded) { // The service URL is not required to end with '/' but we must have this // after it when generating an HREF for the page. string start = ServiceURI; if (!start.EndsWith("/")) { start += "/"; } string href = file.Name; FSDir dir = file.Parent; while (!object.ReferenceEquals(dir, m_root)) { href = dir.Name + "/" + href; dir = dir.Parent; // We should always hit the root before null, provided the file is in fact // somewhere within the hosted directory. Should we get null then the file // is outside of the shared content and it's an invalid call. if (null == dir) { throw new InvalidOperationException( "GetHREF was called for a file that's not in the shared content directories"); } } href = start + href; if (urlEncoded) { return(Uri.EscapeUriString(href)); } return(href); }
public override List <object> Push(IEnumerable <object> objects, string tag = "", PushType pushType = PushType.AdapterDefault, ActionConfig actionConfig = null) { PushConfig pushConfig = actionConfig as PushConfig == null ? new PushConfig() : actionConfig as PushConfig; if (string.IsNullOrWhiteSpace(m_defaultFilePath)) // = if we are about to push multiple files/directories { if (pushType == PushType.DeleteThenCreate && m_Push_enableDeleteWarning && !pushConfig.DisableWarnings) { BH.Engine.Base.Compute.RecordWarning($"You have selected the {nameof(PushType)} {nameof(PushType.DeleteThenCreate)}." + $"\nThis has the potential of deleting files and folders with their contents." + $"\nMake sure that you know what you are doing. This warning will not be repeated." + $"\nRe-enable the component to continue."); m_Push_enableDeleteWarning = false; return(new List <object>()); } } List <IResource> createdFiles = new List <IResource>(); List <IResource> filesOrDirs = objects.OfType <IResource>().Select(fd => fd.ShallowClone()).ToList(); List <object> remainder = objects.Where(o => !(o is IResource)).ToList(); if (remainder.Any()) { if (filesOrDirs.Any()) { BH.Engine.Base.Compute.RecordError($"Input objects are both of type `{nameof(BH.oM.Adapters.File.File)}`/`{nameof(BH.oM.Adapters.File.Directory)}` and generic objects." + $"\nIn order to push them:" + $"\n\t- for the `{nameof(BH.oM.Adapters.File.File)}`/`{nameof(BH.oM.Adapters.File.Directory)}` objects, use a Push using a {nameof(FileAdapter)} with no targetLocation input;" + $"\n\t- for the generic objects, use a Push using a {nameof(FileAdapter)} that specifies a targetLocation."); return(null); } else if (string.IsNullOrWhiteSpace(m_defaultFilePath)) { BH.Engine.Base.Compute.RecordError($"To Push objects that are not of type `{nameof(BH.oM.Adapters.File.File)}` or `{nameof(BH.oM.Adapters.File.Directory)}`," + $"\nyou need to specify a target Location by creating the {nameof(FileAdapter)} through the constructor with inputs."); return(null); } } if (m_defaultFilePath != null) { if (filesOrDirs.Any()) { BH.Engine.Base.Compute.RecordWarning($"A `targetLocation` has been specified in the File_Adapter constructor." + $"\nObjects of type `{nameof(BH.oM.Adapters.File.File)}` or `{nameof(BH.oM.Adapters.File.Directory)}` will be appended to the file at `targetLocation`." + $"\nIf you want to target multiple files, you need create the {nameof(FileAdapter)} through the constructor without inputs."); } } foreach (IResource fileOrDir in filesOrDirs) { if (fileOrDir == null) { continue; } if (fileOrDir is IFile) { string extension = Path.GetExtension(fileOrDir.IFullPath()); if (string.IsNullOrWhiteSpace(extension)) { BH.Engine.Base.Compute.RecordNote($"File {fileOrDir.IFullPath()} has no extension specified. Defaults to JSON."); extension = ".json"; fileOrDir.Name += extension; } if (extension != ".json") { BH.Engine.Base.Compute.RecordWarning($"Cannot create File {fileOrDir.IFullPath()}. Currently only JSON extension is supported."); continue; } } IResource created = Create(fileOrDir as dynamic, pushType, pushConfig); createdFiles.Add(created); } if (remainder.Any()) { string defaultDirectory = Path.GetDirectoryName(m_defaultFilePath); string defaultFileName = Path.GetFileName(m_defaultFilePath); FSFile file = CreateFSFile(defaultDirectory, defaultFileName, remainder); if (remainder.All(o => o is Dataset)) { // Automatically set UseDatasetSerialization to true. pushConfig.UseDatasetSerialization = true; pushConfig.BeautifyJson = false; } IResource created = Create(file, pushType, pushConfig); if (created != null) { createdFiles.Add(created); } } return(createdFiles.OfType <object>().ToList()); }
/***************************************************/ public static IFSContainer Rename(this FSFile file, string name) { file.Name = name; return(file); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public FSFile CreateJson(FSFile file, PushType pushType, PushConfig pushConfig) { string fullPath = file.IFullPath(); bool fileExisted = System.IO.File.Exists(fullPath); // Put together all of the file content. List <string> allLines = new List <string>(); string json = ""; // Process file content, only if there is any. if (file.Content != null && file.Content.Count != 0) { if (file.Content.All(o => o is Dataset)) { pushConfig.UseDatasetSerialization = true; } if (!pushConfig.UseDatasetSerialization) { allLines.AddRange(file.Content.Where(c => c != null).Select(obj => obj.ToJson() + ",")); // Remove the trailing comma if there is only one element. allLines[allLines.Count - 1] = allLines[allLines.Count - 1].Remove(allLines[allLines.Count - 1].Length - 1); // Join all between square brackets to make a valid JSON array. json = String.Join(Environment.NewLine, allLines); json = "[" + json + "]"; } else { // Use the non-JSON compliant "Dataset" serialization style. // This is a newline-separated concatenation of individual JSON-serialized objects. allLines.AddRange(file.Content.Where(c => c != null).Select(obj => obj.ToJson())); json = String.Join(Environment.NewLine, allLines); } if (pushConfig.BeautifyJson) { try { json = BeautifyJson(json); } catch (Exception e) { BH.Engine.Base.Compute.RecordWarning($"Beautify json failed. File will be created with non-beautified json. Error:\n{e.Message}"); } } } bool filecreated = true; try { // Clarify if we are considering the Push in terms of content or of Files. if (string.IsNullOrWhiteSpace(m_defaultFilePath)) // We are talking about Files/Directories. { if (pushType == PushType.DeleteThenCreate) { if (fileExisted) { System.IO.File.Delete(fullPath); } WriteJsonFile(fullPath, json, true); } else if (pushType == PushType.UpdateOnly) { // Overwrite existing file. if (fileExisted) { WriteJsonFile(fullPath, json, true); } else { BH.Engine.Base.Compute.RecordNote($"File {fullPath} was not updated as no file existed at that location."); } } else if (pushType == PushType.UpdateOrCreateOnly) { // Overwrite existing file. If it doesn't exist, create it. WriteJsonFile(fullPath, json, true); } else if (pushType == PushType.CreateOnly || pushType == PushType.CreateNonExisting) { // Create only if file didn't exist. Do not touch existing ones. if (!fileExisted) { WriteJsonFile(fullPath, json, true); } else { BH.Engine.Base.Compute.RecordNote($"File {fullPath} was not created as it existed already (Pushtype {pushType.ToString()} was specified)."); } } else { BH.Engine.Base.Compute.RecordWarning($"The specified Pushtype of {pushType.ToString()} is not supported for .json files."); filecreated = false; } } else // We are talking about File content. { if (pushType == PushType.DeleteThenCreate) { BH.Engine.Base.Compute.RecordNote($"Replacing entire content of file `{fullPath}`."); // Replace all content. WriteJsonFile(fullPath, json, true); } else if (pushType == PushType.CreateOnly || pushType == PushType.CreateNonExisting || pushType == PushType.UpdateOnly || pushType == PushType.UpdateOrCreateOnly) { // Should be refactored to cover distinct use cases for CreateNonExisting, UpdateOnly, UpdateOrCreateOnly if (fileExisted) { BH.Engine.Base.Compute.RecordNote($"Appending content to file `{fullPath}`."); } WriteJsonFile(fullPath, json, false); } else if (pushType == PushType.CreateNonExisting) { // Currently captured by CreateOnly. // The following ideally should be the default behaviour of the IDiffing method. //IEnumerable<object> allReadContent = ReadContent(fullPath); //IEnumerable<IBHoMObject> bHoMObjects_read = allReadContent.OfType<IBHoMObject>(); //IEnumerable<object> genericObjs_read = allReadContent.Except(bHoMObjects_read); //IEnumerable<IBHoMObject> readBhomObjects_hashAssigned = BH.Engine.Diffing.Modify.SetHashFragment(bHoMObjects_read); //IEnumerable<IBHoMObject> bHoMObjects_create = file.Content.OfType<IBHoMObject>(); //IEnumerable<object> genericObjs_create = file.Content.Except(bHoMObjects_create); //Diff diffGeneric = BH.Engine.Diffing.Compute.DiffGenericObjects(genericObjs_read, genericObjs_create, null, true); // Then combine the two diffs in one. // For old objects (= already in file) do not create. // Create only those that are "new". } else if (pushType == PushType.UpdateOnly || pushType == PushType.UpdateOrCreateOnly) { // Currently captured by CreateOnly. See above. // For old objects (= already in file) Update Them. // For those who are "new": create them only if `UpdateOrCreateOnly` is used. } else { BH.Engine.Base.Compute.RecordWarning($"The specified Pushtype of {pushType.ToString()} is not supported for .json files."); filecreated = false; } } } catch (Exception e) { BH.Engine.Base.Compute.RecordError(e.Message); } if (filecreated) { System.IO.FileInfo fileinfo = new System.IO.FileInfo(fullPath); oM.Adapters.File.FSFile createdFile = fileinfo.ToFiling(); createdFile.Content = file.Content; return(createdFile); } BH.Engine.Base.Compute.RecordError($"Could not create {file.ToString()}"); return(null); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Env arguments to use:"); Console.WriteLine(" WZ_KEY - key for wz file, like '315' for maple version 315"); Console.WriteLine(" WZ_MAP_NAME - name of the json file (without extension) that contains the tree of the wz contents."); Console.WriteLine(" MSEXE - path to MapleStory.exe. Will use MapleStory.exe from WZ directory if not set. Used for detecting version (and set WZ_MAP_NAME)"); Console.WriteLine(" EXTRACT_IMGS=1 - also extract raw img files from wz"); Console.WriteLine(" PRETTYPRINT_JSON=1 - pretty print json files (makes them huge)"); Console.WriteLine(" EXPORT_BSON=1 - Use BSON instead of JSON for img files (images will be binary instead of base64)"); Console.WriteLine(" OUTPUT_DIR - Write files to specified output dir, instead of the directory of the wz file"); Console.WriteLine("Files to pass:"******" *.img files"); Console.WriteLine(" *.wz files"); Console.WriteLine(); } else { exportBson = Environment.GetEnvironmentVariable("EXPORT_BSON") == "1"; if (exportBson) { Console.WriteLine("[OPT] Exporting as BSON"); } var hadWzMapNameSet = Environment.GetEnvironmentVariable("WZ_MAP_NAME") != null; var useFileLocationAsOutputDir = Environment.GetEnvironmentVariable("OUTPUT_DIR") == null; if (!useFileLocationAsOutputDir) { globalOutputDirectory = new DirectoryInfo(Environment.GetEnvironmentVariable("OUTPUT_DIR")); } if (globalOutputDirectory != null && !globalOutputDirectory.Exists) { globalOutputDirectory.Create(); } foreach (var s in args) { Console.WriteLine("Handling {0}", s); var fileInfo = new FileInfo(s); if (useFileLocationAsOutputDir) { globalOutputDirectory = fileInfo.Directory; } if (s.EndsWith(".img")) { var fsf = new FSFile { RealPath = fileInfo.FullName, Name = fileInfo.Name, }; ExtractFile(fsf, fileInfo.Directory); } else if (s.EndsWith(".wz")) { var msExe = Environment.GetEnvironmentVariable("MSEXE") ?? Path.Combine(fileInfo.DirectoryName, "MapleStory.exe"); if (File.Exists(msExe)) { var fvi = FileVersionInfo.GetVersionInfo(msExe); // Version is stored as locale.version.subversion.test var version = fvi.FileMinorPart; var subversion = fvi.FileBuildPart; var locale = fvi.FileMajorPart; Console.WriteLine( "File for version {0}.{1} locale {2}", version, subversion, locale ); if (!hadWzMapNameSet) { var mapName = $"v{version}-{subversion}-{locale}"; Environment.SetEnvironmentVariable("WZ_MAP_NAME", mapName); } } else if (!hadWzMapNameSet) { // Clear map name for files that did not match Environment.SetEnvironmentVariable("WZ_MAP_NAME", null); } ExtractWZ(fileInfo, Environment.GetEnvironmentVariable("WZ_KEY") ?? ""); } else { Console.WriteLine("Unable to handle file"); } } } Console.WriteLine("Press any key to exit..."); Console.ReadLine(); }
private static ZipExtractionStats ExtractZip(ZipArchive zipA, FSDir targetDirectory, ZipExtractionOptions options) { // Keep track of the number of entries encountered and extracted ZipExtractionStats stats = new ZipExtractionStats(); // Loop through entries and extract foreach (ZipArchiveEntry entry in zipA.Entries) { stats.NumEntriesSeen++; bool skipThisEntry = false; FSDir targetDir = targetDirectory; // Split the full name on '/' string[] pieces = entry.FullName.Split('/'); int i; for (i = 0; i < pieces.Length - 1; i++) { targetDir = targetDir.CreateDir(pieces[i]); if (null == targetDir) { skipThisEntry = true; break; } } // Skip this entry if need be if (skipThisEntry) { continue; } // At this point pieces[i] is the file we need to create in targetDir if (targetDir.GetFile(pieces[i]) != null && !options.Overwrite) { // We can't overwrite the file continue; } FSFile fileForEntry = targetDir.CreateFile(pieces[i]); if (null == fileForEntry) { continue; } // Open the zip entry stream for reading and the FSFile for writing. Notice that despite // the possibility of failure to open the source stream from the zip file entry, we've // already created the FSFile in the target directory. This is intentional. If we fail // to extract a file, then a 0-byte placeholder is desired (for now, may change later). Stream src = entry.Open(); if (src == null) { continue; } Stream dst = fileForEntry.OpenReadWrite(); if (dst == null) { src.Dispose(); continue; } // Copy the contents byte[] buf = new byte[8192]; while (true) { int bytesRead = src.Read(buf, 0, buf.Length); if (bytesRead <= 0) { break; } dst.Write(buf, 0, bytesRead); } // Clean up and increment number of files extracted src.Dispose(); dst.Dispose(); stats.NumEntriesExtracted++; } return(stats); }
public FsStorage() { Directory = new FSDirectory(); File = new FSFile(); }
public void TestBasicTraversal() { var root = new FSDirectory() { Name = "", }; var dir1 = new FSDirectory() { Name = "dir1" }; var dir2 = new FSDirectory() { Name = "dir2" }; root.AddDirectories(dir1, dir2); Assert.AreEqual(root, dir1.Parent); Assert.IsTrue(root.HasChild("dir1")); Assert.IsTrue(root.HasChild("dir2")); var file1 = new FSFile() { Name = "crappyfile.img" }; var file1Object = new WzFileProperty { FileNode = file1, Name = file1.Name, }; file1.Object = file1Object; dir1.AddFiles(file1); file1Object.Set("prop1", "whatever"); file1Object.Set("prop2", 1337); file1Object.Set("uol_1", new WzUOL() { Path = "./prop1", }); Assert.AreEqual(dir1, file1.GetParent()); Assert.AreEqual(file1Object, dir1.GetChild("crappyfile")); Assert.AreEqual(file1Object, dir1.GetChild("crappyfile.img")); { var x = file1Object.Get("uol_1"); Assert.IsNotNull(x); var xnsn = (INameSpaceNode)x; Assert.IsNotNull(xnsn); var xnsn1 = (INameSpaceNode)xnsn.GetParent(); Assert.AreEqual(file1Object, xnsn1); var xnsn2 = (INameSpaceNode)xnsn1.GetParent(); Assert.AreEqual(dir1, xnsn2); var xnsn3 = (INameSpaceNode)xnsn2.GetParent(); Assert.AreEqual(root, xnsn3); } file1Object.Set("uol", new WzUOL { Path = "uol_1" }); Assert.AreEqual(file1Object.Get("uol_1"), ((WzUOL)file1Object.Get("uol")).ActualObject(false)); file1Object.Set("uol", new WzUOL { Path = "uol_1" }); Assert.AreEqual(file1Object.Get("prop1"), ((WzUOL)file1Object.Get("uol")).ActualObject(true)); file1Object.Set("uol", new WzUOL { Path = "./prop2" }); Assert.AreEqual(1337, ((WzUOL)file1Object.Get("uol")).ActualObject()); file1Object.Set("uol", new WzUOL { Path = "prop2" }); Assert.AreEqual(1337, ((WzUOL)file1Object.Get("uol")).ActualObject()); file1Object.Set("uol", new WzUOL { Path = "../crappyfile/prop2" }); Assert.AreEqual(1337, ((WzUOL)file1Object.Get("uol")).ActualObject()); file1Object.Set("uol", new WzUOL { Path = "../crappyfile/prop2" }); Assert.AreEqual(1337, ((WzUOL)file1Object.Get("uol")).ActualObject()); file1Object.Set("uol", new WzUOL { Path = "../crappyfile.img/prop2" }); Assert.AreEqual(1337, ((WzUOL)file1Object.Get("uol")).ActualObject()); file1Object.Set("uol", new WzUOL { Path = "../../dir1/crappyfile/prop2" }); Assert.AreEqual(1337, ((WzUOL)file1Object.Get("uol")).ActualObject()); file1Object.Set("uol", new WzUOL { Path = "../../dir1/crappyfile/uol_1" }); Assert.AreEqual(file1Object.Get("uol_1"), ((WzUOL)file1Object.Get("uol")).ActualObject(false)); file1Object.Set("uol", new WzUOL { Path = "../../dir1/crappyfile/uol_1" }); Assert.AreEqual("whatever", ((WzUOL)file1Object.Get("uol")).ActualObject(true)); }
/// <summary> /// Request handler function /// </summary> public override void Handler(WebRequest req) { if (m_disposed) { throw new ObjectDisposedException("FileWebServer"); } if ("POST" == req.Method) { HandlePost(req); return; } // Handle uploads if ("PUT" == req.Method) { HandlePut(req); return; } // If it's anything other than GET at this point then it's not implemented if (req.Method != "GET") { m_logger.WriteLine( " Method was \"" + req.Method + "\" -> sending not implemented response"); req.WriteNotImplementedResponse( "<html><h1>HTTP method "" + req.Method + "" is not implemented</h1></html>"); return; } // First get rid of formatting on requested file string toGet = req.URIDecoded; // Requested file/content name must never contain \ (only /) if (toGet.Contains("\\")) { m_logger.WriteLine( " URI contains \"\\\" -> sending 400 response"); req.WriteBadRequestResponse(); return; } m_logger.WriteLine("Got request for \"" + toGet + "\""); // Make sure the URL starts with the service URL, and prodived it does, strip // off that part. if (!toGet.StartsWith(ServiceURI)) { req.WriteNotFoundResponse(); return; } toGet = toGet.Substring(ServiceURI.Length); // Get the file or directory that we need to serve string[] parts = toGet.Split( new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); FSDir dir = m_root, parent = null; for (int i = 0; i < parts.Length; i++) { parent = dir; dir = dir.GetDir(parts[i]); // Should we get a null directory we have 2 cases: // 1. This is NOT the last loop iteration, implying that we've hit a not found. // 2. This IS the last loop iteration, meaning that the last part of the file // string may be a file name and/or may be a not found. We fall through to // the code after this loop in that case. if (null == dir && i != parts.Length - 1) { if (null != m_onFileNotFound) { // Invoke custom handler m_onFileNotFound(this, toGet, req); } else { req.WriteNotFoundResponse(); } return; } } // If 'dir' is non-null at this point then it's a request for a listing of files in // that directory. if (null != dir) { m_logger.WriteLine(" Sending directory listing as response"); // Build response and send it string response = m_onNeedDirList(dir); req.WriteHTMLResponse(response); // That's all we need for a directory listing return; } // Coming here implies a file name FSFile file = parent.GetFile(parts[parts.Length - 1]); // If it doesn't exist then we respond with a file-not-found response if (null == file) { if (null != m_onFileNotFound) // custom handler { m_logger.WriteLine(" File not found -> invoking external handler"); m_onFileNotFound(this, parts[parts.Length - 1], req); } else { m_logger.WriteLine(" File not found -> sending 404 response"); // If we don't have a handler for file-not-found then we use the generic 404 req.WriteNotFoundResponse(); } return; } // File DOES exist, so we write the file data as the response m_logger.WriteLine(" Sending file contents as response"); WriteFileResponse(req, file); }
private void HandlePut(WebRequest req) { if (!m_allowUploads) { req.WriteBadRequestResponse(); return; } // For now, don't allow overwriting if (GetEntry(req.URIDecoded) != null) { req.WriteBadRequestResponse(); //req.WriteHTMLResponse("<html>Cannot overwrite files</html>"); return; } // Make sure it starts with the service URI then remove that part string toPut = req.URIDecoded; if (!toPut.StartsWith(ServiceURI)) { req.WriteBadRequestResponse(); return; } toPut = toPut.Substring(ServiceURI.Length); // Parse the path and get the directories string[] pieces = toPut.Split('/'); FSDir dir = m_root; for (int i = 0; i < pieces.Length - 1; i++) { dir = dir.GetDir(pieces[i]); if (dir == null) { req.WriteBadRequestResponse(); return; } } // By the time we get here we expected the last piece of the URI to be the file name FSFile theUploadedFile = dir.CreateFile(pieces[pieces.Length - 1]); if (null == theUploadedFile) { // If we can't create the file at this point, we'll call it a bad request (because // it's most likely because of a bad file name) req.WriteBadRequestResponse(); return; } // Stream in the body of request from the socket and out to the file Stream outS = theUploadedFile.OpenReadWrite(); if (outS == null) { req.WriteInternalServerErrorResponse(); return; } byte[] buf = new byte[8192]; while (true) { int bytesRead = req.Body.Read(buf, 0, buf.Length); if (bytesRead <= 0) { break; } outS.Write(buf, 0, bytesRead); } long fileLength = outS.Length; outS.Dispose(); req.WriteHTMLResponse(string.Format("<html>OK: Uploaded {0} bytes</html>", fileLength)); }