/// <summary> /// Creates a empty object. /// </summary> /// <param name="request"></param> /// <param name="status"></param> public DAVRequestResult(WebDAV request, object status, string statusText) { Status = (ServerStatus)Enum.Parse(typeof(ServerStatus), status.ToString(), false); StatusText = statusText; Request = request; Items = new List<Item>(); }
/// <summary> /// Creates a empty object. /// </summary> /// <param name="request"></param> /// <param name="status"></param> public DAVRequestResult(WebDAV request, object status, string statusText) { Status = (ServerStatus)Enum.Parse(typeof(ServerStatus), status.ToString(), false); StatusText = statusText; Request = request; Items = new List <Item>(); }
private void OnHTTPResponse(IAsyncResult result) { AsyncHttpResponse state = (AsyncHttpResponse)result.AsyncState; var success = false; try { state.Request.EndGetResponse(result); success = true; } catch (WebException) { if (state.AssociatedAccount.Protocol == "https") { // try to fetch certificate try { var tls = new TLSHandshake(); tls.SetServerNameExtension(state.AssociatedAccount.Hostname); var socket = new StreamSocket(); socket.Connect(state.AssociatedAccount.Hostname, state.AssociatedAccount.GetPort(true)); socket.Write(tls.CreateClientHello()); DateTime startTime = DateTime.Now; while (true) { var data = socket.Read(); if (data.Length > 0) { var cert = tls.FindPacket(data, TLSHandshake.TLS_HANDSHAKE_CERTIFICATE); if (cert.Length > 0) { var details = tls.GetCertificateDetails(cert); if (details.Count > 0) { var certDetails = details[0]; if (certDetails.ContainsKey("CN")) { Dispatcher.BeginInvoke(() => { MessageBox.Show("EditAccountPage_Connection_Rejected".Translate(state.AssociatedAccount.Hostname, certDetails["CN"], certDetails["ValidAfter"], certDetails["ValidTo"]), "EditAccountPage_Connection_Rejected_Caption".Translate(), MessageBoxButton.OK); _overlay.Hide(); }); return; } } break; } } if (DateTime.Now.Subtract(startTime).TotalSeconds > 5) { break; } } } catch (Exception) { // Host not reachable, no SSL host or TLS version not supported } } } catch (Exception) { // HTTPWebRequest has failed } if (success) { // Testing DAV //TODO: Add your additional connection test statement here // To complete the test all fragments must have been fired. EventCollector collector = new EventCollector() { Complete = () => { OnConnectTestComplete(success, state.AssociatedAccount); } }; collector.WaitFor(state.AssociatedAccount.WebDAVPath); collector.WaitFor(state.AssociatedAccount.CalDAVPath); // define paths to test Queue<string> pathsToTest = new Queue<string>(); pathsToTest.Enqueue(state.AssociatedAccount.WebDAVPath); pathsToTest.Enqueue(state.AssociatedAccount.CalDAVPath); // create master instance WebDAV davTest = new WebDAV(state.AssociatedAccount.GetUri(), state.AssociatedAccount.GetCredentials()); // call tests while (pathsToTest.Count > 0) { var path = pathsToTest.Dequeue(); davTest.StartRequest(DAVRequestHeader.CreateListing(path), path, (requestResult, userObj) => { if (requestResult.Status != ServerStatus.MultiStatus) { // all other states are fail states success = false; Dispatcher.BeginInvoke(() => { MessageBox.Show("EditAccountPage_CheckingConnection_DAVTestFailed".Translate(userObj, requestResult.StatusText), "Error_Caption".Translate(), MessageBoxButton.OK); }); } collector.Raise(userObj); }); } } else { OnConnectTestComplete(success, state.AssociatedAccount); } }
/// <summary> /// Parses the DAV result. /// Note that it will only parse if the server status was 207. /// There maybe error outputs on 4xx and 5xx but this will not parsed /// by this class. /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <param name="uri"></param> public DAVRequestResult(WebDAV request, HttpWebResponse response, Uri uri) { Request = request; Items = new List<Item>(); Status = (ServerStatus)Enum.Parse(typeof(ServerStatus), response.StatusCode.ToString(), false); StatusText = response.StatusDescription; IsMultiState = Status == ServerStatus.MultiStatus; _stream = new MemoryStream(); response.GetResponseStream().CopyTo(_stream); // dispose response.Dispose(); _stream.Seek(0, SeekOrigin.Begin); if (_stream.Length == 0) return; // A kingdom for normal DOMDocument support. // Why not XDocument? XmlReader is faster and less resource hungry. // A huge multitstatus would be first loaded to memory completely. // // This reader can only go forward. Read-* methods will cause // to jump over elements. Hence we stop at the element and // store the element name. Then wait for Text-Elements value // to capture. using(XmlReader reader = XmlReader.Create(_stream, null)) { Item item = new Item(); var waitForResourceType = false; var lastElementName = ""; var waitForLockScope = false; var waitForLockType = false; List<DAVLocking> lockingList = null; List<PropertyState> propertyStateList = null; PropertyState pItem = null; DAVLocking litem = null; while (reader.Read()) { switch (reader.NodeType) { // look for special elements case XmlNodeType.Element: if (reader.NamespaceURI == XmlNamespaces.NsDav) { switch (reader.LocalName) { // DAV Elements // Response case Elements.Response: // start a new item // pItem must be set before d:prop in order to // catch non-real properties such "href" item = new Item(); propertyStateList = new List<PropertyState>(); pItem = new PropertyState(); break; // Resource type case Elements.Collection: if (waitForResourceType) { item.ResourceType = ResourceType.Collection; } break; // Lock case Elements.LockEntry: litem = new DAVLocking(); lockingList.Add(litem); break; case Elements.LockScope: waitForLockScope = true; break; case Elements.LockType: waitForLockType = true; break; case Elements.ExclusiveLocking: if (waitForLockScope) { litem.Scope = DAVLocking.LockScope.Exclusive; } break; case Elements.SharedLocking: if (waitForLockScope) { litem.Scope = DAVLocking.LockScope.Shared; } break; case Elements.WriteLocking: if (waitForLockType) { litem.Type = DAVLocking.LockType.Write; } break; case Elements.LockDiscovery: ///TODO break; // DAV Properties case Elements.Properties: // a pItem was already created before break; case Properties.ResourceType: waitForResourceType = true; break; case Properties.SupportedLock: lockingList = new List<DAVLocking>(); break; default: lastElementName = reader.LocalName; break; } } break; // clean up case XmlNodeType.EndElement: if (reader.NamespaceURI == XmlNamespaces.NsDav) { switch (reader.LocalName) { // DAV Elements case Elements.PropertyState: // save to list and create a new one (which stays maybe temporary) propertyStateList.Add(pItem); pItem = new PropertyState(); break; case Elements.Response: // clean the list // the HTTP Status is important foreach (PropertyState state in propertyStateList) { if (state.Status == ServerStatus.OK) { item.Properties = state.Properties; } else { item.FailedProperties.Add(state); } } // Close the item Items.Add(item); item = null; // Reset the property state list propertyStateList = null; pItem = null; break; // Locking case Elements.LockType: waitForLockType = false; break; case Elements.LockScope: waitForLockScope = false; break; // DAV Properties case Properties.ResourceType: waitForResourceType = false; break; case Properties.SupportedLock: item.Locking = lockingList; break; } } break; // Grap the text values case XmlNodeType.Text: // no whitespace please if (reader.Value == null) continue; // can't set in empty element if (item == null) continue; switch (lastElementName) { // DAV Elements case Elements.Reference: string _ref = Uri.UnescapeDataString(reader.Value); pItem.Properties.Add(lastElementName, _ref); pItem.Properties.Add(lastElementName + ".local", _ref.Trim('/').Split('/').Last()); break; // Status element case Elements.Status: List<string> s = new List<string>(reader.Value.Split(' ')); s.RemoveAt(0); pItem.Status = (ServerStatus)Enum.Parse(typeof(ServerStatus), s[0], false); s.RemoveAt(0); pItem.ServerStatusText = String.Join(" ", s.ToArray()); break; // DAV Properties case Properties.QuotaUsedBytes: case Properties.QuotaAvailableBytes: case Properties.GetContentLength: pItem.Properties.Add(lastElementName, long.Parse(reader.Value)); break; case Properties.DisplayName: case Properties.GetContentLanguage: case Properties.GetContentType: case Properties.GetETag: pItem.Properties.Add(lastElementName, reader.Value); break; case Properties.GetLastModified: case Properties.CreationDate: pItem.Properties.Add(lastElementName, DateTime.Parse(reader.Value)); break; } lastElementName = ""; break; } } } }
/// <summary> /// Parses the DAV result. /// Note that it will only parse if the server status was 207. /// There maybe error outputs on 4xx and 5xx but this will not parsed /// by this class. /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <param name="uri"></param> public DAVRequestResult(WebDAV request, HttpWebResponse response, Uri uri) { Request = request; Items = new List <Item>(); Status = (ServerStatus)Enum.Parse(typeof(ServerStatus), response.StatusCode.ToString(), false); IsMultiState = Status == ServerStatus.MultiStatus; _stream = new MemoryStream(); response.GetResponseStream().CopyTo(_stream); // dispose response.Dispose(); _stream.Seek(0, SeekOrigin.Begin); if (_stream.Length == 0) { return; } // A kingdom for normal DOMDocument support. // Why not XDocument? XmlReader is faster and less resource hungry. // A huge multitstatus would be first loaded to memory completely. // // This reader can only go forward. Read-* methods will cause // to jump over elements. Hence we stop at the element and // store the element name. Then wait for Text-Elements value // to capture. using (XmlReader reader = XmlReader.Create(_stream, null)) { Item item = new Item(); var waitForResourceType = false; var lastElementName = ""; var waitForLockScope = false; var waitForLockType = false; List <DAVLocking> lockingList = null; List <PropertyState> propertyStateList = null; PropertyState pItem = null; DAVLocking litem = null; while (reader.Read()) { switch (reader.NodeType) { // look for special elements case XmlNodeType.Element: if (reader.NamespaceURI == XmlNamespaces.NsDav) { switch (reader.LocalName) { // DAV Elements // Response case Elements.Response: // start a new item // pItem must be set before d:prop in order to // catch non-real properties such "href" item = new Item(); propertyStateList = new List <PropertyState>(); pItem = new PropertyState(); break; // Resource type case Elements.Collection: if (waitForResourceType) { item.ResourceType = ResourceType.Collection; } break; // Lock case Elements.LockEntry: litem = new DAVLocking(); lockingList.Add(litem); break; case Elements.LockScope: waitForLockScope = true; break; case Elements.LockType: waitForLockType = true; break; case Elements.ExclusiveLocking: if (waitForLockScope) { litem.Scope = DAVLocking.LockScope.Exclusive; } break; case Elements.SharedLocking: if (waitForLockScope) { litem.Scope = DAVLocking.LockScope.Shared; } break; case Elements.WriteLocking: if (waitForLockType) { litem.Type = DAVLocking.LockType.Write; } break; case Elements.LockDiscovery: ///TODO break; // DAV Properties case Elements.Properties: // a pItem was already created before break; case Properties.ResourceType: waitForResourceType = true; break; case Properties.SupportedLock: lockingList = new List <DAVLocking>(); break; default: lastElementName = reader.LocalName; break; } } break; // clean up case XmlNodeType.EndElement: if (reader.NamespaceURI == XmlNamespaces.NsDav) { switch (reader.LocalName) { // DAV Elements case Elements.PropertyState: // save to list and create a new one (which stays maybe temporary) propertyStateList.Add(pItem); pItem = new PropertyState(); break; case Elements.Response: // clean the list // the HTTP Status is important foreach (PropertyState state in propertyStateList) { if (state.Status == ServerStatus.OK) { item.Properties = state.Properties; } else { item.FailedProperties.Add(state); } } // Close the item Items.Add(item); item = null; // Reset the property state list propertyStateList = null; pItem = null; break; // Locking case Elements.LockType: waitForLockType = false; break; case Elements.LockScope: waitForLockScope = false; break; // DAV Properties case Properties.ResourceType: waitForResourceType = false; break; case Properties.SupportedLock: item.Locking = lockingList; break; } } break; // Grap the text values case XmlNodeType.Text: // no whitespace please if (reader.Value == null) { continue; } // can't set in empty element if (item == null) { continue; } switch (lastElementName) { // DAV Elements case Elements.Reference: string _ref = Uri.UnescapeDataString(reader.Value); string _localRef = _ref.Substring(uri.LocalPath.Length, _ref.Length - uri.LocalPath.Length); pItem.Properties.Add(lastElementName, _ref); pItem.Properties.Add(lastElementName + ".local", _localRef.Trim('/')); break; // Status element case Elements.Status: List <string> s = new List <string>(reader.Value.Split(' ')); s.RemoveAt(0); pItem.Status = (ServerStatus)Enum.Parse(typeof(ServerStatus), s[0], false); s.RemoveAt(0); pItem.ServerStatusText = String.Join(" ", s.ToArray()); break; // DAV Properties case Properties.QuotaUsedBytes: case Properties.QuotaAvailableBytes: case Properties.GetContentLength: pItem.Properties.Add(lastElementName, long.Parse(reader.Value)); break; case Properties.DisplayName: case Properties.GetContentLanguage: case Properties.GetContentType: case Properties.GetETag: pItem.Properties.Add(lastElementName, reader.Value); break; case Properties.GetLastModified: case Properties.CreationDate: pItem.Properties.Add(lastElementName, DateTime.Parse(reader.Value)); break; } lastElementName = ""; break; } } } }
/// <summary> /// Creates a empty object. /// </summary> /// <param name="request"></param> /// <param name="status"></param> public DAVRequestResult(WebDAV request, ServerStatus status) { Status = status; Request = request; Items = new List <Item>(); }
/// <summary> /// Tries to fetch a given path and refreshes the views. /// </summary> /// <param name="path"></param> private void FetchStructure(string path) { _board = (Storyboard)Resources["DropFileListFadeOut"] as Storyboard; if (_dropFileListFadeOutCompleted == null) { _dropFileListFadeOutCompleted = new EventHandler(delegate { _context.Files.Clear(); _collector.Raise(_dropFileListFadeOutCompleted); }); _board.Completed += _dropFileListFadeOutCompleted; } if (_overlay == null) { _overlay = new ProgressOverlayPopup() { BackgroundColor = Colors.Transparent }; } _overlay.Show(); _result = null; _board.Begin(); _collector.WaitFor(_dropFileListFadeOutCompleted); _collector.WaitFor("FileListReceived"); _collector.Complete = () => { FetchStructureCompleteHandler(_result); Dispatcher.BeginInvoke(() => { ((Storyboard)Resources["DropFileListFadeIn"] as Storyboard).Begin(); _overlay.Hide(); }); }; if (_workingAccount != null) { var dav = new WebDAV(_workingAccount.GetUri(), _workingAccount.GetCredentials()); dav.StartRequest(DAVRequestHeader.CreateListing(path), DAVRequestBody.CreateAllPropertiesListing(), null, FetchStructureComplete); } }
private void StartRequest() { var dav = new WebDAV(_workingAccount.GetUri(), _workingAccount.GetCredentials()); dav.StartRequest(DAVRequestHeader.CreateListing(_workingPath), DAVRequestBody.CreateAllPropertiesListing(), null, FetchStructureComplete); }