using System; using System.Diagnostics; using System.IO; using System.Security.Principal; using System.Web; using WebDAVSharp.Server.Exceptions; using WebDAVSharp.Server.Utilities; namespace WebDAVSharp.Server.Stores.DiskStore { /// /// This class implements a disk-based mapped to a file. /// [DebuggerDisplay("File ({Name})")] public sealed class WebDavDiskStoreDocument : WebDavDiskStoreItem, IWebDavStoreDocument { /// /// Initializes a new instance of the class. /// /// The parent /// that contains this /// ; /// or /// null if this is the root /// . /// The path that this maps to. /// is null or empty. public WebDavDiskStoreDocument(WebDavDiskStoreCollection parentCollection, string path) : base(parentCollection, path) { // Do nothing here } #region IWebDAVStoreDocument Members /// /// Gets the size of the document in bytes. /// public long Size { get { return new FileInfo(ItemPath).Length; } } /// /// Gets the mime type of this . /// public string MimeType { get { return MimeMapping.GetMimeMapping(Name); } } /// /// Gets the etag of this . /// public string Etag { get { // itempath is currently the absolute path, if we want to work with multiple servers and load balancing, // we need to change this to the relative path // For this moment, we can't get access to the root path for calculating the relative path, // because we don't have an instance of WebDAVDiskStore return Md5Util.Md5HashStringForUtf8String(ItemPath + ModificationDate + Hidden + Size); } } #endregion #region IWebDAVStoreDocument Members /// /// Opens a object for the document, in read-only mode. /// /// /// The object that can be read from. /// /// If the user is unauthorized or has no access public Stream OpenReadStream() { Stream stream = null; try { // Impersonate the current user and create the file stream for opening the file WindowsImpersonationContext wic = Identity.Impersonate(); stream = new FileStream(ItemPath, FileMode.Open, FileAccess.Read, FileShare.None); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } return stream; } public void WriteStream(Stream inputStream, bool append) { FileStream outputStream; if (append) { outputStream = new FileStream(ItemPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); outputStream.Seek(0, SeekOrigin.End); } try { // Impersonate the current user and create the file stream for writing the file WindowsImpersonationContext wic = Identity.Impersonate(); outputStream = new FileStream(ItemPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); wic.Undo(); } catch { throw new WebDavUnauthorizedException(); } long left = inputStream.Length; byte[] buffer = new byte[4096]; while (left > 0) { int toRead = Convert.ToInt32(Math.Min(left, buffer.Length)); int inBuffer = inputStream.Read(buffer, 0, toRead); outputStream.Write(buffer, 0, inBuffer); left -= inBuffer; } } ///// ///// Opens a object for the document, in write-only mode. ///// ///// A value indicating whether to append to the existing document; ///// if ///// false, the existing content will be dropped. ///// ///// The object that can be written to. ///// ///// If the user is unauthorized or has no access //public Stream OpenWriteStream(bool append) { // if (append) { // FileStream result = new FileStream(ItemPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); // result.Seek(0, SeekOrigin.End); // return result; // } // Stream stream = null; // try { // // Impersonate the current user and create the file stream for writing the file // WindowsImpersonationContext wic = Identity.Impersonate(); // stream = new FileStream(ItemPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); // wic.Undo(); // } // catch { // throw new WebDavUnauthorizedException(); // } // return stream; //} #endregion } }