L’archivio del tag «htaccess»

Ho pensato di affrontare in un paragrafo separato una questione particolare riguardante il reindirizzamento (redirect 301). Ed è il caso di scrivere «tratto da una storia vera»: ho passato due o tre ore a risolvere il problema in questione verificatosi sul mio sito.
Immaginiamo di avere pubblicato sul nostro sito una serie di documenti da mostrare (e evidentemente far scaricare) ai visitatori. Tali documenti sono raccolti in una directory del nostro server ma, durante i lavori di aggiornamento del nostro sito, abbiamo deciso di spostarli da un’altra parte (oppure semplicemente rinominare la directory). I nostri visitatori fedeli, però, sono abituati ad aprire i loro documenti preferiti con i loro indirizzi (URL) vecchi. Probabilmente hanno pure pubblicato dei link diretti su internet… Come possiamo proteggerli dall’errore 404?
Il problema si risolve con il file di configurazione del server (.htaccess o web.config).

1. La soluzione con il web.config
Nel caso di un server IIS (hosting Windows) dobbiamo risolvere il problema lavorando sul file web.config.
Ipotizziamo un problema con un indirizzo URL da riscrivere in modo complesso. Ipotizziamo dunque di avere un archivio pubblico dei libri in PDF raggruppati in sottocartelle chiamate con i cognomi degli autori. Di conseguenza, l’indirizzo di ogni file è http://sito.it/download/booksinpdf/nomeautore/nomelibro.pdf
La nostra biblioteca digitale è grande, quindi le componenti che ho messo in corsivo sono ovviamente varie e numerose. Noi abbiamo trasferito tutti i pdf e vogliamo essere certi che i visitatori li aprano sempre senza problemi agli indirizzi nuovi: http://sito.it/files/booksinpdf/nomeautore/nomelibro.pdf
Nell’indirizzo nuovo ho messo in corsivo anche la parte modificata.
La soluzione è la seguente:

<rule name="redirect PDFs" stopProcessing="true">
<match url="download/booksinpdf/([0-9A-Za-z ]+)/([0-9A-Za-z ]+).pdf$" />
<action type="Rewrite" url="files/booksinpdf/{R:1}/{R:2}.pdf" />
</rule>

Le componenti variabili sono racchiuse tra le parentesi tonde e vengono riprese nella fase di reindirizzamento nelle parentesi graffe. La loro quantità e posizione, naturalmente, variano in base alle necessità concrete.
Un’altra osservazione è banalissima: tale metodo funziona per tutte le estensioni dei file: .mp3, .jpg, .doc etc.

2. La soluzione con il .htaccess
Nel caso di un server Apache (hosting Linux) siamo costretti a lavorare con il file .htaccess.
La logica del reindirizzamento dovrebbe essere come descritta di seguito, anche se non ho avuto il modo di sperimentarla sulla pratica (sto sul server IIS, quindi ho risolto il caso come descritto sopra).
Ipotizziamo un problema con un indirizzo URL da riscrivere in modo complesso. Ipotizziamo dunque di avere un archivio pubblico dei libri in PDF raggruppati in sottocartelle chiamate con i cognomi degli autori. Di conseguenza, l’indirizzo di ogni file è http://sito.it/download/booksinpdf/nomeautore/nomelibro.pdf
La nostra biblioteca digitale è grande, quindi le componenti che ho messo in corsivo sono ovviamente varie e numerose. Noi abbiamo trasferito tutti i pdf e vogliamo essere certi che i visitatori li aprano sempre senza problemi agli indirizzi nuovi: http://sito.it/files/booksinpdf/nomeautore/nomelibro.pdf
Nell’indirizzo nuovo ho messo in corsivo anche la parte modificata.
La soluzione è la seguente:

RewriteEngine on
RewriteRule ^download/booksinpdf/(.+)/(.+\.pdf)$ files/booksinpdf/$1 [L]

Tale metodo deve funzionare per tutte le estensioni dei file: .mp3, .jpg, .doc etc.


Oggi scrivo di un problema molto più ricorrente di quanto si possa pensare.
Il problema
Supponiamo di voler installare due WordPress sullo stesso dominio: il primo nella root (sito.it) e il secondo in una cartella (sito.it/cartella). Il risultato che attendiamo è il seguente:

