예제 #1
0
 /// <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>();
 }
예제 #2
0
 /// <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>();
 }
예제 #3
0
        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);
            }
            
        }
예제 #4
0
        /// <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;
                    }
                }
            }
        }
예제 #5
0
        /// <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;
                    }
                }
            }
        }
예제 #6
0
 /// <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>();
 }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
 private void StartRequest()
 {
     var dav = new WebDAV(_workingAccount.GetUri(), _workingAccount.GetCredentials());
     dav.StartRequest(DAVRequestHeader.CreateListing(_workingPath), DAVRequestBody.CreateAllPropertiesListing(), null, FetchStructureComplete);
 }