Tente reescrever para um URL diferente se isso resultar em 404

Tente reescrever para um URL diferente se isso resultar em 404

Eu tenho um servidor Tomcat local que estou desenvolvendo para usar minha instância local do IIS como proxy.

Faço isso porque implantar o servidor é um processo doloroso, já que grande parte do conteúdo não é (o que eu descreveria como) independente. O conteúdo de diferentes projetos é essencialmente copiado para a raiz do servidor. Eu não queria lidar com o incômodo de configurar isso, então, com a ajuda do módulo de reescrita, eu poderia reescrever URLs em diretórios virtuais na maior parte.

por exemplo,

/js/* -> /someproject/js/*
/css/* -> /someproject/css/*
/**/*.pdf -> /someotherproject/pdf/*

No entanto, existem alguns casos em que este esquema não funciona, especialmente quando há sobreposição nos diretórios de destino. Na implantação, alguns recursos são colocados no mesmo diretório, portanto não há uma maneira real de distinguir qual é qual. Não existe um padrão estrito para esses arquivos, é tudo uma mistura.

por exemplo,

/someproject1/file1.txt -> /file1.txt
/someproject2/book2.doc -> /book2.doc

Então, dado um url /file1.txt, eu não saberia se posso reescrever para ir para someproject1ou someproject2. Então, estou pensando que poderia fazer isso funcionar se houvesse algum tipo de hierarquia para quais URLs tentar reescrever. Portanto, posso pegar um URL como /file3.txte reescrever o primeiro desses padrões que parecer válido.

/someproject1/file3.txt     # if 404, try the next
/someproject2/file3.txt     # if 404, try the next
/someotherproject/file3.txt # if 404, try the next
/file3.txt                  # fallback

Isso é algo que pode ser expresso apenas usando o módulo de reescrita de URL?

Responder1

Consegui fazer isso funcionar.

O primeiro obstáculo foi não perceber que nem todos os tipos de correspondência condicional estão disponíveis no escopo global (que era onde eu estava escrevendo minhas regras). Só Patternestava disponível. Tive que alterar o escopo para o escopo "distribuído" (regras por site) para obter acesso aos tipos de correspondência IsFilee IsDirectory.

A partir daí, eu poderia escrever minhas regras com algum tipo de hierarquia. Primeiro reescreva para corresponder ao padrão que desejo tentar primeiro e, se não resolver para um arquivo, reescreva-o para o próximo padrão e repita.

<rule name="try in project/content" stopProcessing="false">
    <match url=".*" />
    <action type="Rewrite" url="project/content/{R:0}" />
</rule>
<rule name="verify project/content" stopProcessing="false">
    <match url="(project)/content(/.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}{R:2}" />
</rule>

No meu caso específico, eu queria tentar primeiro um subdiretório específico e depois tentar os diretórios pais, se eles não existissem. Mas teoricamente eu poderia fazer isso para qualquer conjunto de caminhos, desde que saiba em que ordem experimentá-los.


Então, para o meu exemplo na pergunta, eu definiria estas regras:

<rule name="try in someproject1" stopProcessing="false">
    <match url=".*" />
    <action type="Rewrite" url="someproject1/{R:0}" />
</rule>
<rule name="try in someproject2 otherwise" stopProcessing="false">
    <match url="someproject1/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="someproject2/{R:1}" />
</rule>
<rule name="try in someotherproject otherwise" stopProcessing="false">
    <match url="someproject2/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="someotherproject/{R:1}" />
</rule>
<rule name="fallback to root otherwise" stopProcessing="false">
    <match url="someotherproject/(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}" />
</rule>

informação relacionada