【问题标题】:gzip compression for HTTP 1.0 proxy requests on Azure Web SitesAzure 网站上 HTTP 1.0 代理请求的 gzip 压缩
【发布时间】:2012-12-13 02:37:58
【问题描述】:
有没有办法让Azure Web Sites 为来自Amazon Web Services CloudFront 等HTTP 1.0 代理的请求提供gzip 压缩的内容?考虑这样的请求:
curl -I -H "accept-encoding: gzip,deflate,sdch" -H "Via: 1.0 {foo.cdn.net}" -0 http://{fooproject}.azurewebsites.net/
看来一般的实现方式是在system.webServer中加入如下元素:
<httpCompression noCompressionForHttp10="false" noCompressionForProxies="false" />
似乎ApplicationHost.config 中的httpCompression is only valid 而不是web.config,这意味着它在 Azure 网站上不可覆盖。
对解决方法有什么建议吗?
其他资源:
【问题讨论】:
标签:
asp.net
iis
azure
http-compression
azure-web-app-service
【解决方案1】:
IIS 不会针对 HTTP/1.0 请求进行压缩。
您可以通过设置覆盖此行为:
appcmd set config -section:system.webServer/httpCompression /noCompressionForHttp10:"False"
【解决方案3】:
完成这项工作的自动神奇 HTTP 模块如下所示。您需要在您的 Web.config 文件中注册它。
/// <summary>
/// Provides HTTP compression support for CDN services when
/// ASP.NET website is used as origin.
/// </summary>
public sealed class CdnHttpCompressionModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += Context_PreRequestHandlerExecute;
}
public void Dispose()
{
}
void Context_PreRequestHandlerExecute(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
var request = application.Request;
var response = application.Response;
// ---------------------------------------------------------------------
bool allowed = false;
string via = request.Headers["Via"];
if (!string.IsNullOrEmpty(via))
{
if (via.Contains(".cloudfront.net"))
{
// Amazon CloudFront
allowed = true;
}
// HINT: You can extend with other criterias for other CDN providers.
}
if (!allowed)
return;
// ---------------------------------------------------------------------
try
{
if (request["HTTP_X_MICROSOFTAJAX"] != null)
return;
}
catch (HttpRequestValidationException)
{
}
// ---------------------------------------------------------------------
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding))
return;
string fileExtension = request.CurrentExecutionFilePathExtension;
if (fileExtension == null)
fileExtension = string.Empty;
fileExtension = fileExtension.ToLowerInvariant();
switch (fileExtension)
{
case "":
case ".js":
case ".htm":
case ".html":
case ".css":
case ".txt":
case ".ico":
break;
default:
return;
}
acceptEncoding = acceptEncoding.ToLowerInvariant();
string newContentEncoding = null;
if (acceptEncoding.Contains("gzip"))
{
// gzip
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
newContentEncoding = "gzip";
}
else if (acceptEncoding.Contains("deflate"))
{
// deflate
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
newContentEncoding = "deflate";
}
if (newContentEncoding != null)
{
response.AppendHeader("Content-Encoding", newContentEncoding);
response.Cache.VaryByHeaders["Accept-Encoding"] = true;
}
}
}
该模块旨在在集成管道模式下与 IIS 7.0 或更高版本一起使用(Azure 网站开箱即用)。这是最普遍的配置,所以通常只要你附加它就可以工作。请注意,该模块应该是模块列表中的第一个。
Web.config 注册示例:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="CdnHttpCompressionModule" preCondition="managedHandler" type="YourWebsite.Modules.CdnHttpCompressionModule, YourWebsite" />
<!-- You may have other modules here -->
</modules>
<system.webServer>
</configuration>