Using IIS 8 we can remove the ETag header by conf但是如果我们使用kestrel或其他服务器实现怎么办?
使用ASP.Net,4我使用了global.asax的PreSendRequestHeaders事件:
protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
if (HttpContext.Current != null)
{
HttpContext.Current.Response.Headers.Remove("Server");
HttpContext.Current.Response.Headers.Remove("ETag");
}
}
我尝试使用IHttpResponseFeature的OnSendHeaders,但这并不适用于所有情况,特别是静态文件中间件
答案 0 :(得分:1)
我所做的是一个覆盖httpcontext的中间件
public class RemoveResponseHeadersMiddleware
{
readonly IEnumerable<string> _headersToRemove;
readonly RequestDelegate _next;
readonly ILoggerFactory _loggerFactory;
/// <summary>
/// Create an instance of <see cref="RemoveResponseHeadersMiddleware"/>
/// </summary>
/// <param name="next">the next <see cref="RequestDelegate"/> to call in the pipeline</param>
/// <param name="optionsAccessor">the accessor to <see cref="CommaSeparatedListOptions"/> where headers to remove are configured</param>
/// <param name="loggerFactory">the logger factory to create logger</param>
public RemoveResponseHeadersMiddleware(RequestDelegate next, IOptions<CommaSeparatedListOptions> optionsAccessor, ILoggerFactory loggerFactory)
{
if (next == null)
throw new ArgumentNullException("next");
if (optionsAccessor == null || optionsAccessor.Options == null || optionsAccessor.Options.List == null)
throw new ArgumentNullException("optionsAccessor");
if (loggerFactory == null)
throw new ArgumentNullException("loggerFactory");
_next = next;
_headersToRemove = optionsAccessor.Options.List;
_loggerFactory = loggerFactory;
}
public async Task Invoke(HttpContext context)
{
await _next.Invoke(new RemoveHeaderHttpContext(context, _headersToRemove, _loggerFactory));
}
}
在invoke方法中,我创建了一个httpcontext装饰器,覆盖了httpresponse
public class RemoveHeaderHttpContext : HttpContext
{
readonly HttpContext _parent;
readonly HttpResponse _response;
/// <summary>
/// Create instance of <see cref="RemoveHeaderHttpContext"/>
/// </summary>
/// <param name="parent">the <see cref="HttpContext"/> to decorate/></param>
/// <param name="headersToRemove">a list of unwanted header</param>
/// <param name="loggerFactory">the logger factory to create logger</param>
public RemoveHeaderHttpContext(HttpContext parent, IEnumerable<string> headersToRemove, ILoggerFactory loggerFactory)
{
if (parent == null)
throw new ArgumentNullException("parent");
if (headersToRemove == null)
throw new ArgumentNullException("headersToRemove");
if (loggerFactory == null)
throw new ArgumentNullException("loggerFactory");
_parent = parent;
_response = new RemoveHeaderHttpResponse(this, parent.Response, headersToRemove, loggerFactory);
}
public override HttpResponse Response
{
get
{
return _response;
}
}
这个httpresponse是一个装饰的httpresponse女巫覆盖头集合
public class RemoveHeaderHttpResponse : HttpResponse
{
readonly HttpResponse _parent;
readonly HttpContext _context;
readonly IHeaderDictionary _headers;
/// <summary>
/// Create instance of <see cref="RemoveHeaderHttpResponse"/>
/// </summary>
/// <param name="context">the <see cref="HttpContext"/> associated to the HTTP respone</param>
/// <param name="parent">the <see cref="HttpResponse"/> to decorate</param>
/// <param name="headersToRemove">a list of unwanted header</param>
/// <param name="loggerFactory">the logger factory to create logger</param>
public RemoveHeaderHttpResponse(HttpContext context, HttpResponse parent, IEnumerable<string> headersToRemove, ILoggerFactory loggerFactory)
{
if (parent == null)
throw new ArgumentNullException("parent");
if (headersToRemove == null)
throw new ArgumentNullException("headersToRemove");
if (loggerFactory == null)
throw new ArgumentNullException("loggerFactory");
_parent = parent;
_context = context;
_headers = new RemoveHeaderHeaderDictionary(parent.Headers, headersToRemove, loggerFactory);
}
public override IHeaderDictionary Headers
{
get
{
return _headers;
}
}
这个标题字典过滤器标题由管道中的其他中间件添加
public class RemoveHeaderHeaderDictionary : IHeaderDictionary
{
readonly IHeaderDictionary _parent;
readonly IEnumerable<string> _headersToRemove;
/// <summary>
/// Logger
/// </summary>
public ILogger Logger { get; private set; }
/// <summary>
/// Create an instance of <see cref="RemoveHeaderHeaderDictionary"/>
/// </summary>
/// <param name="parent">the <see cref="IHeaderDictionary"/> to decorate</param>
/// <param name="headersToRemove">a list of unwanted header</param>
/// <param name="loggerFactory">the logger factory to create logger</param>
public RemoveHeaderHeaderDictionary(IHeaderDictionary parent, IEnumerable<string> headersToRemove, ILoggerFactory loggerFactory)
{
if (parent == null)
throw new ArgumentNullException("parent");
if (headersToRemove == null)
throw new ArgumentNullException("headersToRemove");
if (loggerFactory == null)
throw new ArgumentNullException("loggerFactory");
Logger = loggerFactory.Create<RemoveHeaderHeaderDictionary>();
_parent = parent;
_headersToRemove = headersToRemove;
foreach (var header in headersToRemove)
parent.Remove(header);
}
bool IsAllowedHeader(string header)
{
var allowed = !_headersToRemove.Any(h => h == header);
Logger.WriteInformation(string.Format("{0} is {1}", header, allowed ? "allowed" : "not allowed"));
return allowed;
}
public string this[string key]
{
get
{
return _parent[key];
}
set
{
if (IsAllowedHeader(key))
_parent[key] = value;
}
}
但也许有一种更简单的方法吗?
You can find the whole code on github, project ChatLe.HttpUtility