2009-10-19 13 views
10

Sto riscontrando alcuni problemi con il passaggio di un indirizzo di posta elettronica in un URL di un'app di symfony.Symfony: indirizzo di posta elettronica come parametro di richiesta

L'url sembra

example.com/unsubscribe/email/[email protected] 

Sarà sempre come risultato un sfError404Exception, tranne quando viene rimosso il periodo. Dopo aver fatto qualche ricerca su google, l'unica soluzione che ho visto è che htaccess sta bypassando l'url a causa del periodo presente. Tuttavia, quando aggiungo la correzione suggerito di .htaccess, in questo modo:

# we skip all files with .something 
RewriteCond %{REQUEST_URI} \..+$ 
RewriteCond %{REQUEST_URI} [email protected]+ #skip email address 
RewriteCond %{REQUEST_URI} \.epl$ 
RewriteCond %{REQUEST_URI} !\.html$ 
RewriteCond %{REQUEST_URI} !\.rhtml$ 
RewriteRule .* - [L] 

ottengo lo stesso 404. Inoltre restituisce 404 quando uso il front controller direttamente nella URL (example.com/index.php/unsubscribe/email/[email protected]). Ho provato a mettere la versione di escape direttamente nella barra degli indirizzi, ad esempio example.com/unsubscribe/me%40example%2Ecom e questo funziona, ma solo in Firefox, da nessun'altra parte.

Ho passato circa 2 ore in un forum a cercare l'inferno su Google a questo punto e sono a corto di idee.

Qualche idea?

Grazie.

Aggiornamento: Ecco la sezione dedicata del routing.yml:

unsubscribeform: 
    url: /unsubscribe/email/:email 
    param: { module: subscribe, action: index } 

Aggiornamento: Analisi dello stack ... sembra proprio non ottenere alcuna informazione itinerario per andare a me

404 | Not Found | sfError404Exception 
Empty module and/or action after parsing the URL "/unsubscribe/email/[email protected]" (/). 
stack trace 

1. at() 
    in SF_SYMFONY_LIB_DIR/controller/sfFrontWebController.class.php line 44 ... 
      41. 
      42.  if (empty($moduleName) || empty($actionName)) 
      43.  { 
      44.   throw new sfError404Exception(sprintf('Empty module and/or action after parsing the URL "%s" (%s/%s).', $request->getPathInfo(), $moduleName, $actionName)); 
      45.  } 
      46. 
      47.  // make the first request 
2. at sfFrontWebController->dispatch() 
    in SF_SYMFONY_LIB_DIR/util/sfContext.class.php line 159 ... 
     156. */ 
     157. public function dispatch() 
     158. { 
     159.  $this->getController()->dispatch(); 
     160. } 
     161. 
     162. /** 
3. at sfContext->dispatch() 
    in /home/web/htdocs/index.php line 10 ... 
      7. require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'ProjectConfiguration.class.php'); 
      8. 
      9. $configuration = ProjectConfiguration::getApplicationConfiguration(SF_APP, SF_ENVIRONMENT, SF_DEBUG); 
      10. sfContext::createInstance($configuration)->dispatch(); 

11.

+0

+1 come penso che sarò in esecuzione in questo problema così –

risposta

0

Il tuo problema non è con Riscrivi regole. Considerando che Symfony sta generando un'eccezione, la richiesta arriva a Symfony.

È possibile pubblicare il traceback per l'eccezione? Se hai sf_logging_enabled dovrebbe registrare alcune informazioni piuttosto utili per il debug del routing.

+0

Ho aggiunto la traccia per il corpo domanda. – pivotal

+0

Hm, sembra che ottenga l'URL ok. Sf_logging_enabled fornisce dettagli sul perché il tuo percorso non è riuscito? – six8

3

Non so cosa si sta facendo in Symfony ma può aiutare a essere chiaro che quanto segue non è un URL valido:

example.com/unsubscribe/email/[email protected] 

Quello che quasi certamente desidera (e questo è vero per tutti ! browser) è:

http://example.com/unsubscribe/email/me%40example.com 

Nota: il simbolo @ non è sicuro e deve essere codificato, il. il simbolo è comunque sicuro (RFC1738). Se non si sfugge al simbolo @, quasi sicuramente causerà grossi problemi quindi (sfuggendo al. Quasi certamente no, ma non ne hai bisogno, quindi non lo farei).

I problemi si verificano quando non si esegue l'escape perché @ è riservato come separatore quando si passano i parametri di autenticazione (ad esempio http://username:[email protected]/url/). Alcuni parser di URL funzioneranno sul fatto che si intende veramente digitare% 40 se @ si verifica dopo il dominio nell'URL, ma altri no.

Anziché codificare il simbolo @ staticamente, è necessario utilizzare una delle funzioni di codifica URL di PHP sull'indirizzo e-mail (ad esempio "$ emailAddress = urlencode($emailAddress);") per garantire che altri caratteri nell'indirizzo siano correttamente inseriti in escape.Non lasciarti tentare di lasciare questo fino a tardi o "dopo averlo fatto funzionare" fallo dall'inizio e salva te stesso e gli utenti finali un mal di testa! :-)

NB: Esistono diversi modi per codificare gli URL in PHP, quindi sarà necessario leggere la pagina di documentazione per urlencode() e confrontarla con altri approcci come rawurlencode() per assicurarsi che sia ciò che realmente voglio nel tuo caso.

+0

Grazie, stavo progettando di usare una versione di escape di "@", ma purtroppo non sembra essere il problema per me - se la e commerciale è scappata, senza caratteri o completamente assente, il periodo riesce ancora a lanciare off symfony:/ – pivotal

+0

Ah interessante! Penso che tu l'abbia inchiodato lì. Ho dato un'occhiata e sembra che questo accada ad altre persone ed è un 'problema noto' - sembra che le configurazioni .htaccess che vengono con Symfony (o che stanno raccomandando) causino il. da interpretare! Sembra essere coperto in risposta a un messaggio qui: http://www.mail-archive.com/[email protected]/msg08689.html Come non so come Symfony posso diamo un esempio di copia + incolla ma i suggerimenti su come cambiare .htaccess per risolverlo nelle risposte hanno senso - buona fortuna! 8) –

9

Per impostazione predefinita, Symfony tratta . e / come separatori di parametri.
che lo rende molto facile da abbinare un URL in questo modo:

/some/path/:param.:ext 

Ma non aiuta con indirizzi e-mail.

Fortunatamente, è possibile sostituire il separatore . specificando il proprio modello.
Basta aggiungere la linea requirements qui sotto al tuo percorso:

unsubscribeform: 
    url: /unsubscribe/email/:email 
    param: { module: subscribe, action: index } 
    requirements: { email: .+ } 

Il .+ nel requisito è un'espressione regolare che corrisponde nulla. Lo . corrisponde a qualsiasi carattere e lo + significa corrispondere uno o più.

(Testato in Symfony 1.4)

+0

+1 Bella risposta! –

+0

Se usi più parametri dopo l'indirizzo email, puoi usare alternativamente '[^ \ /] +' in modo che non corrisponda alle barre nel percorso. – fyrye

Problemi correlati