views:

116

answers:

3

SOLVED:

This URI works:

/controller/action?ret=%2F

I want to pass an additional "/" parameter to the controller action. So I did this:

$par1 = urlencode('/');
$this->_redirect('/controller/action/par1/' . $par1);

But I get this error message:

Not Found

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

When I call the controller action without any parameters or with parameter "aaa" it works. These URIs work:

/controller/action
/controller/action/par1/aaa
/controller/action/par1/jfhsdajkhfui454fs
/controller/action/par1
/controller/action/par1/

You can put http://example.com in front of all relative URIs above and it's the same.

+2  A: 

Try %2F. I don't think urlencode is going to encode '/' because it's valid URL syntax.

[Edit]: appreciate the votes but it appears my answer is incorrect. See bobince's correct (and much more detailed) answer below above.

Renesis
`urlencode` does encode `/`.
bobince
+1  A: 

see rawurlencode

knittl
+7  A: 

You are almost doing it right. The only slight mistake is that urlencode will prefer to use a plus to signify a space, which is only appropriate in query parameters and not path part. rawurlencode would be better here.

However, that's not the reason it doesn't work. You are already generating the path /controller/action/par1/%2F, which is correct.

It doesn't work in practice for you because Apache is trying to protect you (in a rather ineffective way) from directory traversal problems. If you include a %2F sequence in a URL path, Apache will by default jump in and show your its own 404 page (ignoring any errordocument settings). To turn this feature (IMO: misfeature) off, you can use the AllowEncodedSlashes configuration directive.

Whether you can actually retrieve the encoded slash when it comes back to your script is another can of worms. Due to the bad design of the PATH_INFO variable in the original CGI spec, many environments won't be able to see the %2F as being anything different from an unencoded /, potentially breaking routing you're doing from path parts.

It is usually best to avoid having slashes in path parts, because Apache is not the only server or language that will get confused by them. In general you should use query parameters for input where you need to be able to accept any string of bytes or characters, because path parts have practical problems in many servers with (a) /, (b) \, (c) the NUL character and (d) empty strings.

bobince
I actually managed to solve this by using URI like this: /controller/action?ret=%2F :)
Richard Knop
Very informative answer, bobince. I wasn't familiar with the AllowEncodedSlashes config option, myself.
Brian Lacy