Пример #1
0
        /// <summary>
        /// Invoked when an IQ stanza has been received.
        /// </summary>
        /// <param name="stanza">The stanza which has been received.</param>
        /// <returns>true to intercept the stanza or false to pass the stanza
        /// on to the next handler.</returns>
        public async Task <bool> Input(Iq stanza)
        {
            if (stanza.Type != IqType.Set)
            {
                return(false);
            }
            var e = stanza.Data["open"];

            if (e == null)
            {
                e = stanza.Data["close"];
            }
            if (e == null)
            {
                e = stanza.Data["data"];
            }
            if (e == null || e.NamespaceURI != "http://jabber.org/protocol/ibb")
            {
                return(false);
            }
            string sessionId = e.GetAttribute("sid");

            // Dispatch to the proper handler method.
            try
            {
                switch (e.Name)
                {
                case "open":
                    Open(sessionId, stanza);
                    break;

                case "data":
                    await Data(sessionId, stanza);

                    break;

                case "close":
                    Close(sessionId, stanza);
                    break;

                default:
                    throw new ArgumentException("Invalid stanza element.");
                }
                // Acknowledge the IQ request.
                await im.IqResult(stanza);
            }
            catch (Exception ex)
            {
                // Send an error response.
                await im.IqError(stanza, ErrorType.Cancel, ErrorCondition.ServiceUnavailable,
                                 ex.Message);

                // If there is an open stream associated with the session id, we should
                // dispose of it.
                siFileTransfer.InvalidateSession(sessionId);
            }
            // We took care of this IQ request, so intercept it and don't pass it
            // on to other handlers.
            return(true);
        }
Пример #2
0
        /// <summary>
        /// Performs the actual data-transfer implied by the specified
        /// SI session.
        /// </summary>
        /// <param name="session">The SI session whose data to transfer.</param>
        /// <exception cref="ArgumentNullException">The session parameter is
        /// null.</exception>
        /// <exception cref="NotSupportedException">The XMPP extension
        /// implementing this method is not supported by the intended recipient's
        /// XMPP client.</exception>
        /// <exception cref="XmppErrorException">The server or the XMPP entity
        /// with the specified JID returned an XMPP error code. Use the Error
        /// property of the XmppErrorException to obtain the specific error
        /// condition.</exception>
        /// <exception cref="XmppException">The server returned invalid data or
        /// another unspecified XMPP error occurred.</exception>
        public void Transfer(SISession session)
        {
            IEnumerable <Streamhost> proxies = null;

            // Determine if this is going to be a direct or a mediated transfer.
            if (ProxyAllowed)
            {
                try
                {
                    var externalAddresses = GetExternalAddresses();
                    // If all of our external addresses are behind NATs, we may need a proxy.
                    bool behindNAT = externalAddresses.All(addr => BehindNAT(addr));
                    if (behindNAT)
                    {
                        // Look for user-defined proxies first.
                        if (Proxies.Count > 0)
                        {
                            proxies = Proxies;
                        }
                        else
                        {
                            // Otherwise query XMPP server for a list of proxies.
                            proxies = GetProxyList();
                        }
                    }
                }
                catch
                {
                    // Retrieving the external addresses may fail as well as querying
                    // the XMPP server for proxies. In these cases, we at least try
                    // with a direct transfer.
                }
            }

            try
            {
                if (proxies != null && proxies.Count() > 0)
                {
                    MediatedTransfer(session, proxies);
                }
                else
                {
                    DirectTransfer(session);
                }
            }
            catch (Exception)
            {
                // Raise the 'TransferAborted' event.
                TransferAborted.Raise(this, new TransferAbortedEventArgs(session));
                // Invalidate the session.
                siFileTransfer.InvalidateSession(session.Sid);
            }
        }