I have a list of IP’s that keep crawling our live site which throw exceptions when they use certain URL’s with no parameters (because of the MVC routing). I want to block those IP addresses and return a 404 not found page as soon as they can be picked up, but I don’t want to do it in IIS as I want to log the encounters within our application.
I’ve written a catch-all type routehandler that uses a custom MvcHandler to check the list and modify the response:
public class ApplicationRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
BlacklistedIPAddressHandler handler = new BlacklistedIPAddressHandler(Cache.WebsiteCache.GetBlacklistedIPList(), requestContext);
return handler;
}
}
public class BlacklistedIPAddressHandler : MvcHandler
{
List<IPBlacklistModel> blacklist;
public BlacklistedIPAddressHandler(List<IPBlacklistModel> Blacklist, RequestContext requestContext) : base(requestContext)
{
blacklist = Blacklist;
}
protected override IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state)
{
var ip = httpContext.Request.UserHostAddress;
if (blacklist != null &&
blacklist.Where(x => x.IP_ADDRESS.Contains(ip)).Count() > 0)
{
httpContext.Response.ClearHeaders();
httpContext.Response.Clear();
httpContext.Response.StatusCode = 404;
httpContext.Response.SuppressContent = true;
httpContext.Response.End();
}
return base.BeginProcessRequest(httpContext, callback, state);
}
}
It’s then implemented as follows:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = @"[^\.]*" }
).RouteHandler = new Helpers.Routing.ApplicationRouteHandler();
}
I keep getting a Server cannot append header after HTTP headers have been sent error when I do this. Anybody perhaps know why?
I suppose you should remove
httpContext.Response.End();statement from your handler – as the request is passed for further processing, it should not be terminated now.HttpResponse.Endmethod description from MSDN: