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); }
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)); }