Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use OWIN middleware to rewrite versioned url for request to static file?

e.g. I have a file located on the server at /Content/static/home.html. I want to be able to make a request to /Content/v/1.0.0.0/static/home.html (for versioning), and have it rewrite the url so it accesses the file at the correct url, using OWIN middleware.

I am currently using the URL rewrite module (an IIS extension), but I want to make this work in the OWIN pipeline instead.

like image 492
Ben Wilde Avatar asked Jul 07 '14 20:07

Ben Wilde


3 Answers

I found a solution using the Microsoft.Owin.StaticFiles nuget package:

First make sure this is in your web config so that static file requests are sent to OWIN:

<system.webServer>
    ...
    <modules runAllManagedModulesForAllRequests="true"></modules>
    ...
</system.webServer>

Then in your Startup Configuration method, add this code:

// app is your IAppBuilder
app.Use(typeof(MiddlewareUrlRewriter));
app.UseStaticFiles();
app.UseStageMarker(PipelineStage.MapHandler);

And here is the MiddlewareUrlRewriter:

public class MiddlewareUrlRewriter : OwinMiddleware
{
    private static readonly PathString ContentVersioningUrlSegments = PathString.FromUriComponent("/content/v");

    public MiddlewareUrlRewriter(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        PathString remainingPath;
        if (context.Request.Path.StartsWithSegments(ContentVersioningUrlSegments, out remainingPath) && remainingPath.HasValue && remainingPath.Value.Length > 1)
        {
            context.Request.Path = new PathString("/Content" + remainingPath.Value.Substring(remainingPath.Value.IndexOf('/', 1)));
        }

        await Next.Invoke(context);
    }
}

For an example, this will allow a GET request to /Content/v/1.0.0.0/static/home.html to retrieve the file at /Content/static/home.html.

UPDATE: Added app.UseStageMarker(PipelineStage.MapHandler); after the other app.Use methods as it is required to make this work. http://katanaproject.codeplex.com/wikipage?title=Static%20Files%20on%20IIS

like image 130
Ben Wilde Avatar answered Sep 19 '22 01:09

Ben Wilde


Theoretically you can do this using UseStaticFiles with options instead of a separate UrlRewriter middleware:

string root = AppDomain.CurrentDomain.BaseDirectory;
var staticFilesOptions = new StaticFileOptions();
staticFilesOptions.RequestPath = new PathString("/foo");
staticFilesOptions.FileSystem = 
          new PhysicalFileSystem(Path.Combine(root, "web"));
app.UseStaticFiles(staticFilesOptions);

But see this question as it doesn't currently seem to work.

like image 35
Ian Mercer Avatar answered Sep 18 '22 01:09

Ian Mercer


There is now an Owin.UrlRewrite project in here : https://github.com/gertjvr/owin.urlrewrite

It is syntactically based on Apache mod_rewrite.

like image 26
Jani Hyytiäinen Avatar answered Sep 21 '22 01:09

Jani Hyytiäinen