WebDavSharp/WebDavSharp_MVC/WebDAVSharp.Server/Stores/DiskStore/WebDavDiskStoreDocument.cs

148 lines
4.9 KiB
C#

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 {
/// <summary>
/// This class implements a disk-based <see cref="WebDavDiskStoreDocument" /> mapped to a file.
/// </summary>
[DebuggerDisplay("File ({Name})")]
public sealed class WebDavDiskStoreDocument : WebDavDiskStoreItem, IWebDavStoreDocument {
/// <summary>
/// Initializes a new instance of the <see cref="WebDavDiskStoreDocument" /> class.
/// </summary>
/// <param name="parentCollection">The parent
/// <see cref="WebDavDiskStoreCollection" /> that contains this
/// <see cref="WebDavDiskStoreItem" />;
/// or
/// <c>null</c> if this is the root
/// <see cref="WebDavDiskStoreCollection" />.</param>
/// <param name="path">The path that this <see cref="WebDavDiskStoreItem" /> maps to.</param>
/// <exception cref="ArgumentNullException"><paramref name="path" /> is <c>null</c> or empty.</exception>
public WebDavDiskStoreDocument(WebDavDiskStoreCollection parentCollection, string path)
: base(parentCollection, path) {
// Do nothing here
}
#region IWebDAVStoreDocument Members
/// <summary>
/// Gets the size of the document in bytes.
/// </summary>
public long Size {
get { return new FileInfo(ItemPath).Length; }
}
/// <summary>
/// Gets the mime type of this <see cref="IWebDavStoreItem" />.
/// </summary>
public string MimeType {
get {
return MimeMapping.GetMimeMapping(Name);
}
}
/// <summary>
/// Gets the etag of this <see cref="IWebDavStoreItem" />.
/// </summary>
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
/// <summary>
/// Opens a <see cref="Stream" /> object for the document, in read-only mode.
/// </summary>
/// <returns>
/// The <see cref="Stream" /> object that can be read from.
/// </returns>
/// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access</exception>
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;
}
}
///// <summary>
///// Opens a <see cref="Stream" /> object for the document, in write-only mode.
///// </summary>
///// <param name="append">A value indicating whether to append to the existing document;
///// if
///// <c>false</c>, the existing content will be dropped.</param>
///// <returns>
///// The <see cref="Stream" /> object that can be written to.
///// </returns>
///// <exception cref="WebDAVSharp.Server.Exceptions.WebDavUnauthorizedException">If the user is unauthorized or has no access</exception>
//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
}
}