¿Puede una condición de reescritura de URL comparar dos variables del servidor?

¿Puede una condición de reescritura de URL comparar dos variables del servidor?

Estoy intentando comparar dos variables del servidor como parte de una condición de reescritura de URL. Pero primero, algo de contexto...

En IIS, si lo solicita http://www.example.com/fooy fooes un directorio, IIS envía una redirección 302 de "Objeto movido" http://www.example.com/foo/como una "redirección de cortesía" (Fuente).

Si está utilizando IIS+ARR como proxy inverso con descarga SSL, la solicitud que recibe el nodo IIS de fondo es a través de http, no de https.

Combine estos dos comportamientos y las redirecciones de cortesía de IIS eliminarán SSL. La redirección de cortesía utiliza el mismo esquema que la solicitud que recibió IIS (Fuente), http en este caso en lugar de https.

Me gustaría crear una regla de reescritura saliente que compare la URL entrante con el encabezado Ubicación saliente y la reescriba de http a https en este caso:

  • La respuesta es una redirección: {RESPONSE_STATUS}es 302
  • La solicitud entrante se realizó a través de SSL: {HTTPS}está "activada"
  • La URL entrante no termina en una barra.
  • El encabezado de Ubicación saliente termina en una barra.

Todo lo anterior se maneja en la condición previa. La parte complicada es la última parte:

  • La ruta del encabezado de Ubicación saliente es la misma que la de la URL entrante con una barra diagonal adjunta.

A continuación se muestra el código que tengo hasta ahora. La condición previa y la reescritura del encabezado funcionan bien. Sin embargo, la condición provoca un error 500 (error del módulo de reescritura de URL), presumiblemente porque lo estoy usando {REQUEST_URI}en el patrón. Intenté separar la condición en dos y usar grupos de captura, pero tampoco funcionó. ¿Algunas ideas?

<rule name="Fix: Courtesy Redirect + SSL Offloading = SSL dropped" preCondition="Courtesy Redirect Drops SSL" enabled="true">
    <match serverVariable="RESPONSE_LOCATION" pattern="^http://(.+/)$" />
    <conditions>
        <add input="{RESPONSE_LOCATION}" pattern="{REQUEST_URI}/" />
    </conditions>
    <action type="Rewrite" value="https://{R:1}" />
</rule>
<preConditions>
    <preCondition name="Courtesy Redirect Drops SSL">
        <add input="{RESPONSE_STATUS}" pattern="^302$" />
        <add input="{HTTPS}" pattern="^on$" />
        <add input="{REQUEST_URI}" pattern=".*[^/]$" />
        <add input="{RESPONSE_LOCATION}" pattern="^http://.+/$" />
    </preCondition>
</preConditions>

Respuesta1

Puedes usar unproveedor de reescritura personalizada.Un proveedor es un código C# que convierte una cadena en otra cadena. Luego puedes usarlo de manera similar a como usarías rewrite map:

Puede elegir un separador que no sea válido en absoluto en una URL. (Tal vez use espacio o algo así. Lo usaré |para que sea visible en esta publicación, pero deberías elegir otra cadena).

Escribirá una regla para establecer el valor de la variable del servidor IsItMatching. El valor de la variable del servidor se establecerá utilizando su proveedor de reescritura de URL personalizado:

{provider_name:{server_variable_1}|{server_variable_2}}

El código C# que implementa el proveedor hará esto (pseudocódigo, sin verificación de errores):

string Rewrite(string input)
{
    string[] inputVariables = input.split(separator);
    if (inputVariables[0] == inputVariables[1] + "/")
        return "yes";
    else
        return "no";
}

Luego escribirás una regla más para comprobar si el valor de la IsItMatchingvariable del servidor es "sí" o "no".

información relacionada