Domanda

Abbiamo un'applicazione PHP con uno schema dinamico URL che richiede personaggi di essere codificati per cento-, anche " caratteri non prenotati " come parentesi o aphostrophes che non sono effettivamente necessari da codificare. URLs che i Deems app da codificare il modo "sbagliato" sono canonizzati e poi reindirizzati alla "destra" codifica.

Ma Google e da altri interpreti sarà canonicalize percentuale di codifica / decodifica in modo diverso, cioè quando Googlebot richiede la pagina che vi chiederà per il "sbagliato" URL, e quando si rimette un redirect al "diritto" URL, volontà Googlebot rifiutare di seguire il reindirizzamento e si rifiuterà di indicizzare la pagina.

Sì, questo è un bug sulla nostra fine. Le specifiche HTTP richiedono che i server trattano personaggi senza riserve per cento-codificato e non-cento-codificati in modo identico. Ma risolvere il problema nel codice app è diritto non semplice ora, quindi speravo di evitare un cambiamento di codice utilizzando una regola di riscrittura di Apache che garantirebbe che gli URL sono codificati "correttamente" dal punto di vista-di-dell'app , il che significa che apopstrophes, parentesi, ecc sono tutti per cento-codificato e che gli spazi sono codificati come + e non %20.

Ecco un esempio, dove voglio riscrivere la prima e finiscono con la seconda forma:

  • www.splunkbase.com/apps/All/4.x/Add-On/app:OPSEC+LEA+for+Check+Point+ (Linux)
  • www.splunkbase.com/apps/All/4.x/Add-On/app:OPSEC+LEA+for+Check+Point+%28Linux%29

Ecco un altro:

  • www.splunkbase.com/apps/All/4.x/app:Benford's+Law+Fraud+Detection+Add-on
  • www.splunkbase.com/apps/All/4.x/app:Benford%27s+Law+Fraud+Detection+Add-on

Ecco un altro:

  • www.splunkbase.com/apps/All/4.x/app:Benford%27s%20Law%20Fraud%20Detection%20Add-on
  • www.splunkbase.com/apps/All/4.x/app:Benford%27s+Law+Fraud+Detection+Add-on

Se l'applicazione vede solo la seconda forma di questi URL, allora non invia alcun redirect e Google sarà in grado di indicizzare la pagina.

Sono un principiante con regole di riscrittura, ed era chiaro dalla mia lettura della documentazione mod-rewrite che mod_rewrite fa qualche codifica / decodifica automatica che può aiutare o danneggiare quello che voglio fare, anche se non è sicuro.

Qualche consiglio per le regole di riscrittura per gestire i casi di cui sopra? Sto bene con una regola per ogni carattere speciale dal momento che non ci sono molti di loro, ma una sola regola (se possibile) sarebbe l'ideale.

È stato utile?

Soluzione

La soluzione in realtà può essere abbastanza semplice, anche se sarà solo il lavoro in Apache 2.2 e successive a causa dell'uso della B bandiera . Non sono sicuro se sia o non si prende cura di tutti i casi in modo corretto (devo ammettere che sono un po 'scettico non comporta più lavoro di questo), ma sto portato a credere che dovrebbe dal codice sorgente.

Tenete presente anche che il valore di REQUEST_URI non viene aggiornato da trasformazioni mod_rewrite, quindi, se l'applicazione si basa su quel valore per determinare l'URL richiesto, le modifiche apportate non saranno comunque visibili.

La buona notizia è che questo può essere fatto in .htaccess, in modo da avere la possibilità di lasciare la configurazione principale intatta se funziona meglio per voi.

RewriteEngine On

# Make sure this is only done once to avoid escaping the escapes...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
# Check if we have anything to bother escaping (likely unnecessary...)
RewriteCond $0 [^\w]+
# Rewrite the entire URL by escaping the backreference
RewriteRule ^.*$ $0 [B]

Quindi, perché v'è la necessità di usare la bandiera B invece di lasciare mod_rewrite sfuggire l'URL riscritto automaticamente? Quando mod_rewrite sfugge automaticamente l'URL, utilizza ap_escape_uri (che a quanto pare è stato trasformato in una macro per ap_os_escape_path per qualche motivo ...), una funzione che sfugge un sottoinsieme limitato di caratteri. La bandiera B, tuttavia, utilizza una funzione di modulo interno chiamato escape_uri, che è modellato su di PHP funzione di urlencode .

L'implementazione della escape_uri nel modulo suggerisce che i caratteri alfanumerici e underscore sono lasciati così come sono, gli spazi vengono convertiti in +, e tutto il resto viene convertito nel suo equivalente sfuggito. Questo sembra essere il comportamento che si desidera, quindi presumibilmente dovrebbe funzionare.

In caso contrario, si ha la possibilità di istituire un programma esterno RewriteMap che poteva manipolare gli URL in entrata nel formato corretto. Ciò richiede la manipolazione della configurazione di Apache, però, e uno script rinnegato potrebbe causare problemi per il server nel suo complesso, in modo da non considero una soluzione ideale se può essere evitato.

Altri suggerimenti

mod_rewrite non è lo strumento migliore per fare questo tipo di lavoro. Perché con mod_rewrite è possibile sostituire solo una quantità fissa di occorrenze in un momento. Ma è possibile:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?\ ]*)%20([^?\ ]*)
RewriteRule ^ /%1+%2 [R=301,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?'\ ]*)'([^?'\ ]*)
RewriteRule ^ /%1\%27%2 [R=301,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?(\ ]*)\(([^?(\ ]*)
RewriteRule ^ /%1\%28%2 [R=301,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?)\ ]*)\)([^?)\ ]*)
RewriteRule ^ /%1\%29%2 [R=301,NE]

Questo sostituirà uno %20, ', ( o ) alla volta e risponde con un reindirizzamento 301. Quindi, se un sentiero URL contiene 10 caratteri che deve essere sostituito, ha bisogno di 10 redirect a farlo.

Dal momento che questo potrebbe non essere la soluzione migliore, è possibile fare tutte le sostituzioni, tranne l'ultimo interno utilizzando il N bandiera e solo l'ultimo sostituzione esternamente con un reindirizzamento:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /(([^?%\ ]|%(2[1-9a-fA-F]|[013-9][0-9a-fA-F]))*)%20(([^?%\ ]|%(2[1-9a-fA-F]|[013-9][0-9a-fA-F]))*%20[^?\ ]*)
RewriteRule ^ /%1+%4 [R=301,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?\ ]*)%20([^?\ ]*)[?\ ]
RewriteRule ^ /%1+%2 [R=301,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?'\ ]*)'([^?'\ ]*'[^?\ ]*)
RewriteRule ^ /%1\%27%2 [N,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?'\ ]*)'([^?'\ ]*)[?\ ]
RewriteRule ^ /%1\%27%2 [R=301,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?(\ ]*)\(([^?(\ ]*\([^?\ ]*)
RewriteRule ^ /%1\%28%2 [N,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?(\ ]*)\(([^?(\ ]*)[?\ ]
RewriteRule ^ /%1\%28%2 [R=301,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?)\ ]*)\)([^?)\ ]*\)[^?\ ]*)
RewriteRule ^ /%1\%29%2 [N,NE]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^?)\ ]*)\)([^?)\ ]*)[?\ ]
RewriteRule ^ /%1\%29%2 [R=301,NE]

Ma usando l' N bandiera può essere pericoloso in quanto non incrementa il contatore ricorsione interno e quindi può facilmente portare a ricorsione infinita.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top