Skip to content

Instantly share code, notes, and snippets.

@trailmax
Created February 22, 2014 23:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trailmax/9163794 to your computer and use it in GitHub Desktop.
Save trailmax/9163794 to your computer and use it in GitHub Desktop.
Unit tests for EnforceHttpsHandler
using System.Net;
using System.Net.Http;
using System.Web;
using Moq;
using NUnit.Framework;
using MyApp.Tests.Stubs;
using MyApp.Web.Api.Infrastructure;
namespace MyApp.Tests.Web.Api.Infrastructure
{
public class EnforceHttpsHandlerTests
{
[Test]
public void SendAsync_NonSecureConnection_ForbiddenReturned()
{
//Arrange
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://Somesite.com");
var sut = new EnforceHttpsHandler();
var client = new HttpClient(sut);
//Act
var result = client.SendAsync(httpRequestMessage).Result;
// Assert
Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.Forbidden));
}
[Test]
public void SendAsync_SecureConnection_OkReturned()
{
//Arrange
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://somesite.com");
var sut = new EnforceHttpsHandler()
{
InnerHandler = new StubHttpHandler()
};
var client = new HttpClient(sut);
//Act
var result = client.SendAsync(httpRequestMessage).Result;
// Assert
Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.OK));
}
[Test]
public void SendAsync_LocalRequestNonSecure_ReturnsOk()
{
//Arrange
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://local.dev");
var request = new Mock<HttpRequestBase>();
request.Setup(r => r.IsLocal).Returns(true);
var contextBase = new Mock<HttpContextBase>();
contextBase.Setup(c => c.Request).Returns(request.Object);
httpRequestMessage.Properties.Add("MS_HttpContext", contextBase.Object);
var sut = new EnforceHttpsHandler() { InnerHandler = new StubHttpHandler() };
var client = new HttpClient(sut);
//Act
var result = client.SendAsync(httpRequestMessage).Result;
// Assert
Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.OK));
}
[Test]
public void SendAsync_NonLocalRequestNonSecure_ReturnsForbidden()
{
//Arrange
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://local.dev");
var request = new Mock<HttpRequestBase>();
request.Setup(r => r.IsLocal).Returns(false);
var contextBase = new Mock<HttpContextBase>();
contextBase.Setup(c => c.Request).Returns(request.Object);
httpRequestMessage.Properties.Add("MS_HttpContext", contextBase.Object);
var sut = new EnforceHttpsHandler() { InnerHandler = new StubHttpHandler() };
var client = new HttpClient(sut);
//Act
var result = client.SendAsync(httpRequestMessage).Result;
// Assert
Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.Forbidden));
}
}
}
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
namespace MyApp.Web.Api.Infrastructure
{
public class EnforceHttpsHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// if request is local, just serve it without https
object httpContextBaseObject;
if (request.Properties.TryGetValue("MS_HttpContext", out httpContextBaseObject))
{
var httpContextBase = httpContextBaseObject as HttpContextBase;
if (httpContextBase != null && httpContextBase.Request.IsLocal)
{
return base.SendAsync(request, cancellationToken);
}
}
// if request is remote, enforce https
if (request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
return Task<HttpResponseMessage>.Factory.StartNew(
() =>
{
var response = new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("HTTPS Required")
};
return response;
});
}
return base.SendAsync(request, cancellationToken);
}
}
}
public class StubHttpHandler : DelegatingHandler
{
private readonly Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> handlerFunc;
public StubHttpHandler()
{
handlerFunc = (r, c) => Return200();
}
public StubHttpHandler(Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> handlerFunc)
{
this.handlerFunc = handlerFunc;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return handlerFunc(request, cancellationToken);
}
public static Task<HttpResponseMessage> Return200()
{
return Task.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.OK));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment