diff --git a/src/SoapCore.Tests/XDocumentXmlReaderTests.cs b/src/SoapCore.Tests/XDocumentXmlReaderTests.cs index c34566b7..ee9dadc7 100644 --- a/src/SoapCore.Tests/XDocumentXmlReaderTests.cs +++ b/src/SoapCore.Tests/XDocumentXmlReaderTests.cs @@ -74,5 +74,120 @@ public async Task WriteTwice() pm.WriteBodyContents(dw); pm.WriteBodyContents(dw); } + + //Test for https://github.com/DigDes/SoapCore/issues/1183 + [TestMethod] + public async Task TestIssue1183() + { + var request = +@$" + + + + + + 2982441 + 2.5 + http://192.168.1.2:7000 + + xxx + false + + + + +"; + + var expectedBody = +@" + + + + 2982441 + 2.5 + http://192.168.1.2:7000 + + xxx + false + + + +"; + + ParsedMessage pm = await ParsedMessage.FromStreamAsync(new MemoryStream(Encoding.Default.GetBytes(request)), Encoding.Default, MessageVersion.Soap11, CancellationToken.None); + var parsedBody = pm.ToString(); + Assert.IsFalse(pm.IsEmpty); + Assert.AreEqual(expectedBody, parsedBody); + } + + [TestMethod] + public async Task TestIncorrectRequestToIneraPuServiceFromClientWhoShouldNotBeNamed() + { + var request = +@" + + + SOME_ADDRESS + urn:riv:strategicresourcemanagement:persons:person:GetPersonsForProfileResponder:4:GetPersonsForProfile + + + + + SOME_ROOT + SOME_EXTENSION + + P4 + true + + +"; + ParsedMessage pm = await ParsedMessage.FromStreamAsync(new MemoryStream(Encoding.Default.GetBytes(request)), Encoding.Default, MessageVersion.Soap11, CancellationToken.None); + + // This whould throw in the original implementation due to some incorrect namespaces in the request + var header = pm.Headers.GetHeader(0); + Assert.AreEqual("SOME_ADDRESS", header); + } + + [TestMethod] + public async Task TestRequestToIneraPuService() + { + var request = +@" + + + SOME_ADDRESS + GetPersonsForProfile + + + + + SOME_ROOT + SOME_EXTENSION + + P4 + true + + +"; + ParsedMessage pm = await ParsedMessage.FromStreamAsync(new MemoryStream(Encoding.Default.GetBytes(request)), Encoding.Default, MessageVersion.Soap11, CancellationToken.None); + var header = pm.Headers.GetHeader(0); + Assert.AreEqual("SOME_ADDRESS", header); + } } } diff --git a/src/SoapCore/ParsedMessage.cs b/src/SoapCore/ParsedMessage.cs index 97b72679..ba8159d7 100644 --- a/src/SoapCore/ParsedMessage.cs +++ b/src/SoapCore/ParsedMessage.cs @@ -188,6 +188,11 @@ private static (XDocument, bool isEmpty) ExtractSoapBody(XDocument envelope, Mes return (new XDocument(), true); } + var rootAttributes = root.Attributes(); + var bodyAttributes = bodyNode.Attributes(); + var allAttributes = bodyAttributes.Union(rootAttributes); + bodyNode.ReplaceAttributes(allAttributes); + //return new XDocument(bodyNode.Elements().FirstOrDefault()); return (new XDocument(bodyNode), bodyNode.IsEmpty); } diff --git a/src/SoapCore/ParsedMessageHeader.cs b/src/SoapCore/ParsedMessageHeader.cs index 8832729a..8cd5ec19 100644 --- a/src/SoapCore/ParsedMessageHeader.cs +++ b/src/SoapCore/ParsedMessageHeader.cs @@ -29,6 +29,17 @@ protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, Messag // Write custom attributes foreach (var attr in _attributes) { + // If the attribute is an xmlns declaration and its value is different + // from the header's namespace, skip it to avoid conflicts. + + // This should not really be necessary, but it is a safeguard against malformed + // SOAP messages that might include redundant or conflicting + // namespace declarations in the header + if (attr.Name.LocalName == "xmlns" && attr.Value != Namespace) + { + continue; + } + writer.WriteAttributeString(attr.Name.LocalName, attr.Value); }