/// <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 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": Data(sessionId, stanza); break; case "close": Close(sessionId, stanza); break; default: throw new ArgumentException("Invalid stanza element."); } // Acknowledge the IQ request. im.IqResult(stanza); } catch (Exception ex) { // Send an error response. 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); }
/// <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); } }