I serve a bunch of static files in my app with app.UseStaticFiles()
. I'd like to inject some additional markup into the response for a particular HTML file before it's sent. My first attempt was to add middleware like this before the static files middleware:
app.Use(async (context, next) => {
await next();
// Modify the response here
});
However, this doesn't work as I can't actually read the read the response stream - it's using Kestrel's FrameResponseStream
under the hood, which is unreadable.
So, I figured I could replace the response body stream with a MemoryStream
that I could write to:
app.Use(async (context, next) => {
context.Response.Body = new MemoryStream();
await next();
// Modify the response here
});
But this just causes the request to never complete - it goes through all the pipeline stages, but it never even returns any headers to the browser.
So, is there any way I can modify the response that is produced by the StaticFileMiddleware
?
Update
As the HTML file in question is tiny (765 bytes), memory consumption isn't a concern. However, any attempts to read/modify the response still causes the same problem as before (nothing is returned). More explicitly, here's what's being done:
app.Use(async (context, next) => {
var originalStream = context.Response.Body;
var bufferStream = new MemoryStream();
context.Response.Body = bufferStream;
await next();
bufferStream.Seek(0, SeekOrigin.Begin);
if (/* some condition */)
{
var reader = new StreamReader(bufferStream);
var response = await reader.ReadToEndAsync();
// The response string is modified here
var writer = new StreamWriter(originalStream);
await writer.WriteAsync(response);
}
else
{
await bufferStream.CopyToAsync(originalStream);
}
});
The files hitting the else
condition are returned just fine, but the particular file in the if
condition causes trouble. Even if I don't modify the stream at all, it still hangs.