using System;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using WebsitePanel.WebDav.Core.Config;
using WebsitePanel.WebDav.Core.Exceptions;
namespace WebsitePanel.WebDav.Core
{
namespace Client
{
public interface IFolder : IHierarchyItem
{
IResource CreateResource(string name);
IFolder CreateFolder(string name);
IHierarchyItem[] GetChildren();
IResource GetResource(string name);
Uri Path { get; }
}
public class WebDavFolder : WebDavHierarchyItem, IFolder
{
private IHierarchyItem[] _children = new IHierarchyItem[0];
private Uri _path;
public Uri Path { get { return _path; } }
///
/// The constructor
///
public WebDavFolder()
{
}
///
/// The constructor
///
/// Path to the folder.
public WebDavFolder(string path)
{
_path = new Uri(path);
}
///
/// The constructor
///
/// Path to the folder.
public WebDavFolder(Uri path)
{
_path = path;
}
///
/// Creates a resource with a specified name.
///
/// Name of the new resource.
/// Newly created resource.
public IResource CreateResource(string name)
{
var resource = new WebDavResource();
try
{
resource.SetHref(new Uri(Href.AbsoluteUri + name));
var credentials = (NetworkCredential) _credentials;
string auth = "Basic " +
Convert.ToBase64String(
Encoding.Default.GetBytes(credentials.UserName + ":" + credentials.Password));
var request = (HttpWebRequest) WebRequest.Create(resource.Href);
request.Method = "PUT";
request.Credentials = credentials;
request.ContentType = "text/xml";
request.Accept = "text/xml";
request.Headers["translate"] = "f";
request.Headers.Add("Authorization", auth);
using (var response = (HttpWebResponse) request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.Created ||
response.StatusCode == HttpStatusCode.NoContent)
{
Open(Href);
resource = (WebDavResource) GetResource(name);
resource.SetCredentials(_credentials);
}
}
}
catch (Exception e)
{
}
return resource;
}
///
/// Creates new folder with specified name as child of this one.
///
/// Name of the new folder.
/// IFolder
public IFolder CreateFolder(string name)
{
var folder = new WebDavFolder();
try
{
var credentials = (NetworkCredential) _credentials;
var request = (HttpWebRequest) WebRequest.Create(Href.AbsoluteUri + name);
request.Method = "MKCOL";
request.Credentials = credentials;
string auth = "Basic " +
Convert.ToBase64String(
Encoding.Default.GetBytes(credentials.UserName + ":" + credentials.Password));
request.Headers.Add("Authorization", auth);
using (var response = (HttpWebResponse) request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.Created ||
response.StatusCode == HttpStatusCode.NoContent)
{
folder.SetCredentials(_credentials);
folder.Open(Href.AbsoluteUri + name + "/");
}
}
}
catch (Exception e)
{
}
return folder;
}
///
/// Returns children of this folder.
///
/// Array that include child folders and resources.
public IHierarchyItem[] GetChildren()
{
return _children;
}
///
/// Gets the specified resource from server.
///
/// Name of the resource.
/// Resource corresponding to requested name.
public IResource GetResource(string name)
{
IHierarchyItem item =
_children.Single(i => i.DisplayName.Trim('/') == name.Trim('/'));
var resource = new WebDavResource();
resource.SetCredentials(_credentials);
resource.SetHierarchyItem(item);
return resource;
}
///
/// Opens the folder.
///
public void Open()
{
var request = (HttpWebRequest)WebRequest.Create(_path);
request.PreAuthenticate = true;
request.Method = "PROPFIND";
request.ContentType = "application/xml";
request.Headers["Depth"] = "1";
//TODO Disable SSL
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
var credentials = (NetworkCredential)_credentials;
if (credentials != null && credentials.UserName != null)
{
//request.Credentials = credentials;
string auth = "Basic " +
Convert.ToBase64String(
Encoding.Default.GetBytes(credentials.UserName + ":" + credentials.Password));
request.Headers.Add("Authorization", auth);
}
try
{
using (var response = (HttpWebResponse) request.GetResponse())
{
using (var responseStream = new StreamReader(response.GetResponseStream()))
{
string responseString = responseStream.ReadToEnd();
ProcessResponse(responseString);
}
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
throw new UnauthorizedException();
}
throw e;
}
}
///
/// Opens the folder
///
/// Path of the folder to open.
public void Open(string path)
{
_path = new Uri(path);
Open();
}
///
/// Opens the folder
///
/// Path of the folder to open.
public void Open(Uri path)
{
_path = path;
Open();
}
///
/// Processes the response from the server.
///
/// The raw response from the server.
private void ProcessResponse(string response)
{
try
{
var XmlDoc = new XmlDocument();
XmlDoc.LoadXml(response);
XmlNodeList XmlResponseList = XmlDoc.GetElementsByTagName("D:response");
if (XmlResponseList.Count == 0)
{
XmlResponseList = XmlDoc.GetElementsByTagName("d:response");
}
var children = new WebDavHierarchyItem[XmlResponseList.Count];
int counter = 0;
foreach (XmlNode XmlCurrentResponse in XmlResponseList)
{
var item = new WebDavHierarchyItem();
item.SetCredentials(_credentials);
foreach (XmlNode XmlCurrentNode in XmlCurrentResponse.ChildNodes)
{
switch (XmlCurrentNode.LocalName)
{
case "href":
string href = XmlCurrentNode.InnerText;
if (!Regex.Match(href, "^https?:\\/\\/").Success)
{
href = _path.Scheme + "://" + _path.Host + href;
}
item.SetHref(href, _path);
break;
case "propstat":
foreach (XmlNode XmlCurrentPropStatNode in XmlCurrentNode)
{
switch (XmlCurrentPropStatNode.LocalName)
{
case "prop":
foreach (XmlNode XmlCurrentPropNode in XmlCurrentPropStatNode)
{
switch (XmlCurrentPropNode.LocalName)
{
case "creationdate":
item.SetCreationDate(XmlCurrentPropNode.InnerText);
break;
case "getcontentlanguage":
item.SetProperty(
new Property(
new PropertyName("getcontentlanguage",
XmlCurrentPropNode.NamespaceURI),
XmlCurrentPropNode.InnerText));
break;
case "getcontentlength":
item.SetProperty(
new Property(
new PropertyName("getcontentlength",
XmlCurrentPropNode.NamespaceURI),
XmlCurrentPropNode.InnerText));
break;
case "getcontenttype":
item.SetProperty(
new Property(
new PropertyName("getcontenttype",
XmlCurrentPropNode.NamespaceURI),
XmlCurrentPropNode.InnerText));
break;
case "getlastmodified":
item.SetLastModified(XmlCurrentPropNode.InnerText);
break;
case "resourcetype":
item.SetProperty(
new Property(
new PropertyName("resourcetype",
XmlCurrentPropNode.NamespaceURI),
XmlCurrentPropNode.InnerXml));
break;
}
}
break;
case "status":
break;
}
}
break;
}
}
if (item.DisplayName != String.Empty)
{
children[counter] = item;
counter++;
}
else
{
SetItemType(ItemType.Folder);
SetHref(item.Href.AbsoluteUri, item.Href);
SetCreationDate(item.CreationDate);
SetComment(item.Comment);
SetCreatorDisplayName(item.CreatorDisplayName);
SetLastModified(item.LastModified);
foreach (Property property in item.Properties)
{
SetProperty(property);
}
}
}
int childrenCount = 0;
foreach (IHierarchyItem item in children)
{
if (item != null)
{
childrenCount++;
}
}
_children = new IHierarchyItem[childrenCount];
counter = 0;
foreach (IHierarchyItem item in children)
{
if (item != null)
{
_children[counter] = item;
counter++;
}
}
}
catch (XmlException e)
{
}
}
}
}
}