public async void LoadData(Account account) { _account = account; AccountName = _account.Name; var webDav = new WebDAVClient(_account.GetUri(), await _accountService.GetCredentials(_account)); try { var files = await webDav.GetEntries(_account.WebDAVPath, true); Files = new ObservableCollection<WebDAVFile> // except current folder (files.Where(x => x.FilePath.ToString() != _account.WebDAVPath)); } catch { } }
public async Task<AuthenticationMethod> GetAuthenticationInfo(ConnectionInfo connection) { var webdav = new WebDAVClient(connection.WebDAVUrl); var method = AuthenticationMethod.Unknown; try { await webdav.GetRootEntries(false); method = AuthenticationMethod.None; } catch (WebException webex) { if (webex != null && webex.Response is HttpWebResponse) { var webResponse = (HttpWebResponse)webex.Response; if (webResponse.StatusCode == HttpStatusCode.Unauthorized) { var authHeader = webResponse.Headers["www-authenticate"].ToLower().Trim(); if (authHeader.StartsWith("basic")) method = AuthenticationMethod.Basic; } } } return method; }
private async 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 var davTest = new WebDAVClient(state.AssociatedAccount.GetUri(), await App.AccountService.GetCredentials(state.AssociatedAccount)); // call tests while (pathsToTest.Count > 0) { var path = pathsToTest.Dequeue(); try { await davTest.GetEntries(path, false); } catch { // all other states are fail states success = false; Dispatcher.BeginInvoke(() => { //TODO: fix message MessageBox.Show("EditAccountPage_CheckingConnection_DAVTestFailed".Translate(path, "requestResult.StatusText"), "Error_Caption".Translate(), MessageBoxButton.OK); }); } collector.Raise(path); } } else { OnConnectTestComplete(success, state.AssociatedAccount); } }
private async Task QueryStructure() { var dav = new WebDAVClient(_workingAccount.GetUri(), await App.AccountService.GetCredentials(_workingAccount)); try { var entries = await dav.GetEntries(_workingPath, true); if (entries.Count == 0) throw new Exception("No entries found"); bool _firstItem = false; // display all items linear // we cannot wait till an item is displayed, instead for a fluid // behaviour we should calculate fadeIn-delays. int delayStart = 0; int delayStep = 50; // ms foreach (var item in entries) { File fileItem = new File() { FileName = item.FileName, FilePath = item.FilePath.ToString(), FileSize = item.Size, FileType = item.MimeType, FileCreated = item.Created, FileLastModified = item.LastModified, IsDirectory = item.IsDirectory }; bool display = true; switch (_views[_viewIndex]) { case "detail": if (!_firstItem) { _firstItem = true; // Root if (fileItem.IsDirectory) { if (item.FilePath.ToString() == _workingAccount.WebDAVPath) { // cannot go up further display = false; } else { fileItem.IsRootItem = true; fileItem.FilePath = fileItem.FileParentPath; } } } if (display) { FileDetailViewControl detailControl = new FileDetailViewControl() { DataContext = fileItem, Opacity = 0, Background = new SolidColorBrush() { Color = Colors.Transparent }, }; DetailList.Items.Add(detailControl); detailControl.Delay(delayStart, () => { detailControl.FadeIn(100); }); delayStart += delayStep; } break; case "tile": if (!_firstItem) { _firstItem = true; // Root if (fileItem.IsDirectory) { if (item.FilePath.ToString() == _workingAccount.WebDAVPath) { // cannot go up further display = false; } else { fileItem.IsRootItem = true; fileItem.FilePath = fileItem.FileParentPath; } } } if (display) { FileMultiTileViewControl multiControl = new FileMultiTileViewControl(_workingAccount, fileItem, true) { Width = 200, Height = 200, Opacity = 0, Margin = new Thickness(0, 0, 10, 10), }; multiControl.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(TileListSelectionChanged); // sometimes the exception "wrong parameter" is thrown - but why??? TileView.Children.Add(multiControl); multiControl.Delay(delayStart, () => { multiControl.FadeIn(100); }); } break; } } progress.IsVisible = false; } catch (Exception ex) { progress.IsVisible = false; var webException = ex as WebException; var webResponse = webException != null ? webException.Response as HttpWebResponse : null; if (webException != null && webException.Status == WebExceptionStatus.ProtocolError && webResponse != null && webResponse.StatusCode == HttpStatusCode.Unauthorized) { MessageBox.Show("FetchFile_Unauthorized".Translate(), "Error_Caption".Translate(), MessageBoxButton.OK); } else { MessageBox.Show("FetchFile_Unexpected_Result".Translate(), "Error_Caption".Translate(), MessageBoxButton.OK); } } }
/// <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> internal DAVRequestResult(WebDAVClient 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 RequestProperties.ResourceType: waitForResourceType = true; break; case RequestProperties.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 RequestProperties.ResourceType: waitForResourceType = false; break; case RequestProperties.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 RequestProperties.QuotaUsedBytes: case RequestProperties.QuotaAvailableBytes: case RequestProperties.GetContentLength: pItem.Properties.Add(lastElementName, long.Parse(reader.Value)); break; case RequestProperties.DisplayName: case RequestProperties.GetContentLanguage: case RequestProperties.GetContentType: case RequestProperties.GetETag: pItem.Properties.Add(lastElementName, reader.Value); break; case RequestProperties.GetLastModified: case RequestProperties.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> internal DAVRequestResult(WebDAVClient request, object status, string statusText) { Status = (ServerStatus)Enum.Parse(typeof(ServerStatus), status.ToString(), false); StatusText = statusText; Request = request; Items = new List<Item>(); }