in server/core/src/main/java/org/apache/vysper/xmpp/delivery/failure/ReturnErrorToSenderFailureStrategy.java [66:129]
public void process(Stanza failedToDeliverStanza, List<DeliveryException> deliveryExceptions)
throws DeliveryException {
StanzaErrorCondition stanzaErrorCondition = StanzaErrorCondition.SERVICE_UNAVAILABLE;
StanzaErrorType errorType = StanzaErrorType.CANCEL;
XMPPCoreStanza failedCoreStanza = XMPPCoreStanza.getWrapper(failedToDeliverStanza);
// Not a core stanza
if (failedCoreStanza == null) {
throw new DeliveryException("could not return to sender");
}
if ("error".equals(failedCoreStanza.getType())) {
return; // do not answer these
}
if (deliveryExceptions == null) {
XMPPCoreStanza error = XMPPCoreStanza.getWrapper(ServerErrorResponses.getStanzaError(stanzaErrorCondition,
failedCoreStanza, errorType, "stanza could not be delivered", "en", null));
stanzaBroker.write(error.getTo(), error, IgnoreFailureStrategy.INSTANCE);
} else if (deliveryExceptions.size() == 1) {
DeliveryException deliveryException = deliveryExceptions.get(0);
if (deliveryException instanceof LocalRecipientOfflineException) {
// TODO implement 8.2.3 here
stanzaErrorCondition = StanzaErrorCondition.RECIPIENT_UNAVAILABLE;
if (failedCoreStanza instanceof MessageStanza || failedCoreStanza instanceof IQStanza) {
// RFC3921bis#8.1: message and IQ must return service unavailable
stanzaErrorCondition = StanzaErrorCondition.SERVICE_UNAVAILABLE;
}
} else if (deliveryException instanceof NoSuchLocalUserException) {
// RFC3921bis#8.1: message and IQ must return service unavailable
stanzaErrorCondition = StanzaErrorCondition.SERVICE_UNAVAILABLE;
if (failedCoreStanza instanceof PresenceStanza) {
final PresenceStanzaType presenceStanzaType = ((PresenceStanza) failedCoreStanza).getPresenceType();
if (presenceStanzaType == null || presenceStanzaType == SUBSCRIBED
|| presenceStanzaType == UNSUBSCRIBE || presenceStanzaType == UNSUBSCRIBED
|| presenceStanzaType == UNAVAILABLE || presenceStanzaType == ERROR) {
return; // silently ignore
}
// TODO what happens with PROBE? 8.1 is silent here, but see 4.3
if (presenceStanzaType == SUBSCRIBE) {
// return UNSUBSCRIBED
final Entity from = failedToDeliverStanza.getTo(); // reverse from/to
final Entity to = failedToDeliverStanza.getFrom(); // reverse from/to
StanzaBuilder builder = StanzaBuilder.createPresenceStanza(from, to, null, UNSUBSCRIBED, null,
null);
final Stanza finalStanza = builder.build();
stanzaBroker.write(to, finalStanza, IgnoreFailureStrategy.INSTANCE);
return;
}
}
} else if (deliveryException instanceof SmartDeliveryException) {
// RFC3921bis#10.4.3: return remote server error to sender
SmartDeliveryException smartDeliveryException = (SmartDeliveryException) deliveryException;
XMPPCoreStanza error = XMPPCoreStanza.getWrapper(
ServerErrorResponses.getStanzaError(smartDeliveryException.getStanzaErrorCondition(),
failedCoreStanza, smartDeliveryException.getStanzaErrorType(),
smartDeliveryException.getErrorText(), "en", null));
stanzaBroker.write(error.getTo(), error, IgnoreFailureStrategy.INSTANCE);
}
} else if (deliveryExceptions.size() > 1) {
throw new RuntimeException("cannot return to sender for multiple failed deliveries");
}
}