Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add IP address to HttpRequestMessage

How do I add an IP address to a HttpRequestMessage?

I am writing unit tests for a Web.API application, I have an AuthorizeAttribute that checks the callers IP address -

        string[] AllowedIPs = new string[] { "127.0.0.1",  "::1" }
        string sourceIP = "";

        var contextBase = actionContext.Request.Properties["MS_HttpContext"] as System.Web.HttpContextBase;

        if (contextBase != null)
        {
            sourceIP = contextBase.Request.UserHostAddress;
        }

        if (!string.IsNullOrEmpty(sourceIP))
        {
            return AllowedIPs.Any(a => a == sourceIP);
        }
        return false;

I construct a test request as follows -

    var request = CreateRequest("http://myserver/api/CustomerController, "application/json", HttpMethod.Get);            
    HttpResponseMessage response = client.SendAsync(request).Result;

. .

    private HttpRequestMessage CreateRequest(string url, string mthv, HttpMethod method)
    {
        var request = new HttpRequestMessage();
        request.RequestUri = new Uri(url);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(mthv));
        request.Method = method;
        return request;
    } 

BUT actionContext.Request.Properties["MS_HttpContext"] is null and I cannot perform the test.

SOLUTION BELOW - see my own answer.

like image 448
tom Avatar asked Mar 03 '13 18:03

tom


2 Answers

Thanks to Davin for his suggestion.

Here is the solution -

private HttpRequestMessage CreateRequest(string url, string mthv, HttpMethod method)
{
    var request = new HttpRequestMessage();

    var baseRequest = new Mock<HttpRequestBase>(MockBehavior.Strict);
    var baseContext = new Mock<HttpContextBase>(MockBehavior.Strict);

    baseRequest.Setup(br => br.UserHostAddress).Returns("127.0.0.1");
    baseContext.Setup(bc => bc.Request).Returns(baseRequest.Object);


    request.RequestUri = new Uri(url);
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(mthv));

    request.Properties.Add("MS_HttpContext", baseContext.Object);

    request.Method = method;
    return request;
} 

Then use that method in the following way -

 var request = CreateRequest("http://myserver/api/CustomerController, "application/json", HttpMethod.Get);            
 HttpResponseMessage response = client.SendAsync(request).Result;
like image 153
tom Avatar answered Sep 21 '22 10:09

tom


It seems you are attempting to get the IP address from the host myserver which in this case will not be resolved by anything. This leaves the property MS_HttpContext null.

I would suggest a different approach. First, mock System.Web.HttpContextBase and set up return values for Request.UserHostAddress, then, in your test setup, set the property directly:

private HttpRequestMessage CreateRequest(string url, string mthv, HttpMethod method)
    {
        var request = new HttpRequestMessage();
        request.RequestUri = new Uri(url);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(mthv));
        request.Method = method;
        request.Property["MS_HttpContext"] = mockedHttpContextBase //here
        return request;
    } 
like image 30
Davin Tryon Avatar answered Sep 19 '22 10:09

Davin Tryon