Skip to content
Merged
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
115 changes: 115 additions & 0 deletions src/SoapCore.Tests/XDocumentXmlReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
@$"<?xml version=""1.0"" encoding=""UTF-8""?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:SOAP-ENC=""http://schemas.xmlsoap.org/soap/encoding/""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
xmlns:tal-server=""urn:tal_server""
xmlns:tal-client=""urn:tal_client""
xmlns:tal=""urn:tal"">
<SOAP-ENV:Body>
<tal-server:request>
<request xsi:type=""tal:CreateSession"">
<sessionId></sessionId>
<requestId>2982441</requestId>
<version>2.5</version>
<clientUrl>http://192.168.1.2:7000</clientUrl>
<properties>
<name>xxx</name>
<value>false</value>
</properties>
</request>
</tal-server:request>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>";

var expectedBody =
@"<SOAP-ENV:Body xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:SOAP-ENC=""http://schemas.xmlsoap.org/soap/encoding/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:tal-server=""urn:tal_server"" xmlns:tal-client=""urn:tal_client"" xmlns:tal=""urn:tal"">
<tal-server:request>
<request xsi:type=""tal:CreateSession"">
<sessionId></sessionId>
<requestId>2982441</requestId>
<version>2.5</version>
<clientUrl>http://192.168.1.2:7000</clientUrl>
<properties>
<name>xxx</name>
<value>false</value>
</properties>
</request>
</tal-server:request>
</SOAP-ENV:Body>";

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 =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Header>
<ns3:LogicalAddress xmlns:ns3=""urn:riv:itintegration:registry:1""
xmlns=""urn:riv:strategicresourcemanagement:persons:person:4""
xmlns:ns2=""urn:riv:strategicresourcemanagement:persons:person:GetPersonsForProfileResponder:4"">SOME_ADDRESS</ns3:LogicalAddress>
<Action soap:mustUnderstand=""1""
xmlns=""http://schemas.microsoft.com/ws/2005/05/addressing/none"">urn:riv:strategicresourcemanagement:persons:person:GetPersonsForProfileResponder:4:GetPersonsForProfile</Action>
</soap:Header>
<soap:Body>
<ns2:GetPersonsForProfile xmlns:ns2=""urn:riv:strategicresourcemanagement:persons:person:GetPersonsForProfileResponder:4""
xmlns=""urn:riv:strategicresourcemanagement:persons:person:4""
xmlns:ns3=""urn:riv:itintegration:registry:1"">
<ns2:personId>
<root>SOME_ROOT</root>
<extension>SOME_EXTENSION</extension>
</ns2:personId>
<ns2:profile>P4</ns2:profile>
<ns2:ignoreReferredIdentity>true</ns2:ignoreReferredIdentity>
</ns2:GetPersonsForProfile>
</soap:Body>
</soap:Envelope>";
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<string>(0);
Assert.AreEqual("SOME_ADDRESS", header);
}

[TestMethod]
public async Task TestRequestToIneraPuService()
{
var request =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
<s:Header>
<LogicalAddress ns3=""urn:riv:itintegration:registry:1"" ns2=""urn:riv:strategicresourcemanagement:persons:person:GetPersonsForProfileResponder:4""
xmlns=""urn:riv:itintegration:registry:1"">SOME_ADDRESS</LogicalAddress>
<Action s:mustUnderstand=""1""
xmlns=""http://schemas.microsoft.com/ws/2005/05/addressing/none"">GetPersonsForProfile</Action>
</s:Header>
<s:Body>
<ns2:GetPersonsForProfile xmlns:ns2=""urn:riv:strategicresourcemanagement:persons:person:GetPersonsForProfileResponder:4""
xmlns=""urn:riv:strategicresourcemanagement:persons:person:4""
xmlns:ns3=""urn:riv:itintegration:registry:1"">
<ns2:personId>
<root>SOME_ROOT</root>
<extension>SOME_EXTENSION</extension>
</ns2:personId>
<ns2:profile>P4</ns2:profile>
<ns2:ignoreReferredIdentity>true</ns2:ignoreReferredIdentity>
</ns2:GetPersonsForProfile>
</s:Body>
</s:Envelope>";
ParsedMessage pm = await ParsedMessage.FromStreamAsync(new MemoryStream(Encoding.Default.GetBytes(request)), Encoding.Default, MessageVersion.Soap11, CancellationToken.None);
var header = pm.Headers.GetHeader<string>(0);
Assert.AreEqual("SOME_ADDRESS", header);
}
}
}
5 changes: 5 additions & 0 deletions src/SoapCore/ParsedMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
11 changes: 11 additions & 0 deletions src/SoapCore/ParsedMessageHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Loading