/// <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;
                    }
                }
            }
        }
Esempio n. 3
0
        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();
        }
Esempio n. 4
0
        public static FSFile AddContent(this FSFile file, List <object> content)
        {
            FSFile cloned = file.DeepClone();

            cloned.Content = content;

            return(cloned);
        }
Esempio n. 5
0
        public static FSFile RemoveContent(this FSFile file)
        {
            FSFile cloned = file.DeepClone();

            cloned.Content = new List <object>();

            return(cloned);
        }
Esempio n. 6
0
    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);
    }
}
Esempio n. 7
0
    public static int GetChildIndex(FSFile dir)
    {
        FSDirectory cur   = dir.Parent;
        int         index = 1;

        while (cur.Parent != null)
        {
            index++;
            cur = cur.Parent;
        }
        return(index);
    }
Esempio n. 8
0
    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);
    }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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));
        }
Esempio n. 11
0
    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 + "\"");
        }
    }
Esempio n. 12
0
 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);
 }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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());
        }
Esempio n. 15
0
        /***************************************************/

        public static IFSContainer Rename(this FSFile file, string name)
        {
            file.Name = name;
            return(file);
        }
Esempio n. 16
0
        /***************************************************/
        /**** 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);
        }
Esempio n. 17
0
        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);
        }
Esempio n. 19
0
 public FsStorage()
 {
     Directory = new FSDirectory();
     File      = new FSFile();
 }
Esempio n. 20
0
        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));
        }
Esempio n. 21
0
        /// <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 &quot;" + req.Method + "&quot; 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);
        }
Esempio n. 22
0
        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));
        }