Включить сжатие HTTP с помощью веб-API ASP.NET

Мы обслуживаем файлы для веб-сайта из нашего веб-интерфейса Asp.NET:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var clientHostname = System.Configuration.ConfigurationManager.AppSettings["ClientHostname"];

        var staticFileOptions = new StaticFileOptions()
        {
            OnPrepareResponse = staticFileResponseContext =>
            {
                staticFileResponseContext.OwinContext.Response.Headers.Add("Cache-Control", new[] { "public", "max-age=0" });
            }
        };

        app.MapWhen(ctx => ctx.Request.Headers.Get("Host").Equals(clientHostname), app2 =>
        {
            app2.Use((context, next) =>
            {
                if (context.Request.Path.HasValue == false || context.Request.Path.ToString() == "/") // Serve index.html by default at root
                {
                    context.Request.Path = new PathString("/Client/index.html");
                }
                else // Serve file
                {
                    context.Request.Path = new PathString($"/Client{context.Request.Path}");
                }

                return next();
            });

            app2.UseStaticFiles(staticFileOptions);
        });
    }
}

Я хочу включить HTTP-сжатие. Согласно эта документация MSDN

Использовать технологии сжатия ответов на основе сервера в IIS, Apache или Nginx, где производительность промежуточного программного обеспечения, вероятно, не будет соответствовать производительности серверных модулей. Используйте Средство промежуточного сжатия ответа, если вы не можете использовать:

  • Модуль динамической компрессии IIS

  • Модуль Apache mod_deflate

  • Сжатие и декомпрессия NGINX

  • Сервер HTTP.sys(ранее называемый WebListener)

  • Kestrel

Итак, я думаю, что первым предпочтительным способом сделать это в моем случае является модуль динамического сжатия IIS. Соответственно, я попробовал это в своем Web.config в качестве теста, следуя в этом примере:

<configuration>
  <system.webServer>
    <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
      <dynamicTypes>
        <add mimeType="*/*" enabled="true" />
      </dynamicTypes>
      <staticTypes>
        <add mimeType="*/*" enabled="true" />
      </staticTypes>
    </httpCompression>
  </system.webServer>
</configuration>

Однако заголовки ответов не включают Content-Encoding, поэтому я не считаю, что он сжат. Что мне не хватает? Как я могу настроить это для наилучшего возможного сжатия с помощью сжатия?

Я проверил, что мой клиент отправляет заголовок Accept-Encoding gzip, deflate, br.

Update

Я попытался установить динамическое сжатие HTTP в IIS, поскольку он не установлен по умолчанию. Мне кажется, что я стараюсь обслуживать контент статически, но я думал, что это стоит попробовать. Я проверил, что как статическое, так и динамическое сжатие содержимого включены в диспетчере IIS. Тем не менее, я перезапустил его, но все еще не сжал.

Обновление 2

Я понял, что сжатие работало на наших серверах Azure, но все же не с моим локальным IIS.

Ответы

Ответ 1

Я попробовал ваш запуск в пустом веб-проекте 4.7.NET, и я получаю сжатие, по крайней мере, на index.html. Я установил динамическое сжатие, добавил несколько пакетов Owin, web.config ниже и т.д., Чтобы заставить его работать. Использование IIS/10

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.5" targetFramework="net47" />
  <package id="Microsoft.Net.Compilers" version="2.1.0" targetFramework="net47" developmentDependency="true" />
  <package id="Microsoft.Owin" version="3.1.0" targetFramework="net47" />
  <package id="Microsoft.Owin.FileSystems" version="3.1.0" targetFramework="net47" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="3.1.0" targetFramework="net47" />
  <package id="Microsoft.Owin.StaticFiles" version="3.1.0" targetFramework="net47" />
  <package id="Owin" version="1.0" targetFramework="net47" />
</packages>

Web.config(работал у меня без httpCompression)

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <appSettings>
    <add key="ClientHostname" value="localhost" />
    <add key="owin:appStartup" value="WebApplication22.App_Start.Startup" />
  </appSettings>
  <system.web>
    <compilation targetFramework="4.7" />
    <httpRuntime targetFramework="4.7" />
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
  <system.webServer>
    <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
      <dynamicTypes>
        <add mimeType="*/*" enabled="true" />
      </dynamicTypes>
      <staticTypes>
        <add mimeType="*/*" enabled="true" />
      </staticTypes>
    </httpCompression>
  </system.webServer>
</configuration>

Startup.cs(сокращенно)

using Microsoft.Owin;
using Microsoft.Owin.StaticFiles;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication22.App_Start
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var clientHostname = System.Configuration.ConfigurationManager.AppSettings["ClientHostname"];

            var staticFileOptions = new StaticFileOptions()
            {
                OnPrepareResponse = staticFileResponseContext =>
                {
                    staticFileResponseContext.OwinContext.Response.Headers.Add("Cache-Control", new[] { "public", "max-age=0" });
                }
            };
            ...
            }
    }
}

Ответ

HTTP/1.1 200 OK
Cache-Control: public,max-age=0
Content-Type: text/html
Content-Encoding: gzip
Last-Modified: Tue, 17 Oct 2017 22:03:20 GMT
ETag: "1d347b5453aa6fa"
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Wed, 18 Oct 2017 02:27:34 GMT
Content-Length: 588
...

Ответ 2

Я нашел эти три ресурса полезными при настройке динамического сжатия для IIS на страницах ASP.Net WCF и веб-API. Я предполагаю, что он также работает для .Net Core, но я еще не пробовал. Первые два немного устарели, но принципы все еще применяются:

https://blog.arvixe.com/how-to-enable-gzip-on-iis7/

https://www.hanselman.com/blog/EnablingDynamicCompressionGzipDeflateForWCFDataFeedsODataAndOtherCustomServicesInIIS7.aspx

https://docs.microsoft.com/en-us/iis/configuration/system.webserver/httpcompression/

В частности:

  • Да, вам нужен модуль динамического HTTP-сжатия, установленный в IIS, и включенный
  • Убедитесь, что динамическое сжатие отмечено в диспетчере IIS в разделе [Ваш сервер]/Сжатие: Включить динамическое сжатие
  • Дважды проверьте, что тип MIME в заголовке запроса клиента специально добавлен в Редакторе конфигурации в разделе system.webServer/httpCompression/dynamicTypes/ и что для свойства "Enabled" для типа type установлено значение True
  • Добавьте записи web.config, как указано выше, и другой ответ

Ответ 3

Скорее всего, то, чего не хватает на вашем Windows Server (я полагаю, что вы работаете на сервере Os), является установка функций IIS Performance Web Server, в которых могут быть установлены два подмодуля: Static Content Conpression и Dynamic Content Compression.

Чтобы проверить, установлены ли они, запустите диспетчер сервера, выберите Add Roles and Features, выберите свой экземпляр, на экране Server Roles разверните узлы дерева Web Server (IIS), Web Server, Performance и проверьте, показывают ли флажки, что Static Content Conpression и Dynamic Content Compression устанавливаются, если не проверяют их и продолжают установку функций. Затем повторите все шаги настройки для статической и динамической конфигурации сжатия в диспетчере IIS и в настройках веб-сайта. Теперь он должен работать.