2010-10-14 4 views
5

Testuję moją aplikację Zend Framework przy użyciu Selenium i PHPUnit. Mam test, który musi otworzyć URL zawierający zakodowany adres URL.Zend Framework: Apache dekoduje zakodowany adres URL zamiast przekazywać zakodowany adres URL?

$redirectToLocation = urlencode('/myothercontroller/action'); // %2Fmyothercontroller%2Faction 
$this->openAndWait('/controller/action/thenRedirectTo/' . $redirectToLocation); 

Ale kiedy uruchomić mój test, przeglądarka próbowała otwarcie zdekodowany URL:

/controller/action/thenRedirectTo//myothercontroller/action 

Co należy zrobić, aby uzyskać selen, aby otworzyć zakodowane URL?

Aktualizacja: Właściwie ... Okazuje się, selen robi to zadanie, ale wydaje się, że Apache jest dekodowanie URL zanim dotrze do regulatora:

The requested URL /controller/action/thenRedirectTo//myothercontroller/action was not found on this server. 

Jak mam rozwiązać ten problem ?

Aktualizacja: Oto cała rozmowa na temat tego samego problemu, który mam: http://old.nabble.com/URL-Encoding-td18850769.html. Ich obejście polegało na zakodowaniu adresu URL w base64, ale to mi nie wystarcza. Mogę użyć tego rozwiązania w krótkim czasie, ale chcę wiedzieć, jaka jest prawdziwa przyczyna tego problemu, więc mogę go wyeliminować.

Aktualizacja: Mam współpracownika, który uważa, że ​​może istnieć problem ze sposobem kierowania żądania przez Zend Framework. Myślisz, że tak może być?

Odpowiedz

0

Interesujący problem. Osobiście nigdy nie miałem problemów z przekazaniem innego adresu URL w ciągu zapytań, tj./Controller/action/thenRedirectTo? Q =% 2Fyothercontroller% 2Faction, ale nie używałem Apache od dłuższego czasu, a to nie jest dokładnie to, co Ty " próbuję to zrobić.

Jednym z możliwych rozwiązań może być podwójne kodowanie adresu URL.

$redirectToLocation = urlencode(urlencode('/myothercontroller/action')); 
$this->openAndWait('/controller/action/thenRedirectTo/' . $redirectToLocation); 

Być może Apache urluje się tylko pod kątem dekodowania go o jeden poziom.

+1

Nie próbowałem tego, ale to może działać. Jednak wolałbym, aby Apache działał poprawnie, zamiast zhakować mój kod. – Andrew

+0

To brzydkie rozwiązanie. Zgadzam się, że Apache nie powinien z tym mieszać. Z pewnością jest to w jakiś sposób konfigurowalne? – mcv

0

Napotkałem to zachowanie wcześniej i to było mod_rewrite, który robił dekodowanie. O ile wiem, jedynym sposobem na obejście tego jest urlencode część adresu URL żądania, który musi zachować znaki specjalne dwa razy.

0

należy ustawić w trybie debugowania mod_rewrite w Apache i patrzeć na to, co robi:

RewriteEngine on 
RewriteLog /tmp/rewrite.log 
RewriteLogLevel 9 

i pokazać nam swoją ZF przepisać reguł. to na pewno bazuje na% {QUERY_STRING}, który jest dobrze zdekodowanym adresem URL. Możemy spróbować przerobić go za pomocą% {THE_REQUEST}, który jest nieodkodowanym adresem URL. Najlepiej traktować% {THE_REQUEST} tylko dla właściwego kontrolera.

Innym rozwiązaniem może być użycie kodowania base64 na url, dzięki czemu mod_rewrite i jakiekolwiek inne narzędzia nigdy nie złapią go jako informacji o adresie URL.

Kolejną rzeczą do przetestowania jest [B] na mod_rewrite, jak wyjaśniono tutaj: How to encode special characters using mod_rewrite & Apache?. Ale zastanawiam się, czy nie złamałoby to zasady przepisywania.

0

Wygląda na to, że Zend Framwork issue dotyczy Twojego problemu. Aby zweryfikować otwarcie Zend/Controller/Request/Http.php i usunąć wywołania funkcji Urdecode, ale utrzymuj zmienne w miejscu i ponownie przetestuj swój kod.

2

To jest "funkcja" Apache. Zakodowane ukośniki są automatycznie dekodowane i wysyłane do aplikacji (php). Dlatego jest rozpoznawany jako jeden długi URI zamiast URI z zakodowanym URI jako parametrem.

Mimo to można to wyłączyć, korzystając z konfiguracji AllowEncodedSlashes On. Więcej informacji pod adresem Apache manual. Zwróć uwagę, że kontekst tej dyrektywy to konfiguracja serwera i host wirtualny, więc nie możesz umieścić go w pliku .htaccess.