Skip to content

Commit 7b12abc

Browse files
committed
Add support for requests with body
HttpDisassembler currently assumes that no message body exists when the message is received. This is fine for HTTP GET but will not work for PUT and PATCH that often contains both uri parameters and a body. Added functionality in HttpDisassembler to determine if the incomming message has a body and if that is the case, create a new message part with the uri parameters.
1 parent 9c94583 commit 7b12abc

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

Src/HttpDisassembler/BizTalkComponents.PipelineComponents.HttpDisassembler.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
<SpecificVersion>False</SpecificVersion>
4444
<HintPath>..\..\..\..\..\Windows\assembly\GAC_MSIL\Microsoft.BizTalk.Pipeline\3.0.1.0__31bf3856ad364e35\Microsoft.BizTalk.Pipeline.dll</HintPath>
4545
</Reference>
46+
<Reference Include="Microsoft.BizTalk.Streaming, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
47+
<SpecificVersion>False</SpecificVersion>
48+
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Microsoft BizTalk Server 2013\Microsoft.BizTalk.Streaming.dll</HintPath>
49+
</Reference>
4650
<Reference Include="Microsoft.XLANGs.RuntimeTypes, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
4751
<Reference Include="System" />
4852
<Reference Include="System.ComponentModel.DataAnnotations" />

Src/HttpDisassembler/HttpDisassembler.cs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.BizTalk.Message.Interop;
1010
using Microsoft.XLANGs.RuntimeTypes;
1111
using BizTalkComponents.Utils;
12+
using Microsoft.BizTalk.Streaming;
1213

1314
namespace BizTalkComponents.PipelineComponents.HttpDisassembler
1415
{
@@ -34,6 +35,11 @@ public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
3435
throw new ArgumentException(errorMessage);
3536
}
3637

38+
var data = pInMsg.BodyPart.GetOriginalDataStream();
39+
40+
//Determine of the request body has any data. GET request will not have any body.
41+
var hasData = HasData(data);
42+
3743
//Get a reference to the BizTalk schema.
3844
var documentSpec = (DocumentSpec)pContext.GetDocumentSpecByName(DocumentSpecName);
3945

@@ -64,14 +70,28 @@ public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
6470
ms.Seek(0, SeekOrigin.Begin);
6571

6672
var outMsg = pInMsg;
67-
outMsg.BodyPart.Data = ms;
6873

69-
//Promote message type and SchemaStrongName
70-
outMsg.Context.Promote(new ContextProperty(SystemProperties.MessageType), documentSpec.DocType);
71-
outMsg.Context.Promote(new ContextProperty(SystemProperties.SchemaStrongName), documentSpec.DocSpecStrongName);
74+
//If the request has a body it should be preserved an the query parameters should be written to it's own message part.
75+
if (hasData)
76+
{
77+
outMsg = pInMsg;
78+
outMsg.BodyPart.Data = pInMsg.BodyPart.Data;
79+
outMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context);
80+
var factory = pContext.GetMessageFactory();
81+
var queryPart = factory.CreateMessagePart();
82+
queryPart.Data = ms;
83+
84+
outMsg.AddPart("querypart", queryPart, false);
85+
}
86+
else
87+
{
88+
outMsg.BodyPart.Data = ms;
89+
//Promote message type and SchemaStrongName
90+
outMsg.Context.Promote(new ContextProperty(SystemProperties.MessageType), documentSpec.DocType);
91+
outMsg.Context.Promote(new ContextProperty(SystemProperties.SchemaStrongName), documentSpec.DocSpecStrongName);
92+
}
7293

7394
_outputQueue.Enqueue(outMsg);
74-
7595
}
7696

7797
public void Load(IPropertyBag propertyBag, int errorLog)
@@ -93,5 +113,23 @@ public IBaseMessage GetNext(IPipelineContext pContext)
93113

94114
return null;
95115
}
116+
117+
private bool HasData(Stream data)
118+
{
119+
byte[] buffer= new byte[10];
120+
const int bufferSize = 0x280;
121+
const int thresholdSize = 0x100000;
122+
123+
if (!data.CanSeek || !data.CanRead)
124+
{
125+
data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize);
126+
}
127+
128+
int num = data.Read(buffer, 0, buffer.Length);
129+
data.Seek(0, SeekOrigin.Begin);
130+
data.Position = 0;
131+
132+
return num > 0;
133+
}
96134
}
97135
}

0 commit comments

Comments
 (0)