Search code examples
wcfoauthhttp-headersbiztalkfiddler

BizTalk REST call works only when Fiddler running


I have a BizTalk 2013r2 application that has a request response send port using the WCF-WebHttp adapter. The send port uses a custom WCF behaviour I've developed to attach an OAuth authorization header, details of this can be seen here. All works great when running from my Azure dev vm but I've just run for the 1st time on an on-prem BizTalk server, which is where it will need to run from when live, I've hit a problem!

By adjusting settings in the "Proxy" tab of the send port adapter's config page, I've tried scenarios:

  • Through corporate proxy - fails
  • Direct to the target web service, no proxy - fails
  • Through fiddler - works
  • To local mock service (hosted by SoapUi) - works

If the request is made through the corporate proxy or direct (a network rule has been created to allow this) then I get an EndpointNotFound exception

When running WCF trace against a failed request, I get the following "Message Log Trace":

enter image description here

Followed very shortly after by:

enter image description here

The second request seems to be the same as the first, except an Addressing element is added, complete with an empty Action element. I can see that the second is a log with source=TransportSend whereas the first has source=ServiceLevelSendRequest. Immediately following the second log I see the exception:

<ExceptionType>System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>There was no endpoint listening at https://api-sandbox.tradeshift.com/tradeshift/rest/external/documents/dispatcher/?documentId=66553703-4f22-4294-9a28-1f3ecb22fcf2&documentProfileId=tradeshift.order.1.0 that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStreamAsyncResult.CompleteGetRequestStream(IAsyncResult result)
at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStreamAsyncResult.OnGetRequestStream(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.HttpWebRequest.SetResponse(Exception E)
at System.Net.ConnectionReturnResult.SetResponses(ConnectionReturnResult returnResult)
at System.Net.Connection.CompleteConnectionWrapper(Object request, Object state)
at System.Net.PooledStream.ConnectionCallback(Object owningObject, Exception e, Socket socket, IPAddress address)
at System.Net.ServicePoint.ConnectSocketCallback(IAsyncResult asyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>

Where I make the request via Fiddler then I see the same two outbound logs, one for ServiceLevelSendRequest and one for TransportSend. I then seeTransportReceive followed by ServiceLevelReceiveReply, both containing a HttpResponse element

I'd be grateful for any advice on how to solve this so that requests can be made either via the corporate proxy or directly - insisting Fiddler runs on the live server is not really an option!


Solution

  • Had a great session this morning with a LAN engineer who was able to run a trace on the corporate proxy. We ran these tests:

    1. sent thorough fiddler - it worked, could see that fiddler was routing through corporate proxy
    2. closed fiddler, retried test - it failed but engineer could see no trace
    3. facepalm! I realised that I still had the send port proxy set to 127.0.0.1:8888 for fiddler
    4. changed the send port to use corporate proxy - it worked!

    The engineer did notice that the target ip address returning from api-sandbox.tradeshift.com did vary. So it seems that it's load balanced at their side. Our corp firewall didn't have the addresses for each of their servers so perhaps this could explain why I couldn't get BizTalk to work through our corp proxy last week.