Here is the my final solution after the leads from other answers here. I use the media:request event along with the lesser known AddOnSendingHeaders method on Request object that basically gives me a final chance to change headers before IIS sends the request to the client.
public class ChangeFileName
{
public void OnMediaRequest(object sender, EventArgs args)
{
SitecoreEventArgs eventArgs = args as SitecoreEventArgs;
MediaRequest mediaRequest = eventArgs?.Parameters?[0] as MediaRequest;
if (mediaRequest == null)
{
return;
}
MediaItem mediaItem = MediaManager.GetMedia(mediaRequest.MediaUri).MediaData.MediaItem;
if(mediaItem == null)
{
return;
}
HttpRequest request = mediaRequest.InnerRequest;
request.RequestContext.HttpContext.Response.AddOnSendingHeaders(context =>
{
if (CheckFileType(mediaItem))
context.Response.Headers["Content-Disposition"] = FixFileName(context.Response.Headers["Content-Disposition"]));
});
}
}
Then of course, I had to add the event handler to the config:
<event name="media:request">
<handler type="MyAssembly.ChangeFileName, MyAssembly" method="OnMediaRequest"/>
</event>