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);
        }
Example #2
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));
        }