andrewm
andrewm

Reputation: 2642

Detect static file request from .NET core middleware

I'm writing some middleware to parse the sub-domain of a given request URL to determine the website theme. I want to ignore static file requests in order to reduce unnecessary database lookups, and I'm wondering if there's a cleaner way to do it.

This is what I've tried so far:

var staticFileExtensions = new List<string> { ".css", ".js", ".png", ".ico" };
if (staticFileExtensions.Any(x => httpContext.Request.Path.Value.EndsWith(x)))
{
    await _next(httpContext);
}
else
{
    var hostParts = httpContext.Request.Host.Host.Split('.').ToList();
    if (httpContext.Request.Path.StartsWithSegments(new PathString("/healthcheck"))
    || (hostParts.Count == 6 && _whitelistedDomains.Contains(hostParts[0])))
    {
        httpContext.Items.Add("account", hostParts[0]);
        await _next(httpContext);
    }
    else
    {
        httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
    }
}

This is where I've added it to Startup.cs:

app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseDomainWhitelisting();

It feels as though there should be a cleaner way to detect which requests to ignore, or maybe I'm missing something?

Upvotes: 12

Views: 3628

Answers (4)

Arturbc
Arturbc

Reputation: 49

Maybe check if httpContext.GetEndpoint() is null or not.

Under tests yet in my projects, but looks good.

Upvotes: 0

Alex from Jitbit
Alex from Jitbit

Reputation: 60566

You don't need to.

Any middleware that is registered AFTER the call to UseStaticFiles will not execute, if the request ended up serving a static file.

I just verified this behavior on .NET 6 and 7 under both IIS and Kestrel hosting on both Windows and Linux.

That's probably because the static-files middleware never calls _next(context) delegate, thus aborting the whole pipeline. This is called terminal middleware because it short circuits a request. I wish MS docs mentioned it somewhere, but we can always look at the source codes...

Aaaah-nd yep, just as I thought, source code confirms this: https://source.dot.net/#Microsoft.AspNetCore.StaticFiles/StaticFileMiddleware.cs,79

P.S. In other words, to solve the OP's problem - just make sure you call UseStaticFiles before executing your domain logic middleware. Also make sure the file actually exists. If not - the app will proceed to next middleware.

Upvotes: 9

Hasan Elsherbiny
Hasan Elsherbiny

Reputation: 628

This is quite old question but I cam to it when I had similar problem, I could solve the issue and determine static files request by checking if request is ended with extension.

if(string.IsNullOrEmpty(System.IO.Path.GetExtension(httpContext.Request.Path)))
 //this is normal request
else
 //this can be a file as it ends with some extension (ex*.png) 

Upvotes: 6

Riccardo Bassilichi
Riccardo Bassilichi

Reputation: 969

You can use conditional middleware based on request. Something like:

app.UseMiddlewareOne();

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
    appBuilder.UseMiddlewareTwo();
});

app.UseMiddlewareThree();

Source: https://www.devtrends.co.uk/blog/conditional-middleware-based-on-request-in-asp.net-core

Upvotes: 9

Related Questions