using System; 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.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); } public class WebDavFolder : WebDavHierarchyItem, IFolder { private IHierarchyItem[] _children = new IHierarchyItem[0]; private Uri _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.ItemType == ItemType.Resource && 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) { } } } } }