Archive for January, 2008

Avoid escaping URLs in Apache rewrite rules

Thursday, January 24th, 2008

Today we started hacking some Apache rewrite rules to make some URLs a little more friendly. All of the URLs we are rewriting are entry points for our application, which in the WO world means direct actions.

All of them contain queries parts. These are the arguments in a URL, like http://domain.com/something?arg=value&anotherArg=anotherValue. Well, everything was running fine until we accessed an URL with a escaped character. We had the following rule:


RewriteRule ^/optOut(.*) /cgi-bin/WebObjects/OurApp.woa/wa/optOut$1 [R]

When we tried to access the URL http://domain.com/optOut?email=me%40domain.com, we got:

http://domain.mac/cgi-bin/WebObjects/OurApp.woa/wa/optOut?email=me%2540domain.com

Note the last part or the URL. The problem is that the original % in %40 (the escape code for @) was being itself escaped, leading to a corrupt URL. The result of calling formValueForKey on this was me%40domain.com.

After googling for a while, I found out many people have this problem, but surprisingly I could not find a decent solution. I saw hacks with escape internal functions and PHP weird variables that obviously wouldn’t help me at all, and I was starting to get nervous.

Well, while reading the rewrite module documentation, I found the solution right there: the NE option. According to the docs:

‘noescape|NE’ (no URI escaping of output)
This flag prevents mod_rewrite from applying the usual URI escaping rules to the result of a rewrite. Ordinarily, special characters (such as ‘%’, ‘$’, ‘;’, and so on) will be escaped into their hexcode equivalents (‘%25′, ‘%24′, and ‘%3B’, respectively); this flag prevents this from happening. This allows percent symbols to appear in the output(…)

Well, this is it. I saw so many pages with people asking about this problem without getting any answers that I was not very confident on this, but I tried to change the rule for:


RewriteRule ^/optOut(.*) /cgi-bin/WebObjects/OurApp.woa/wa/optOut$1 [R,NE]

And that’s it. It’s now working as it should, producing the correct URL:

http://domain.mac/cgi-bin/WebObjects/OurApp.woa/wa/optOut?email=me%40domain.com

Apparently, it’s that simple.

A decent XML validator

Sunday, January 20th, 2008

As written on all the good practice books about development, I write my applications ready for localization. To do that in WebObjects, one should put all the localizable strings in a strings file. In WebObjects applications, a strings file may be written in two formats: the Apple’s weird .plist format and XML. I use XML, because it looks more… well… I don’t really know, but I prefer it.

Anyway, some days ago I did a mistake in one of those files. I did something like: <string>Some String/string>. As you can see, I forgot the < character in the closing tag. When I run the application, all I got was this:


The element type "string" must be terminated by the matching end-tag "".: Parsing failed in line 1155, column 3

This is totally useless, as the line 1155 is actually the line before the last one in the file (the one that closes the “dict” entity). And yes, it’s a big file. Obviously, checking all the lines manually in undoable, even if I only checked the modified ones after the last commit (I added/changed many strings since then). So, the easiest way was to find a XML validator on the web, and hope it would point me the error.

How surprised I was when all the validators I found in the first two result pages pages of Googling for “XML Validator” reported exactly the same error as WebObjects itself. Great. Just great. And finally, I found one validator that saved the day. This guy, although a bit slow, showed me the exact line where the error was. So, bookmark this. Really. It’s the best XML validator around! And yes, just so that you don’t forget the link, let’s just mention it one more time!