Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.Collection;

import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.EndpointReference;
Expand Down Expand Up @@ -83,8 +84,10 @@ protected InvocationResponse doProcessing(final IMessageProcessingContext procCt
else {
// This is a multi-hop message, set the multi-hop target on the eb:Messaging element
log.debug("Primary message is a multi-hop UserMessage -> set multi-hop target");
final SOAPHeaderBlock ebHeader = Messaging.getElement(procCtx.getParentContext().getEnvelope());
ebHeader.setRole(MultiHopConstants.NEXT_MSH_TARGET);
final SOAPEnvelope envelope = procCtx.getParentContext().getEnvelope();
final SOAPHeaderBlock ebHeader = Messaging.getElement(envelope);
final String roleAttr = envelope.getVersion().getRoleAttributeQName().getLocalPart();
ebHeader.addAttribute(roleAttr, MultiHopConstants.NEXT_MSH_TARGET, envelope.getNamespace());
}
} else if (primMU instanceof IPullRequest) {
// If the primary message unit is a PullRequest the message is not sent using multi-hop as this is not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import javax.xml.namespace.QName;

import org.apache.axiom.soap.SOAPConstants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.holodeckb2b.interfaces.general.EbMSConstants;
Expand Down Expand Up @@ -52,8 +53,16 @@ public static SOAPHeaderBlock createElement(final org.apache.axiom.soap.SOAPEnve
// No existing messaging element, so create a new one
messaging = env.getHeader().addHeaderBlock(Q_ELEMENT_NAME.getLocalPart(), SOAPEnv.getEbms3Namespace(env));

// The messaging header must be understood by the MSH (see 5.2.1 core spec)
messaging.setMustUnderstand(true);
/*
* The mustUnderstand attribute is explicitly added here because setting
* the mustUnderstand flag on the object results in a redundant namespace
* declaration and prefix, e.g. xmlns:mustUnderstand="...."
* mustUnderstand:mustUnderstand="true"
* Although this isn't incorrect, this additional declaration can confuse
* other SOAP processors when performing c14n.
*/
messaging.addAttribute(SOAPConstants.ATTR_MUSTUNDERSTAND,
SOAPConstants.ATTR_MUSTUNDERSTAND_TRUE, env.getNamespace());
}

return messaging;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
package org.holodeckb2b.ebms3.packaging;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

import org.apache.axiom.soap.SOAPConstants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.holodeckb2b.as4.multihop.MultiHopConstants;
import org.holodeckb2b.interfaces.general.EbMSConstants;
import org.junit.Test;

Expand Down Expand Up @@ -65,4 +69,39 @@ public void testGetElement() throws Exception {
assertEquals(soapHeaderBlock.getVersion(),
newSoapHeaderBlock.getVersion());
}

@Test
public void testMustUnderstandSerializesCleanly() throws Exception {
SOAPEnvelope env = SOAPEnv.createEnvelope(SOAPEnv.SOAPVersion.SOAP_12);
Messaging.createElement(env);

assertNoRedundantNamespace(env, SOAPConstants.ATTR_MUSTUNDERSTAND);
}

@Test
public void testRoleAttributeSerializesCleanly() throws Exception {
SOAPEnvelope env = SOAPEnv.createEnvelope(SOAPEnv.SOAPVersion.SOAP_12);
SOAPHeaderBlock messaging = Messaging.createElement(env);

String roleAttr = env.getVersion().getRoleAttributeQName().getLocalPart();
messaging.addAttribute(roleAttr, MultiHopConstants.NEXT_MSH_TARGET, env.getNamespace());

assertNoRedundantNamespace(env, roleAttr);
}

private static String serializeToString(SOAPEnvelope env) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
env.serialize(baos);
return baos.toString("UTF-8");
}

private static void assertNoRedundantNamespace(SOAPEnvelope env, String attrName) throws Exception {
String xml = serializeToString(env);
assertFalse("Redundant namespace declaration 'xmlns:" + attrName + "=' breaks c14n"
+ " interoperability.\nActual XML:\n" + xml,
xml.contains("xmlns:" + attrName + "="));
assertFalse("Wrongly-prefixed attribute '" + attrName + ":" + attrName + "=' breaks c14n"
+ " interoperability.\nActual XML:\n" + xml,
xml.contains(attrName + ":" + attrName + "="));
}
}