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 但这并不在所有情况下都有效,特别是对于静态文件中间件
最佳答案
我所做的是一个中间件来覆盖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));
}
}
在调用方法中,我创建一个 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 的装饰器,它会覆盖 headers 集合
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;
}
}
并且此 header 字典过滤管道中其他中间件添加的 header
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
关于c# - 如何删除每个响应上的一些 httpresponse header (例如 Server 和 ETag)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27637845/