Sto implementando un proxy inverso per le richieste di routing a un server di backend.IIS come proxy inverso: compressione della risposta riscritta dal server di backend
Funzionalmente tutto funziona correttamente, tuttavia sono preoccupato che tutte le risposte dal server di back-end vengano trasferite al client (browser Web) senza compressione.
La messa a punto è il seguente:
- server di back-end, non accessibile al pubblico, su un dominio interno. Host di un'applicazione Web su
https://internal.app
- Server Web anteriore con IIS 7.5, che ospita il sito Web pubblico principale e funge da proxy per il server di back-end. Il sito principale è
https://site.com
.
voglio percorso tutte le richieste a https://site.com/app/WHATEVER
a https://internal.app/WHATEVER
in un modo che sia trasparente per i clienti.
La mia attuale configurazione è basata su URL Rewrite 2.0 e sulle estensioni IIS di Routing Richiesta Applicazione. L'approccio generale si basa sulle linee guida dai seguenti articoli:
- Setting up a Reverse Proxy using IIS, URL Rewrite and ARR
- Reverse Proxy with URL Rewrite v2 and Application Request Routing
La sezione del web.config
del site.com
app:
<system.webServer>
<rewrite>
<rules>
<rule name="Route the requests for backend app" stopProcessing="true">
<match url="^app/(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://internal.app/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RewriteBackendAbsoluteUrlsInResponse" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^http(s)?://internal.app(\:80)?/(.*)" />
<action type="Rewrite" value="/app/{R:3}" />
</rule>
<rule name="RewriteBackendAbsoluteUrlsInRedirects" preCondition="ResponseIsHtml1">
<match serverVariable="RESPONSE_LOCATION" pattern="^http(s)?://internal.app(\:80)?/(.*)" />
<action type="Rewrite" value="/app/{R:3}" />
</rule>
<rule name="RewriteBackendRelativeUrlsInResponse" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" negate="false" />
<conditions>
<add input="{URL}" pattern="^/app/.*" />
</conditions>
<action type="Rewrite" value="/app/{R:1}" />
</rule>
<rule name="RewriteBackendRelativeUrlsInRedirects" preCondition="ResponseIsHtml1">
<match serverVariable="RESPONSE_LOCATION" pattern="^/(.*)" negate="false" />
<conditions>
<add input="{URL}" pattern="^/app/.*" />
</conditions>
<action type="Rewrite" value="/app/{R:1}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression dynamicCompressionBeforeCache="false" />
</system.webServer>
Il problema è che non appena smetto di cancellare la variabile del server HTTP_ACCEPT_ENCODING
, ogni richiesta corrisponde es la regola precedente termina con il seguente errore: HTTP Error 500.52 - URL Rewrite Module Error. Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("gzip").
Sono a conoscenza di this thread e ho seguito tali istruzioni. Ho impostato dynamicCompressionBeforeCache="false"
come si può vedere sopra, ho aggiunto la voce di registro necessaria e ho assicurato che i moduli sono nell'ordine corretto in IIS.
Tuttavia, questo sembra funzionare solo se la riscrittura si verifica all'interno di un'app Web. Se rimuovo le regole precedenti e aggiungo una semplice (e le rispettive regole in uscita) per riscrivere, ad es. /x/WHATEVER
a solo /WHATEVER
, tutto funziona perfettamente senza la necessità di cancellare HTTP_ACCEPT_ENCODING
- la regola funziona e la compressione è abilitata per le richieste riscritte.
Ma non appena si aggiunge nuovamente la regola che riscrive la risposta a un'altra app Web e non si cancella l'intestazione HTTP_ACCEPT_ENCODING
, viene visualizzato di nuovo lo stesso errore.
Da quello che ho capito, se la riscrittura coinvolge un'altra app Web, ci sono più limiti su cosa può essere fatto. Per esempio. Il rewriter di URL deve ricevere una risposta non compressa dal server di back-end per poterlo riscrivere utilizzando le regole in uscita. Immagino che azzerare HTTP_ACCEPT_ENCODING
in questo scenario sia un must per questo.
Tuttavia, mi aspetto che, poiché il modulo di compressione è elencato in cima all'elenco dei moduli, la risposta riscritta finale dovrebbe essere compressa indipendentemente da dove ha avuto origine. Sembra che IIS crei alcune scorciatoie e restituisca la risposta al client ignorando il modulo di compressione.Oppure l'intestazione HTTP_ACCEPT_ENCODING
viene rimossa abbastanza presto da disabilitare completamente la compressione (non solo nella comunicazione da server a server).
Quindi, alla fine, la mia domanda è: c'è un modo per comprimere quelle risposte?
Grazie, ho bloggato sulla tua risposta qui: http://anjdreas.blogspot.no/2016/01/iis-aspnet- exposing-localhost-to-world.html – angularsen
Contento di aver trovato questo utile e grazie per il collegamento di nuovo qui! –
Hm, mi sento come se mi mancasse una parte della tua formula. Ho tutte queste cose a posto, eppure non vedo ancora alcuna compressione per i contenuti proxy. Qual è l'ordine dei tuoi moduli IIS? Importa dove 'HttpCacheModule' e' RewriteModule' sono in relazione a 'DynamicCompressionModule' e' StaticCompressionModule'? –