2

I have an CustomHttp module in my application to remove the unwanted response headers as below.

 public class RemoveServerHeadersModule : IHttpModule
        {
            public void Init(HttpApplication context)
            {
                context.PreSendRequestHeaders += OnPreSendRequestHeaders;
            }

            public void Dispose() { }

            public void OnPreSendRequestHeaders(object sender, EventArgs e)
            {
                HttpContext.Current.Response.Headers.Remove("X-Powered-By");
                HttpContext.Current.Response.Headers.Remove("X-AspNet-Version");
                HttpContext.Current.Response.Headers.Remove("X-AspNetMvc-Version");
                HttpContext.Current.Response.Headers.Remove("Server");
            }
        }

I need to write unit test for this .

Tried few like below but unable to do that , getting error.

 HttpRequest httpRequest = new HttpRequest("", "", "");
 StringWriter stringWriter = new StringWriter();
 HttpResponse httpResponse = new HttpResponse(stringWriter);
 HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse);

 var application = new Mock<HttpApplication>();
 application.Setup(ct => ct.Context).Returns(httpContextMock);

 var module = new RemoveServerHeadersModule();
 HttpApplication httpApplication = new HttpApplication();
 module.Init(httpApplication);
 module.OnPreSendRequestHeaders(httpApplication, EventArgs.Empty);

Getting error when trying to set the Context in HttpApplication. Please could you help me out

Das
  • 59
  • 1
  • 9

1 Answers1

2

Per guidance by Microsoft you shouldn't be using the OnPreSendRequestHeaders event

You can use the PreSendRequestHeaders and PreSendRequestContext events with native IIS modules, but do not use them with managed modules that implement IHttpModule. Setting these properties can cause issues with asynchronous requests.

If you can move to a different event, you can then use the techniques shown here

Which links to this old article

where you create a BaseHttpModule to then create events where you can pass the context into the handler

public abstract class BaseHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, e) => OnBeginRequest(new HttpContextWrapper(((HttpApplication) sender).Context));
        context.Error += (sender, e) => OnError(new HttpContextWrapper(((HttpApplication) sender).Context));
        context.EndRequest += (sender, e) => OnEndRequest(new HttpContextWrapper(((HttpApplication) sender).Context));
    }

    public void Dispose()
    {
    }

    public virtual void OnBeginRequest(HttpContextBase context)
    {
    }

    public virtual void OnError(HttpContextBase context)
    {
    }

    public virtual void OnEndRequest(HttpContextBase context)
    {
    }
}

Then your class becomes

public class RemoveServerHeadersModule : BaseHttpModule
{
    public override void OnBeginRequest(HttpContextBase context)
    {
        context.Response.Headers.Remove("X-Powered-By");
        context.Response.Headers.Remove("X-AspNet-Version");
        context.Response.Headers.Remove("X-AspNetMvc-Version");
        context.Response.Headers.Remove("Server");
    }
}

and your test is something like

        var fakeContext = A.Fake<HttpContextBase>();
        var fakeRequest = A.Fake<HttpRequestBase>();
        var fakeResponse = A.Fake<HttpResponseBase>();

        A.CallTo(() => fakeResponse.Headers).Returns( /*put your headers here*/);

        A.CallTo(() => fakeContext.Response).Returns(fakeResponse);
        A.CallTo(() => fakeContext.Request).Returns(fakeRequest);

        var _sut = new RemoveServerHeadersModule();
        _sut.OnBeginRequest(fakeContext);

        //your header checks.
Eonasdan
  • 7,563
  • 8
  • 55
  • 82
Fran
  • 6,440
  • 1
  • 23
  • 35
  • The OP is using an `HttpModule`, not a `Controller`. – NightOwl888 Oct 13 '17 at 19:15
  • Thank you so much for your response. Have one query..Do i need to attach other events(OnError, OnEndRequest) apart from OnBeginRequest since iam using OnBeginRequest only in RemoveServerHeadersModule. Please let me know – Das Oct 14 '17 at 05:08
  • you shouldn't have to implement the other even handlers unless you are going to use them – Fran Oct 15 '17 at 19:41
  • After modifying the event from OnPreSendRequestHeaders to OnBeginRequest only the "Server" key is getting removed from the header.While debugging the web api response i could see only "Server" key is present in the response.Please suggest how to modify to get all server headers in the web api response. – Das Oct 16 '17 at 05:28
  • if all you really need to do is to remove those asp.net headers, you can do it with the web.config without ever writing a custom handler. https://stackoverflow.com/questions/4078756/how-to-delete-iis-custom-headers-like-x-powered-by-asp-net-from-response – Fran Oct 16 '17 at 13:29