Dlaczego IIS 7 ignoruje niektóre (ale nie wszystkie) typy MIME do kompresji? Podawanie błędu: DYNAMIC_COMPRESSION_NOT_SUCCESS - Przyczyna 12

11

Tak więc jestem trochę IIS7 n00b, ale korzystałem z większości starych systemów IIS wracając do 3. Próbuję włączyć kompresję dynamiczną i działa ona głównie. Nie działa w przypadku moich żądań ADO.Net Data Service (Astoria), grupowych lub nie.

Znalazłem śledzenie nieudanego żądania (FREB), które było naprawdę pomocne. I to, co widzę w niezakończonych żądaniach, to Reason Code 12, NO_MATCHING_CONTENT_TYPE. OK, więc nie mam określonego typu MIME, to proste.

Z wyjątkiem tego, co mam w pliku web.config (który moim zdaniem jest poprawny, ale może nie).

<httpCompression dynamicCompressionDisableCpuUsage="100"
                 dynamicCompressionEnableCpuUsage="100"
                 noCompressionForHttp10="false"
                 noCompressionForProxies="false"
                 noCompressionForRange="false"
                 sendCacheHeaders="true"
                 staticCompressionDisableCpuUsage="100"
                 staticCompressionEnableCpuUsage="100">
    <dynamicTypes>
        <clear/>
        <add mimeType="*/*"
             enabled="true" />
    </dynamicTypes>
    <staticTypes>
        <clear/>
        <add mimeType="*/*"
             enabled="true" />
    </staticTypes>
</httpCompression>
<urlCompression doDynamicCompression="true"
                doStaticCompression="true"
                dynamicCompressionBeforeCache="false" />

Teraz myślę, że oznacza to, że powinien kompresować każde żądanie zawierające nagłówek Accept: Gzip. Chciałbym wiedzieć, co mogą tu myśleć inni.

Mój ślad skrzypka:

GET /SecurityDataService.svc/GetCurrentAccount HTTP/1.1
Accept-Charset: UTF-8
Accept-Language: en-us
dataserviceversion: 1.0;Silverlight
Accept: application/atom+xml,application/xml
maxdataserviceversion: 1.0;Silverlight
Referer: http://sdev03/apptestpage.aspx
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.21022; .NET CLR 3.5.30729; InfoPath.2; .NET CLR 3.0.30729; OfficeLiveConnector.1.4; OfficeLivePatch.1.3)
Host: sdev03
Connection: Keep-Alive
Cookie: .ASPXAUTH=<snip>


HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/atom+xml;charset=utf-8
Server: Microsoft-IIS/7.0
DataServiceVersion: 1.0;
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Mon, 22 Mar 2010 22:29:06 GMT
Content-Length: 2726

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
*** <snip> removed ***
Peter Oehlert
źródło
1
UŻYJ NOTEPAD, aby edytować applicationHost.config. Zmarnowałem kilka godzin, zanim zrozumiałem, że moje zmiany wprowadzone w Notatniku ++ (a także w edytorze Visual Studio 2010 !!) nie są stosowane przez IIS. Alternatywnym sposobem dodania dodatkowego mimeType do kolekcji dynamicTypes / staticTypes jest użycie appcmd. "C:\Windows\System32\Inetsrv\Appcmd.exe" set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/javascript',enabled='True']" /commit:apphostI znowu: po wprowadzeniu tych zmian - zobaczysz je tylko w notatniku. Notepad ++ (oraz edytor Visual Studio 2010 !!)
Sasha
Alexander, nie jestem w 100% pewien, że rozumiem, co tu mówisz, ale mogę z całą pewnością stwierdzić, że modyfikacja konfiguracji IIS w dowolnym edytorze tekstu działa dobrze. Możesz mieć trudności z edytorem, który dodaje znacznik BOM, ale poza tym powinno być w porządku. W moim przypadku nie było tak, że nie mogłem użyć notatnika do edycji, tylko to, że edytowałem zły plik. Nie wszystkie zmiany konfiguracji można wprowadzić w pliku web.config, który znajduje się w katalogu głównym aplikacji. Niektóre muszą zostać wykonane przeciwko appHost w folderze System.
Peter Oehlert,
6
@alexander: Prawda, użycie 32-bitowych aplikacji, takich jak notepad ++ lub visual studio w 64-bitowym systemie Windows, spowoduje, że WOW64 uruchomi przekierowanie pliku dla folderu System32. Edycja utworzy klon w C: \ WINDOWS \ SysWOW64 widoczny tylko dla programów 32-bitowych i nigdy nie będzie używany przez IIS, który jest programem 64-bitowym
Fredrik Haglund
Notepad faktycznie działa ... Notepad ++ i Visual Studio zostają przekierowane.
Brian White,
@FredrikHaglund Holy pali. Sugerowałbym umieszczenie tego komentarza we własnej odpowiedzi z jakimś wyjaśnieniem ... Nie miałem pojęcia, że ​​coś takiego się wydarzy, i ścigałbym się za ogonem jeszcze przez wiele godzin, gdybym nie widział twojego komentarza. (Wspiera również Sashę i Briana White'a, którzy również wspomnieli o tym problemie, ale twój komentarz wydaje się być najbliżej sedna problemu.)
Beska

Odpowiedzi:

7

OK, okazuje się, że nie można tego skonfigurować w pliku web.config, tylko appHost.config. Przypuszczałem, że doktorzy powiedzieli appHost.config, ale założyłem, że była to specyfikacja ogólnej koncepcji, a nie jedyna dozwolona lokalizacja konfiguracji.

Peter Oehlert
źródło
Poprawny. Konfiguracja system.webServer nie zezwala na kompresję http na poziomie witryny internetowej. Możesz skonfigurować to samo w katalogu głównym, tj. W applicationhost.config.
Vivek Kumbhar
hmm .. Dokumenty MÓWIĄ, że można go zastosować na poziomie web.config - przewiń w dół: msdn.microsoft.com/en-us/library/ms690689(v=vs.90).aspx i spójrz na „Lokalizacje konfiguracji” tabela .. Czy to problem w dokumentacji?
avs099,
@ avs099 Nie wiem. Kiedy opublikowałem to 3 lata temu, jestem pewien, że zacząłem od web.config i wysłałem b / c, że to nie działało. Być może funkcjonalność zmieniona w łatce lub dokumenty są nieprawidłowe. Dobrze byłoby przetestować, aby się dowiedzieć.
Peter Oehlert,
1
och - być może nie byłem jasny - sposób, w jaki czytam dokumentację, mówi, że http.Kompresja MOŻE być używana w web.config - ale nie byłem w stanie jej uruchomić, więc skończyłem również modyfikować plik applicationHost.config. Wydaje mi się, że dokumentacja wprowadza w błąd.
Łączę
Zobacz moją odpowiedź - domyślnie czysta instalacja IIS wyłącza web.confignadpisywanie ustawień kompresji, dlatego musisz zmodyfikować applicationHost.config. Zamiast jednak zmieniać tam ustawienia kompresji, możesz po prostu zezwolić na zastąpienie i wrócisz do pracy.
mcw
3

Peter, dzięki za podpowiedź - znaleźliśmy również to ustawienie

<add mimeType="application/atom+xml; charset=utf-8" enabled="true" />

w <httpCompression>sekcji applicationHost.confignaprawiono to.

Musieliśmy również określić kodowanie z powodu błędu w kodzie kompresji:

W kodzie kompresji występuje błąd polegający na tym, że nie analizuje on poprawnie zestawu znaków w nagłówku odpowiedzi, więc aby ustawienia działały, musisz skonfigurować „application / xml; charset = utf-8” w ustawieniach kompresji dynamicznej.

Oto pełna sekcja w całości

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="9" dynamicCompressionLevel="4" />
    <scheme name="deflate" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="9" dynamicCompressionLevel="4" />
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/atom+xml; charset=utf-8" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </dynamicTypes>
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>
Jeff Atwood
źródło
3

Po nowej instalacji mój applicationHost.config(in %windir%\system32\inetsrv\config) miał następujące ustawienie:

<section name="httpCompression" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />

... a także domyślny zestaw typów MIME do kompresji, który niestety nie obejmuje JSON i innych typów danych, które byłyby dobrymi kandydatami na kompresję.

Przełączam na:

<section name="httpCompression" overrideModeDefault="Allow" />

włącza konfigurację httpCompressiontagu pod system.webServertagiem w moim web.config.

Potwierdziłem to, ustawiając httpCompressionsekcję applicationHost.configna:

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
    <dynamicTypes>
        <add mimeType="*/*" enabled="false" />
    </dynamicTypes>
    <staticTypes>
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>

... a teraz mogę ustawić wszystkie typy MIME, które chcę skompresować w pliku web.config.

McW
źródło
Śledzenie nieudanych żądań było dla mnie bardzo pomocne w rozwiązywaniu tego problemu
mcw
To nie działa w ogóle dla IIS8 +. Czy masz jakieś doświadczenie w tworzeniu httpCompressionelementu na web.configpoziomie w nowszych wersjach IIS, czy jest to niemożliwe? Dokumenty to koszmar - wydaje się, że nie mówi się o oficjalnej umowie.
theyetiman
@theyetiman - przepraszam, w ogóle nie pracowałem z IIS8 +. Powodzenia.
mcw
0

Aby dodać brakujące typy mimetyczne z programu PowerShell, użyj następujących poleceń:

Add-WebConfiguration -Filter '/system.webServer/httpCompression/staticTypes' -PSPath 'IIS:\' -AtIndex 0 -Value @{mimeType='application/javascript'; enabled='True'}

Add-WebConfiguration -Filter '/system.webServer/httpCompression/staticTypes' -PSPath 'IIS:\' -AtIndex 0 -Value @{mimeType='image/svg+xml'; enabled='True'}

Add-WebConfiguration -Filter '/system.webServer/httpCompression/staticTypes' -PSPath 'IIS:\' -AtIndex 0 -Value @{mimeType='text/css'; enabled='True'}

Zauważ, że kolejność typów mimeTypes jest ważna, ponieważ IIS wydaje się przyjmować pierwsze dopasowanie. Oznacza to, że mimeTypes z symbolami wieloznacznymi (*) powinien znajdować się poniżej mimeTypes bez symboli wieloznacznych. Dlatego upewnij się, że mimeType */*znajduje się na dole, ponieważ jakikolwiek wpis poniżej nie będzie używany

Edytować:

Usługi IIS są do bani, więc najlepszą opcją jest po prostu wyczyszczenie staticTypes i dodanie wszystkiego z powrotem w prawidłowej kolejności:

Clear-WebConfiguration -Filter "//system.webServer/httpCompression/staticTypes/add" -PSPath 'IIS:\'

SetCompressionOfMimeType 'text/*' 'True'
SetCompressionOfMimeType 'application/javascript' 'True'
SetCompressionOfMimeType 'image/svg+xml' 'True'
SetCompressionOfMimeType 'text/css' 'True'
SetCompressionOfMimeType '*/*' 'False'


function SetCompressionOfMimeType($mimeType, $enabled){
    Write-Output "Setting compression for $mimeType to $enabled"
    Add-WebConfiguration -Filter '/system.webServer/httpCompression/staticTypes' -PSPath 'IIS:\' -Value @{mimeType=$mimeType; enabled=$enabled}
}
Marius
źródło