Based on my researches, I found a hacky way to achieve caching.
In your VPP implementation, you should be implementing your own VirtualFile
class, extending System.Web.Hosting.VirtualFile
base class. It just expects a stream to read file if it is needed from VPP. At that phase, you can inject headers and even change cachability of resource. Because priorly, if I request a static file from VPP, it was coming with a header Cache-Control:private
. Actually, server was saying that: I do not care your local caches, etags and so on. I decide whether you should cache it or not. The code below changes it to public
and add required e-tag header so that it should stay at cache unless that assembly is changed:

class EmbeddedResourceVirtualFile : VirtualFile
{
readonly EmbeddedResource embedded;
public EmbeddedResourceVirtualFile(string virtualPath, EmbeddedResource embedded)
: base(virtualPath)
{
this.embedded = embedded;
}
public override Stream Open()
{
var assemblyLastModified = embedded.AssemblyLastModified;
var etag = assemblyLastModified.Ticks;
var response = HttpContext.Current.Response;
var cache = response.Cache;
cache.SetCacheability(HttpCacheability.Public);
cache.SetETag(etag.ToString());
cache.SetLastModified(assemblyLastModified);
cache.SetExpires(assemblyLastModified.AddYears(2));
return embedded.GetStream();
}
}
Special thanks for the commentor :)