REQUEST_URI non corrisponde a percorso e nome file espliciti
Davvero perplesso, perché forma e sintassi sembrano a posto.
RewriteCond per REQUEST_URI non corrisponde al percorso e al nome file espliciti. Quando è isolato, RewriteCond per REQUEST_FILENAME corrisponde perfettamente. Ho verificato utilizzando phpinfo () che REQUEST_URI contiene la barra iniziale e ho testato anche senza la barra iniziale.
L'obiettivo qui è sapere che la richiesta è per questo file e, se non esiste, lancia un 410.
RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$ RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ - [R=410,L]
Non voglio omettere il primo Cond, perché voglio farlo solo per una manciata di file simili a questo.
AGGIORNAMENTO I
cercando di ottenere un test definitivo. Configurazione di prova:
- testmee.txt non esiste
- la richiesta è per testmee.txt nella root
- verificato che request_uri corrisponde, reindirizzando a google
- non può ottenere 410 quando si utilizza solo la prima cond
- (quando si utilizza solo la prima Cond, il server serve 404, non 410)
- (utilizzando entrambe le condizioni, il server serve 404, non 410)
- PU ottenere 410 quando si utilizza solo la seconda cond
RewriteCond %{REQUEST_URI} ^/testmee\.txt$ #RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ - [R=410,L]
contro
#RewriteCond %{REQUEST_URI} ^/testmee\.txt$ RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ - [R=410,L]
AGGIORNAMENTO II
Risposta per MrWhite:
ughh, stesso sintomo. Potrebbe essere necessario convivere con Googlebot che colpisce 404 invece di un 410 desiderato per css / js obsoleti. Nessun problema a lungo termine, probabilmente.
Grazie per il reindirizzamento del test request_uri. Tutto funziona normalmente in quei test. I nomi delle pagine e così via vengono restituiti come previsto, nell'URL var = rewrite.
A questo punto, penso che debba essere una gestione interna dei 404 relativi alle estensioni del tipo di file. Vedi indizio sotto. Ho il software del carrello degli acquisti Prestashop e deve forzare i 404 sui tipi di file.
Questo reindirizzerà a Google (per confermare la corrispondenza del pattern):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.txt$ http://www.google.com/ [L]
(L flag is needed or else other Rules further down will interfere.)
Questo continuerà a restituire 404 invece di 410:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.txt$ - [NC,R=410]
E come test di controllo, questo restituirà un 410:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ - [NC,R=410]
Se il tipo di file è css nel test fallito sopra, il mio controller 404 personalizzato non viene richiamato. Ricevo solo una semplice risposta 404, senza la 404 personalizzata inclusa in tutti i modelli del mio sito.
Per esempio:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.css$ - [NC,R=410]
Ho paura di aver perso un po 'del tuo tempo. Mie scuse. Non avrei mai immaginato che il codice di Prestashop avrebbe forzato 404 in base al tipo di file, ma non riesco a vedere nessun'altra spiegazione. Potrei scavare dentro e forse trovare il punto nei controller che lo sta facendo. Però devo fare una pausa.
Risposte
Questa non è davvero una risposta solida, più di una cosa per cercare di aiutare a eseguire il debug di questo e per annullare alcuni miti ...
Ho verificato utilizzando
phpinfo()cheREQUEST_URIcontiene la barra principale
Sì, la REQUEST_URIvariabile del server Apache contiene effettivamente la barra iniziale. Contiene il percorso URL completo.
Tuttavia, la REQUEST_URIvariabile del server Apache non è necessariamente la stessa del $_SERVER['REQUEST_URI']superglobale PHP - in effetti, non sono affatto la stessa cosa. Ci sono alcune differenze significative tra queste variabili (in qualche modo è forse un po 'un peccato che condividano lo stesso nome). In particolare, il superglobale PHP contiene l'URL iniziale della richiesta e include la stringa di query (se presente) e non è% -decoded. Mentre la variabile del server Apache con lo stesso nome contiene l' URL riscritto (non necessariamente l'URL richiesto) e non contiene la stringa di query ed è% -decoded.
Quindi, ecco perché ti chiedevo se hai altre direttive mod_rewrite. Potevi benissimo avere un conflitto. Se un'altra direttiva riscrive l'URL, la condizione non corrisponderà mai (nonostante il superglobale PHP suggerisca che dovrebbe).
Sembrava che se avessi messo questo in alto, il flag Last avrebbe terminato l'elaborazione per quel viaggio attraverso, restituendo il 410
Questa direttiva dovrebbe certamente andare all'inizio del .htaccessfile, per evitare che l'URL venga riscritto prima. Il Lflag è in realtà superfluo se usato con a R=410(qualsiasi cosa diversa da a 3xx) - in questo caso è implicito.
Quindi cambio il risultato in "lancia un 410" e viene lanciato un 404.
Ciò può certamente essere causato da un override lato server. Ma sei in grado di lanciare un 410 in altre situazioni, quindi questo sembrerebbe escluderlo. Tuttavia, puoi reimpostare il documento di errore in .htaccesscaso di dubbio (a meno che tu non stia già utilizzando un documento di errore personalizzato):
ErrorDocument 410 default
RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$ RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ - [R=410,L]
Anche se questo non fa davvero la differenza nel modo in cui si comporta la regola, non è necessaria la prima RewriteConddirettiva che si confronta con REQUEST_URI. Dovresti invece eseguire questo controllo nel RewriteRule pattern (che sarà più efficiente, poiché viene elaborato per primo). Per esempio:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$ - [NC,R=410]
La NCbandiera dovrebbe essere superflua.
Tuttavia, un conflitto con le direttive esistenti è la causa più probabile. Rimuovi tutte le altre direttive. Vedi ancora lo stesso comportamento?
È possibile testare il valore della REQUEST_URIvariabile del server. Puoi emettere un reindirizzamento e passare REQUEST_URIcome parametro URL o impostare variabili di ambiente (ma dovrai fare attenzione REDIRECT_<var>a ogni riscrittura).
Ad esempio, nella parte superiore del tuo .htaccess(o ovunque tu stia provando questo):
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ /test.php?var=%{REQUEST_URI} [NE,R,L]
Creato un test.phpfile fittizio per evitare una sottorichiesta interna a un documento di errore.
Ero in grado di determinare il motivo per cui la configurazione del server o il codice del sito stava costringendo '410 finiti' direttiva risposta in .htaccess per essere sovrascritta con una risposta 404, quindi abbiamo dovuto fare qualcosa di simile questo per dire Googlebot di arresto di caccia per i file CSS / JS che eliminati i periodicamente (e rinominato quando rigenerato).
in .htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule v_(.*)_(.*)$ /410response.php [L]
in 410response.php posizionato nella radice:
<?php header($_SERVER['SERVER_PROTOCOL'].' 410 Gone');
AGGIORNAMENTO I
La risposta 404 durante il tentativo di utilizzare htaccess per la direttiva 410 è stata forzata dal server, a causa del fatto che il server apparentemente aveva un documento 410 personalizzato, apparentemente instradato a 404. L'aggiunta di una direttiva per impedire che quindi correttamente consentito l'uso di htaccess per restituire 410 per le corrispondenze di pattern in RewriteRule. (Pensavo di aver già controllato ieri per vedere se avrebbe funzionato, dal momento che @MrWhite ha detto nella sua risposta sopra di controllare il server che potrebbe avere un 410 personalizzato; oggi, quando si effettua questo controllo, ha funzionato e indica che il server 410-to -Il reindirizzamento 404 sovrascriveva la mia direttiva 410.)
ErrorDocument 410 default
RewriteRule test\.txt$ - [NC,R=410]
MrWhite! Ho trovato questa soluzione in uno dei tuoi post su Stack Exchange.