diff options
Diffstat (limited to 'src/com')
11 files changed, 251 insertions, 32 deletions
diff --git a/src/com/isode/stroke/elements/RawXMLPayload.java b/src/com/isode/stroke/elements/RawXMLPayload.java index 30c9f74..a1652c5 100644 --- a/src/com/isode/stroke/elements/RawXMLPayload.java +++ b/src/com/isode/stroke/elements/RawXMLPayload.java @@ -15,6 +15,14 @@ package com.isode.stroke.elements; public class RawXMLPayload extends Payload { private String rawXML_ = ""; + public RawXMLPayload() { + this(""); + } + + public RawXMLPayload(String data) { + this.rawXML_ = data; + } + public void setRawXML(String data) { rawXML_ = data; } diff --git a/src/com/isode/stroke/elements/SoftwareVersion.java b/src/com/isode/stroke/elements/SoftwareVersion.java index 9d2bc6e..4b5b9a4 100644 --- a/src/com/isode/stroke/elements/SoftwareVersion.java +++ b/src/com/isode/stroke/elements/SoftwareVersion.java @@ -22,7 +22,15 @@ public class SoftwareVersion extends Payload { } public SoftwareVersion() { - + this("","",""); + } + + public SoftwareVersion(final String name) { + this(name, "", ""); + } + + public SoftwareVersion(final String name, final String version) { + this(name, version, ""); } public String getName() { diff --git a/src/com/isode/stroke/queries/IQRouter.java b/src/com/isode/stroke/queries/IQRouter.java index 0dd55f2..7b6e5d7 100644 --- a/src/com/isode/stroke/queries/IQRouter.java +++ b/src/com/isode/stroke/queries/IQRouter.java @@ -10,6 +10,7 @@ import com.isode.stroke.elements.ErrorPayload; import com.isode.stroke.elements.IQ; import com.isode.stroke.signals.Slot1; import com.isode.stroke.jid.JID; +import java.util.Collections; /** * This class is responsible for routing all IQ stanzas to the handlers. It's @@ -21,12 +22,16 @@ import com.isode.stroke.jid.JID; */ public class IQRouter { - private final Vector<IQHandler> handlers_ = new Vector<IQHandler>(); - private final IQChannel channel_; + private Vector<IQHandler> handlers_ = new Vector<IQHandler>(); + private IQChannel channel_; private JID jid_ = new JID(); + private JID from_ = new JID(); + private Vector<IQHandler> queuedRemoves_ = new Vector<IQHandler>(); + private boolean queueRemoves_; public IQRouter(IQChannel channel) { channel_ = channel; + queueRemoves_ = false; channel_.onIQReceived.connect(new Slot1<IQ>() { public void call(IQ p1) { @@ -42,12 +47,20 @@ public class IQRouter { } public void removeHandler(IQHandler handler) { - synchronized (handlers_) { - handlers_.remove(handler); + if (queueRemoves_) { + queuedRemoves_.add(handler); + } + else { + synchronized (handlers_) { + handlers_.remove(handler); + } } } public void sendIQ(IQ iq) { + if (from_.isValid() && !iq.getFrom().isValid()) { + iq.setFrom(from_); + } channel_.sendIQ(iq); } @@ -70,9 +83,13 @@ public class IQRouter { } private void handleIQ(IQ iq) { + queueRemoves_ = true; boolean handled = false; + Vector<IQHandler> i = new Vector<IQHandler>(); + i.addAll(handlers_); + Collections.reverse(i); synchronized (handlers_) { - for (IQHandler handler : handlers_) { + for (IQHandler handler : i) { handled |= handler.handleIQ(iq); if (handled) { break; @@ -82,6 +99,18 @@ public class IQRouter { if (!handled && (iq.getType().equals(IQ.Type.Get) || iq.getType().equals(IQ.Type.Set))) { sendIQ(IQ.createError(iq.getFrom(), iq.getID(), ErrorPayload.Condition.FeatureNotImplemented, ErrorPayload.Type.Cancel)); } + + processPendingRemoves(); + queueRemoves_ = false; + } + + public void processPendingRemoves() { + synchronized(handlers_) { + for(IQHandler handler : queuedRemoves_) { + handlers_.remove(handler); + } + } + queuedRemoves_.clear(); } /** @@ -98,5 +127,15 @@ public class IQRouter { public JID getJID() { return jid_; } - + + /** + * Sets the 'from' JID for all outgoing IQ stanzas. + * + * By default, IQRouter does not add a from to IQ stanzas, since + * this is automatically added by the server. This overrides this + * default behavior, which is necessary for e.g. components. + */ + public void setFrom(final JID from) { + from_ = from; + } } diff --git a/src/com/isode/stroke/queries/RawRequest.java b/src/com/isode/stroke/queries/RawRequest.java new file mode 100644 index 0000000..eaa31bc --- /dev/null +++ b/src/com/isode/stroke/queries/RawRequest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011-2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +package com.isode.stroke.queries; + +import com.isode.stroke.queries.Request; +import com.isode.stroke.elements.RawXMLPayload; +import com.isode.stroke.elements.ErrorPayload; +import com.isode.stroke.elements.Payload; +import com.isode.stroke.elements.IQ; +import com.isode.stroke.jid.JID; +import com.isode.stroke.serializer.PayloadSerializer; +import com.isode.stroke.serializer.payloadserializers.ErrorSerializer; +import com.isode.stroke.serializer.payloadserializers.FullPayloadSerializerCollection; +import com.isode.stroke.signals.Signal1; +import com.isode.stroke.signals.SignalConnection; + +public class RawRequest extends Request { + + private FullPayloadSerializerCollection serializers = new FullPayloadSerializerCollection(); + + public RawRequest(IQ.Type type, final JID receiver, final String data, IQRouter router) { + super(type, receiver, new RawXMLPayload(data), router); + } + + public static RawRequest create(IQ.Type type, final JID recipient, final String data, IQRouter router) { + return new RawRequest(type, recipient, data, router); + } + + public final Signal1<String> onResponse = new Signal1<String>(); + + protected void handleResponse(Payload payload, ErrorPayload error) { + if (error != null) { + onResponse.emit(new ErrorSerializer(serializers).serializePayload(error)); + } + else { + assert(payload != null); + PayloadSerializer serializer = serializers.getPayloadSerializer(payload); + assert(serializer != null); + onResponse.emit(serializer.serialize(payload)); + } + } +} + diff --git a/src/com/isode/stroke/queries/Request.java b/src/com/isode/stroke/queries/Request.java index 52e3854..c5c9999 100644 --- a/src/com/isode/stroke/queries/Request.java +++ b/src/com/isode/stroke/queries/Request.java @@ -13,6 +13,7 @@ import com.isode.stroke.elements.ErrorPayload; import com.isode.stroke.elements.IQ; import com.isode.stroke.elements.IQ.Type; import com.isode.stroke.elements.Payload; +import com.isode.stroke.elements.RawXMLPayload; import com.isode.stroke.jid.JID; import java.util.logging.Logger; @@ -20,13 +21,13 @@ import java.util.logging.Logger; * Base class for IQ requests. */ public abstract class Request implements IQHandler { - protected final Type type_; - protected final IQRouter router_; - protected final JID receiver_; - protected final JID sender_; + protected Type type_; + protected IQRouter router_; + protected JID receiver_ = new JID(); + protected JID sender_ = new JID(); private boolean sent_; private Payload payload_; - private String id_; + private String id_ = ""; private Logger logger_ = Logger.getLogger(this.getClass().getName()); /** @@ -99,11 +100,15 @@ public abstract class Request implements IQHandler { if (isCorrectSender(iq.getFrom())) { if (iq.getType().equals(IQ.Type.Result)) { - handleResponse(iq.getPayload(payload_), null); + Payload payload = iq.getPayload(payload_); + if (payload == null && (payload_ instanceof RawXMLPayload) && !iq.getPayloads().isEmpty()) { + payload = iq.getPayloads().firstElement(); + } + handleResponse(payload, null); } else { ErrorPayload errorPayload = iq.getPayload(new ErrorPayload()); if (errorPayload != null) { - handleResponse(null, errorPayload); + handleResponse(null, errorPayload); } else { handleResponse(null, new ErrorPayload(ErrorPayload.Condition.UndefinedCondition)); } @@ -117,20 +122,17 @@ public abstract class Request implements IQHandler { } private boolean isCorrectSender(final JID jid) { - if (isAccountJID(receiver_)) { - return isAccountJID(jid); + if (router_.isAccountJID(receiver_)) { + if (jid.isValid() && jid.compare(router_.getJID(), JID.CompareType.WithResource) == 0) { + // This unspecified behavior seems to happen in ejabberd versions (e.g. 2.0.5) + logger_.warning("Server responded to an account request with a full JID, which is not allowed. Handling it anyway."); + return true; + } + return router_.isAccountJID(jid); } - return (jid.compare(receiver_, JID.CompareType.WithResource) == 0); - } - - private boolean isAccountJID(final JID jid) { - // If the router's JID is not set, we don't check anything - if (!router_.getJID().isValid()) { - return true; + else { + return jid.compare(receiver_, JID.CompareType.WithResource) == 0; } - - return jid.isValid() ? - router_.getJID().compare(jid, JID.CompareType.WithoutResource) == 0 : true; } public JID getReceiver() { diff --git a/src/com/isode/stroke/queries/Responder.java b/src/com/isode/stroke/queries/Responder.java index 203dd7e..831bcd3 100644 --- a/src/com/isode/stroke/queries/Responder.java +++ b/src/com/isode/stroke/queries/Responder.java @@ -30,6 +30,7 @@ public abstract class Responder<PAYLOAD_TYPE extends Payload> implements IQHandl public Responder(final PAYLOAD_TYPE payloadType, IQRouter router) { payloadType_ = payloadType; router_ = router; + isFinalResonder_ = true; } /** @@ -114,6 +115,10 @@ public abstract class Responder<PAYLOAD_TYPE extends Payload> implements IQHandl return router_; } + protected void setFinal(boolean isFinal) { + isFinalResonder_ = isFinal; + } + @Override public boolean handleIQ(IQ iq) { if (IQ.Type.Set.equals(iq.getType()) || IQ.Type.Get.equals(iq.getType())) { @@ -127,7 +132,11 @@ public abstract class Responder<PAYLOAD_TYPE extends Payload> implements IQHandl result = handleGetRequest(iq.getFrom(), iq.getTo(), iq.getID(), payload); } if (!result) { - router_.sendIQ(IQ.createError(iq.getFrom(), iq.getID(), ErrorPayload.Condition.NotAllowed, ErrorPayload.Type.Cancel)); + if(isFinalResonder_) { + router_.sendIQ(IQ.createError(iq.getFrom(), iq.getID(), ErrorPayload.Condition.NotAllowed, ErrorPayload.Type.Cancel)); + } else { + return false; + } } return true; } @@ -136,4 +145,5 @@ public abstract class Responder<PAYLOAD_TYPE extends Payload> implements IQHandl } private IQRouter router_; private PAYLOAD_TYPE payloadType_; + private boolean isFinalResonder_; }; diff --git a/src/com/isode/stroke/queries/requests/GetInBandRegistrationFormRequest.java b/src/com/isode/stroke/queries/requests/GetInBandRegistrationFormRequest.java new file mode 100644 index 0000000..57182e6 --- /dev/null +++ b/src/com/isode/stroke/queries/requests/GetInBandRegistrationFormRequest.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2010-2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +package com.isode.stroke.queries.requests; + +import com.isode.stroke.queries.GenericRequest; +import com.isode.stroke.queries.IQRouter; +import com.isode.stroke.elements.InBandRegistrationPayload; +import com.isode.stroke.elements.IQ; +import com.isode.stroke.jid.JID; + +public class GetInBandRegistrationFormRequest extends GenericRequest<InBandRegistrationPayload> { + + public GetInBandRegistrationFormRequest(final JID to, IQRouter router) { + super(IQ.Type.Get, to, new InBandRegistrationPayload(), router); + } + + public static GetInBandRegistrationFormRequest create(final JID to, IQRouter router) { + return new GetInBandRegistrationFormRequest(to, router); + } +}
\ No newline at end of file diff --git a/src/com/isode/stroke/queries/requests/GetSoftwareVersionRequest.java b/src/com/isode/stroke/queries/requests/GetSoftwareVersionRequest.java new file mode 100644 index 0000000..aeec635 --- /dev/null +++ b/src/com/isode/stroke/queries/requests/GetSoftwareVersionRequest.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2010-2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +package com.isode.stroke.queries.requests; + +import com.isode.stroke.queries.GenericRequest; +import com.isode.stroke.queries.IQRouter; +import com.isode.stroke.elements.SoftwareVersion; +import com.isode.stroke.elements.IQ; +import com.isode.stroke.jid.JID; + +public class GetSoftwareVersionRequest extends GenericRequest<SoftwareVersion> { + + public GetSoftwareVersionRequest(final JID recipient, IQRouter router) { + super(IQ.Type.Get, recipient, new SoftwareVersion(), router); + } + + public static GetSoftwareVersionRequest create(final JID recipient, IQRouter router) { + return new GetSoftwareVersionRequest(recipient, router); + } +}
\ No newline at end of file diff --git a/src/com/isode/stroke/queries/requests/SetInBandRegistrationRequest.java b/src/com/isode/stroke/queries/requests/SetInBandRegistrationRequest.java new file mode 100644 index 0000000..e282847 --- /dev/null +++ b/src/com/isode/stroke/queries/requests/SetInBandRegistrationRequest.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010-2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ +/* + * Copyright (c) 2015 Tarun Gupta. + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +package com.isode.stroke.queries.requests; + +import com.isode.stroke.queries.Request; +import com.isode.stroke.queries.IQRouter; +import com.isode.stroke.elements.InBandRegistrationPayload; +import com.isode.stroke.elements.Payload; +import com.isode.stroke.elements.IQ; +import com.isode.stroke.elements.ErrorPayload; +import com.isode.stroke.signals.Signal2; +import com.isode.stroke.jid.JID; + +public class SetInBandRegistrationRequest extends Request { + + public final Signal2<Payload, ErrorPayload> onResponse = new Signal2<Payload, ErrorPayload>(); + + public SetInBandRegistrationRequest(final JID to, InBandRegistrationPayload payload, IQRouter router) { + super(IQ.Type.Set, to, (InBandRegistrationPayload)payload, router); + } + + public static SetInBandRegistrationRequest create(final JID to, InBandRegistrationPayload payload, IQRouter router) { + return new SetInBandRegistrationRequest(to, payload, router); + } + + protected void handleResponse(Payload payload, ErrorPayload error) { + onResponse.emit(payload, error); + } +}
\ No newline at end of file diff --git a/src/com/isode/stroke/queries/responders/SoftwareVersionResponder.java b/src/com/isode/stroke/queries/responders/SoftwareVersionResponder.java index 1fd5b36..941e03b 100644 --- a/src/com/isode/stroke/queries/responders/SoftwareVersionResponder.java +++ b/src/com/isode/stroke/queries/responders/SoftwareVersionResponder.java @@ -20,6 +20,10 @@ public class SoftwareVersionResponder extends GetResponder<SoftwareVersion> { super(new SoftwareVersion(), router); } + public void setVersion(final String client, final String version) { + setVersion(client, version, ""); + } + public void setVersion(final String client, final String version, final String os) { this.client = client; this.version = version; @@ -31,7 +35,7 @@ public class SoftwareVersionResponder extends GetResponder<SoftwareVersion> { sendResponse(from, id, new SoftwareVersion(client, version, os)); return true; } - private String client; - private String version; - private String os; + private String client = ""; + private String version = ""; + private String os = ""; }
\ No newline at end of file diff --git a/src/com/isode/stroke/serializer/payloadserializers/ErrorSerializer.java b/src/com/isode/stroke/serializer/payloadserializers/ErrorSerializer.java index 47373f8..5540d2b 100644 --- a/src/com/isode/stroke/serializer/payloadserializers/ErrorSerializer.java +++ b/src/com/isode/stroke/serializer/payloadserializers/ErrorSerializer.java @@ -15,7 +15,7 @@ import com.isode.stroke.serializer.xml.XMLTextNode; import com.isode.stroke.serializer.PayloadSerializerCollection; import com.isode.stroke.serializer.PayloadSerializer; -class ErrorSerializer extends GenericPayloadSerializer<ErrorPayload> { +public class ErrorSerializer extends GenericPayloadSerializer<ErrorPayload> { private PayloadSerializerCollection serializers; @@ -25,7 +25,7 @@ class ErrorSerializer extends GenericPayloadSerializer<ErrorPayload> { } @Override - protected String serializePayload(ErrorPayload error) { + public String serializePayload(ErrorPayload error) { String result = "<error type=\""; switch (error.getType()) { case Continue: result += "continue"; break; |