public virtual void HandleRequest(Stream stream)
        {
            StringBuilder response = new StringBuilder();

            /* authentication required? */
            if (IsAccessDenied())
            {
                StatusCode = GetStatusCode(401);
                HeaderLines.Clear();
                HeaderLines.Add("WWW-Authenticate: Basic realm=" + AuthorizationRealm);
                ResponseTextContent = "";
                ResponseBinaryContentLength = 0;

                if (ResponseBinaryContent != null)
                {
                    ResponseBinaryContent = null;
                }
            }

            response.AppendLine(StatusCode);
            response.AppendLine("Date: " + DateTime.Now.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture));
            response.AppendLine("Server: WebDAVServer/" + WebDAVServer.Version + " (g3gg0.de)");

            foreach (string line in HeaderLines)
            {
                response.AppendLine(line);
            }
            HeaderLines.Clear();

            response.AppendLine("Content-Length: " + (ResponseTextContent.Length + ResponseBinaryContentLength));

            if (KeepAlive)
            {
                response.AppendLine("Keep-Alive: timeout=" + Timeout + ", max=" + (Timeout + 10));
                response.AppendLine("Connection: Keep-Alive");
            }
            else
            {
                response.AppendLine("Connection: Close");
            }

            response.AppendLine("Content-Type: " + MimeType);
            response.AppendLine("");

            byte[] textHeaderData = Encoding.ASCII.GetBytes(response.ToString());
            stream.Write(textHeaderData, 0, textHeaderData.Length);
            BytesWrittenHeader += textHeaderData.Length;

            foreach (string line in response.ToString().Split('\n'))
            {
                Server.LogRequest("> " + line.Replace("\r", ""));
            }

            if (!SendHeaderOnly)
            {
                if (ResponseTextContent.Length > 0)
                {
                    WebDAVServer.TransferInfo info = new WebDAVServer.TransferInfo(Server, ResponseTextContent.Length);
                    int written = 0;

                    byte[] respTextData = Encoding.ASCII.GetBytes(ResponseTextContent);
                    try
                    {
                        stream.Write(respTextData, written, respTextData.Length);

                        written += respTextData.Length;
                        BytesWrittenHeader += respTextData.Length;
                        info.BlockTransferred(respTextData.Length);
                    }
                    catch (Exception e)
                    {
                    }

                    info.TransferFinished();

                    if (!SkipRequestLogging)
                    {
                        Server.LogRequest(ResponseTextContent.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;"));
                    }
                    SkipRequestLogging = false;

                    ResponseTextContent = "";
                }

                if (ResponseBinaryContentLength > 0)
                {
                    WebDAVServer.TransferInfo info = new WebDAVServer.TransferInfo(Server, ResponseBinaryContentLength);
                    long written = 0;

                    try
                    {
                        do
                        {
                            stream.Write(ResponseBinaryContent, 0, ResponseBinaryContent.Length);
                            written += ResponseBinaryContent.Length;
                            BytesWrittenData += ResponseBinaryContent.Length;
                            info.BlockTransferred(ResponseBinaryContent.Length);
                        } while (true);
                    }
                    catch (Exception e)
                    {
                    }

                    info.TransferFinished();

                    Server.LogRequest("> (binary content of size " + written + ")");

                    stream.Flush();
                }

                if (ResponseBinaryContent != null)
                {
                    ResponseBinaryContent = null;
                }
            }
        }
        public override void HandleRequest(Stream stream)
        {
            if (IsAccessDenied())
            {
                base.HandleRequest(stream);
                return;
            }

            VirtualFileType type = VirtualFileType.Resolve(RequestPath);

            /* writes to existing files get redirected into virtual dir */
            if (type.Type == FileType.PureVirtualFile)
            {
                type.Type = FileType.Redirected;
            }

            switch (type.Type)
            {
                case FileType.PureVirtualDir:
                    StatusCode = GetStatusCode(400);
                    break;

                case FileType.PureVirtualFile:
                    StatusCode = GetStatusCode(500);
                    break;

                case FileType.Redirected:
                case FileType.Direct:
                    {
                        bool existed = false;
                        bool success = false;

                        if (File.Exists(type.LocalPath))
                        {
                            existed = true;
                        }

                        string dir = new FileInfo(type.LocalPath).DirectoryName;
                        if(!Directory.Exists(dir))
                        {
                            Directory.CreateDirectory(dir);
                        }

                        /* allowed to write, so start reading from input stream and write to disk */
                        FileStream file = null;
                        WebDAVServer.TransferInfo info = new WebDAVServer.TransferInfo(Server, RequestContentLength);

                        try
                        {
                            int blockSize = 4096;
                            long remaining = RequestContentLength;
                            byte[] readBuffer = new byte[blockSize];

                            file = File.Open(type.LocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Write);

                            file.Lock(0, file.Length);

                            if (file != null)
                            {
                                while (remaining > 0)
                                {
                                    int length = (int)Math.Min(remaining, blockSize);

                                    length = PutDataStream.Read(readBuffer, 0, length);
                                    if (length > 0)
                                    {
                                        file.Write(readBuffer, 0, length);

                                        remaining -= length;
                                        BytesReadData += length;
                                        info.BlockTransferred(length);
                                    }
                                    else
                                    {
                                        Server.Log("[E] read <0 byte during PUT request");
                                        remaining = 0;
                                    }
                                }

                                file.Unlock(0, file.Length);
                                file.Close();
                                file = null;
                                success = true;
                            }
                        }
                        catch (Exception e)
                        {
                            Server.Log("[E] "+e.ToString()+" during PUT request");
                            success = false;
                        }

                        info.TransferFinished();

                        if (!success)
                        {
                            StatusCode = GetStatusCode(403);
                        }
                        else if (existed)
                        {
                            StatusCode = GetStatusCode(200);
                        }
                        else
                        {
                            StatusCode = GetStatusCode(201);
                        }

                        MimeType = "text/plain";
                    }
                    break;
            }

            base.HandleRequest(stream);
        }