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
}
}