示例#1
0
        private FSEntry GetEntry(string uri)
        {
            // Request URIs must never contain \ (only /)
            if (uri.Contains("\\"))
            {
                return(null);
            }

            // Make sure the URI starts with the service URI, and prodived it does, strip
            // off that part.
            if (!uri.StartsWith(ServiceURI))
            {
                return(null);
            }
            uri = uri.Substring(ServiceURI.Length);

            // Get the file or directory from the URI
            string[] parts = uri.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)
                {
                    return(null);
                }
            }

            // If 'dir' is non-null at this point then we return it
            if (null != dir)
            {
                return(dir);
            }

            // Coming here implies it's a file name
            return(parent.GetFile(parts[parts.Length - 1]));
        }
        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);
        }
示例#3
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);
        }