Skip to content

Instantly share code, notes, and snippets.

@bvanderveen
Created December 19, 2010 05:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bvanderveen/747129 to your computer and use it in GitHub Desktop.
Save bvanderveen/747129 to your computer and use it in GitHub Desktop.
An IApplication which transforms requests/responses to/from a wrapped IApplication
// this snippet assumes the IAsyncResult implementation provided here:
// http://msdn.microsoft.com/en-us/magazine/cc163467.aspx
using System;
using Owin;
namespace TransformMiddleware
{
// Defines a tranformation of an HTTP context.
public interface IHttpTransform
{
// Transforms a request
IAsyncResult BeginTransformRequest(IRequest request, AsyncCallback callback, object state);
IRequest EndTransformRequest(IAsyncResult asyncResult);
// Transforms a response. Request is provided for context. Note that IApplication is not provided since it has no context.
IAsyncResult BeginTransformResponse(IRequest request, IResponse response, AsyncCallback callback, object state);
IResponse EndTransformResponse(IAsyncResult asyncResult);
}
// A middleware which uses IHttpTransform to transform requests and responses to and from a wrapped application.
public class TransformMiddleware : IApplication
{
IApplication wrap;
IHttpTransform transform;
public TransformMiddleware(IApplication wrap, IHttpTransform transform)
{
this.wrap = wrap;
this.transform = transform;
}
public IAsyncResult BeginInvoke(IRequest request, AsyncCallback callback, object state)
{
var asyncResult = new AsyncResult<IResponse>(callback, state);
// 1. perform the request transform to obtain a new request.
transform.BeginTransformRequest(request, iasr =>
{
IRequest transformedRequest = null;
Exception transformRequestException = null;
try
{
transformedRequest = transform.EndTransformRequest(iasr);
}
catch (Exception e)
{
transformRequestException = e;
}
// if an error occurred, propagate it to our caller
if (transformRequestException != null)
asyncResult.SetAsCompleted(transformRequestException, iasr.CompletedSynchronously);
else
{
// 2. provide the transformed request to the wrapped application, obtain the response.
wrap.BeginInvoke(transformedRequest, iasr2 =>
{
IResponse response = null;
Exception invokeException = null;
try
{
response = wrap.EndInvoke(iasr2);
}
catch (Exception e)
{
invokeException = e;
}
// again, if an error occurred, propagate it back to the original caller.
if (invokeException != null)
asyncResult.SetAsCompleted(invokeException, iasr2.CompletedSynchronously);
else
{
// 3. transform the response.
transform.BeginTransformResponse(transformedRequest, response, iasr3 =>
{
IResponse transformedResponse = null;
Exception transformResponseException = null;
try
{
transformedResponse = transform.EndTransformResponse(iasr3);
}
catch (Exception e)
{
transformResponseException = e;
}
// propagate the error if any.
if (transformResponseException != null)
asyncResult.SetAsCompleted(transformResponseException, iasr3.CompletedSynchronously);
else
// 4. return the transformed response to the caller.
asyncResult.SetAsCompleted(transformedResponse, iasr3.CompletedSynchronously);
}, null);
}
}, null);
}
}, null);
return asyncResult;
}
public IResponse EndInvoke(IAsyncResult result)
{
// takes care of waiting, throwing exceptions, etc.
return ((AsyncResult<IResponse>)result).EndInvoke();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment