Zend Framework: Apache decoding encoded URL instead of passing encoded URL?
I am testing my Zend Framework application using Selenium and PHPUnit. I have a test that needs to open a URL that 开发者_如何学Ccontains an encoded URL.
$redirectToLocation = urlencode('/myothercontroller/action'); // %2Fmyothercontroller%2Faction
$this->openAndWait('/controller/action/thenRedirectTo/' . $redirectToLocation);
But when I run my test, the browser tried opening the decoded URL:
/controller/action/thenRedirectTo//myothercontroller/action
What should I do to get selenium to open the encoded URL?
Update: Actually...turns out selenium is doing it's job, but it seems as if Apache is decoding the URL before it gets to the controller:
The requested URL /controller/action/thenRedirectTo//myothercontroller/action was not found on this server.
How should I fix this problem?
Update: Here's a whole conversation about the same problem that I'm having: http://old.nabble.com/URL-Encoding-td18850769.html. Their workaround was to base64 encode the url, but that's not good enough for me. I may use this solution in the short term, but I want to know what is the real cause of this problem, so I can eliminate it.
Update: I have a co-worker who thinks there may be a problem with the way Zend Framework is routing the request. Do you think that could be the case?
This is an Apache "feature". Encoded slashes are automatically decoded and sent to the application (php). Therefore it's recognized as one long uri instead of an uri with an encoded uri as parameter.
Nevertheless, it's possible to turn this off, by using AllowEncodedSlashes On
in your configuration. More information at the Apache manual. Please note the context of this directive is server config and virtual host so you cannot place it in a .htaccess file.
Interesting problem. I've personally never had any problems passing another URL in a query string, i.e. /controller/action/thenRedirectTo?q=%2Fmyothercontroller%2Faction , but I haven't used Apache in a long time, and that's not exactly what you're trying to do.
One possible solution could be double url encoding it.
$redirectToLocation = urlencode(urlencode('/myothercontroller/action'));
$this->openAndWait('/controller/action/thenRedirectTo/' . $redirectToLocation);
Perhaps Apache will only url decode it one level.
I've encountered this behavior before and it was mod_rewrite that was doing the decoding. As far as I know the only way to get around it is urlencode the portion of the request URL that needs to preserve special characters twice.
It looks like this Zend Framwork issue relates to your problem. To verify open up Zend/Controller/Request/Http.php and remove the urldecode function calls but keep the variables in place and retest your code.
You should set your mod_rewrite in debug mode in Apache and look at what he does:
RewriteEngine on
RewriteLog /tmp/rewrite.log
RewriteLogLevel 9
and show us your ZF rewrite rules. it's quite certainly base on %{QUERY_STRING} which is the competly decoded url. We could try to rework it with %{THE_REQUEST}, which is the non-decoded url. The best thing would be treating %{THE_REQUEST} only for the right controller.
Another solution could be using base64 encoding on the url, so that mod_rewrite and any other tools would never catch it as an url information.
Another thing to test is the [B] on mod_rewrite, as explained here : How to encode special characters using mod_rewrite & Apache? . But I wonder is would would not break the rewrite rule.
精彩评论