Naturalmente, non sorge alcun problema qualora decidessimo di installare solo una copia di WordPress oppure installarne due o più nelle cartelle dello stesso livello (per esempio, sito.it/cartella1, sito.it/cartella2 etc.). Installando invece i due WordPress nella root e nella cartella, ci troviamo di fronte al non-funzionamento del secondo: al tentativo di aprire qualsiasi pagina appartenente a sito.it/cartella esce l’errore 404.
Le soluzioni
Qualora il nostro server avesse il sistema operativo Linux, avremmo potuto limitarci a inserire nella cartella sito.it/cartella (dove sta il nostro WordPress № 2) un file .htaccess come questo:

# BEGIN WordPress

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

… permettendo in questo modo di convivere pacificamente a sito.it con sito.it/cartella
Su un server Windows, invece, non è possibile utilizzare il file .htaccess Di conseguenza, dobbiamo convertirlo in un file web.config Esistono alcuni strumenti online e offline che permettono di effettuare la conversione in automatico, ma tutti essi hanno lo stesso problema: non sanno convertire il comando RewriteBase (il quale è fondamentale per evitare la comparsa dell’errore 404 al posto di tutte le pagine del WordPress installato nella cartella). Sostituiscono semplicemente quel comando con una riga di commento, senza avvisarci che in questo modo l’intero file diventa non funzionante.
Io, dunque, sono giunto alla seguente soluzione.
Creiamo due file web.config. Il primo, quello più semplice, lo mettiamo nella root dove è installato il WordPress № 1. Ecco il suo codice:

<?xml version="1.0" encoding="UTF-8"?>
<!--Questo file sta nella cartella della root.-->
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
          <rule name="nomeregolaroot" patternSyntax="Wildcard">
            <match url="*"/>
                <conditions>
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
                </conditions>
            <action type="Rewrite" url="index.php"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Il secondo file web.config è invece più complesso e va caricato nella cartella dove è installato il WordPress № 2. Eccolo:

<?xml version="1.0" encoding="UTF-8"?>
<!--Questo file sta nella cartella caricata nella root.-->
<configuration>
  <system.webServer>
<rewrite>
  <rules>
    <clear />
    <rule name="nomeregola1" stopProcessing="true">
      <match url="^index\.php$" ignoreCase="false" />
      <action type="None" />
    </rule>
    <rule name="nomeregola2" stopProcessing="true">
      <match url="." ignoreCase="false" />
      <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
      </conditions>
      <action type="Rewrite" url="/cartella/index.php" />
    </rule>
  </rules>
</rewrite>
  </system.webServer>
</configuration>

Attenzione! Alla riga 18 va indicato il nome della cartella nella quale viene caricato il relativo web.config (naturalmente al posto di «cartella»).
Basta, ora entrambi i WordPress devono funzionare correttamente.
So che in teoria avrei potuto provare a escludere l’eredità delle regole nel web.config-«padre» o inserire un <remove> delle regole ereditate nel web.config-«figlio»… Però io di solito preferisco le soluzioni più semplici che non richiedano delle pratiche mentali autolesive prolungate nel tempo. Sul mio sito (che state leggendo ora) ho utilizzato proprio il metodo appena descritto per fare due versioni linguistiche del sito stesso. Come potete vedere, funziona benissimo.
Se volessimo ora installare altre copie di WordPress in altre cartelle più profonde – per esempio, sito.it/cartella1/cartella2 – ci limitiamo a inserire il secondo web.config in ognuna delle cartelle interessate dalla installazione. Dobbiamo solamente ricordarci di indicare il nome della cartella alla riga 18.
È importantissimo, inoltre, indicare tutta la sequenza delle cartelle per i WordPress installati nelle cartelle «profonde». Supponiamo, per esempio, di avere sempre il costrutto sito.it/cartella1/cartella2 dove sono installati tre copie di WordPress: la prima nella root, la seconda nella cartella1 e la terza nella cartella2. La riga 18 del file web.config caricato nella cartella2 deve essere così:

<?xml version="1.0" encoding="UTF-8"?>
<!--Questo file sta nella in una sottocartella (root/cartella/cartella/).-->
<configuration>
  <system.webServer>
<rewrite>
  <rules>
    <clear />
    <rule name="nomeregola1cartella" stopProcessing="true">
      <match url="^index\.php$" ignoreCase="false" />
      <action type="None" />
    </rule>
    <rule name="nomeregola2cartella" stopProcessing="true">
      <match url="." ignoreCase="false" />
      <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
      </conditions>
      <action type="Rewrite" url="/cartella1/cartella2/index.php" />
    </rule>
  </rules>
</rewrite>
  </system.webServer>
</configuration>

Il metodo è stato testato con successo dal sottoscritto.
Se avete delle domande o soluzioni alternative, scrivetemi pure!