Пример #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]));
        }
Пример #2
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);
        }
Пример #3
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));
        }