Friday, June 20, 2014

Captcha never changed (securimage)

It took a while of testing before I noticed, then I finally realized the captcha on a web app I was working never changed!

Thankfully, before launching into some heavy-duty troubleshooting, I had a flash of inspiration: to make my unit tests work nicely I was setting the random seed to a constant (i.e. to get repeatable test data). That test data is actually being generated for every page request of the main web app (just during development).

So the fix was as trivial as calling mt_srand(time());  just before creating the Captcha  (as I'm using the Securimage library, just before the $img = new Securimage(); call).

If only all troubleshooting was this quick!

Saturday, May 24, 2014

Iterate a map in added order, not key order, using C++11

I’m loving C++11. Most of the things only save you a few keystrokes. But C++ was a verbose language, and those saved keystrokes mean the code becomes more readable and more maintainable.
Here is a quick example refactor. I had some key-value pairs, and was using a std::map (I’ve shown the value type as T to avoid cluttering this example):
std::map< std::string, T> data;
...
data [ key ] = value;
...
for(const auto &entry : data){
    std::cout<<"Label:" << entry.first << "\n";
    std::cout<< entry.second.something << "\n";
    }
You can see I’m already using a C++11-ism, with the range-based for loop, and auto. That is so much nicer that I’m not even going to show you the old way it would’ve been done.
The problem was I didn’t want to iterate through the map in key order, I wanted to iterate through in the order the items was added. My first idea was to switch to using two vectors, one for the keys, one for the values. But parallel data structures are a nasty code smell.
Then I thought of using std::pair. And the above code became this:
std::vector< std::pair<std::string, T> > data;
...
data.push_back( {key,value} );
...
(as above)
First thing to observe is that even though the data structure is now completely different, my for(){...} loop is completely the same. This was partly luck: a std::map iterator has first and second elements, and so does a std::pair. But we also need to give a big thanks to auto: it saved us having to even think about what the new iterator type is.
Did you spot the second C++11-ism? It slipped by so naturally it might not even have registered. Here it is: {key,value}
In earlier versions of C++ I would have had to write:
data.push_back( std::make_pair(key,value) );
Only 14 keystrokes saved, but those 14 were pure distraction, and won’t be missed.
(This refactor is the correct approach in older versions of C++ too, by the way. All C++11 brings to the party is that it is now easier to do.)
Written with StackEdit.

Sunday, April 27, 2014

PHP Date vs. gettimeofday

I just had a lot of trouble with a unit test failing. Unfortunately lots of things had changed: new computer, new linux distro, new version of PHP (from 5.3 to 5.5), new version of PHPUnit (from 3.4 all the way to 4.0 then back to 3.7), etc.

I eventually tracked it down; and made this minimal example:

for($n=0;$n<250;++$n){
        $t = time();
        $s = date("Y-m-d H:i:s");
        $tod = gettimeofday();
        echo "$t,$s,{$tod['sec']},{$tod['usec']},".
          date("Y-m-d H:i:s")."\n";
    usleep(10000);  //0.01s
    }

It is getting the time 100 times a second, and comparing with time(), date() and gettimeofday(). I’ll just show the interesting bit:

1398601641,2014-04-27 21:27:21,1398601641,972424,2014-04-27 21:27:21
1398601641,2014-04-27 21:27:21,1398601641,982545,2014-04-27 21:27:21
1398601641,2014-04-27 21:27:21,1398601641,992669,2014-04-27 21:27:21
1398601641,2014-04-27 21:27:21,**1398601642**,2793,2014-04-27 21:27:21
1398601642,2014-04-27 21:27:22,1398601642,12919,2014-04-27 21:27:22
1398601642,2014-04-27 21:27:22,1398601642,23041,2014-04-27 21:27:22

I’ve highlighted the problem point. It appears gettimeofday() is slightly ahead of time() (and date() is always consistent with time()). More precisely, for the first 10000 microseconds of each second, time() is still in the previous second.

My unit test was watching gettimeofday() to wait for a new second to roll by. But the code being tested was using date to get a timestamp. (That timestamp was then used as a unique ID for a database insert, and the unit test asserted it was always an insert, not an update!)

Fascinating stuff, eh? I’ve no idea if this is a behaviour change in PHP, or if this new machine is simply a bit quicker, and the problem never cropped up before. However I doubt the latter as the unit test now fails 100% of the time, but never failed this way before.

Oh, the fix? Simply changed the calls to gettimeofday() to time(). To be honest I’ve no idea why I used the more complicated function in the first place.

Friday, April 11, 2014

Using RewriteRule instead of Alias in .htaccess

Subtitle: Why aren't Apache rewrites working?!?!?!?!

I had a few directories (e.g. each a mini website or webapp) sharing a fonts directory, and I was doing this with symlinks. But symlinks are a pain to rsync, so I thought let's use Apache to do the symlinking, i.e. use Alias. I put this in .htaccess:

  Alias /mysite/fonts/ ../shared/fonts/

500 Internal Server Error.

Or, in other words, Alias cannot be used in .htaccess, only in httpd.conf. I could've done it that way (added the Alias to httpd.conf) but as I was already using RewriteRule in the .htaccess file I decided to persevere finding a way to do it using just the .htaccess file.

This was my first attempt:

   RewriteRule ^/mysite/fonts/(.*)$ /shared/fonts/$1  [L]

Completely ignored. Now, when you start googling, or searching on StackOverflow, for "Apache rewrite does not work", 99% of the hits will tell you how to turn it on. I.e. you need AllowOverride All in your httpd.conf, which allows you to use .htaccess files, and you need Options FollowSymLinks so that the rewrite engine will work. And you need RewriteEngine On in your .htaccess file.


Unfortunately I'd done all those things. I knew the rewrite engine was working, as I had other rules in this same .htaccess file, and commenting them out changed behaviour. My problem was that my new rewrite rule was just being ignored, even though it looked correct.


I'll spare you the pain of seeing the 187 other experiments I tried. The forehead-slap moment came when I realized the first parameter of the rewrite rule is relative to the directory the .htaccess file is in. I.e. my .htaccess file is in the /mysite/ directory. And, thus, the correct rule turned out to be:

   RewriteRule ^fonts/(.*)$ /shared/fonts/$1  [L]

Note the lack of leading forward slash. Very important. Incidentally, the second parameter is relative to the server root if you start it with a forward slash! In other words, it is only the first parameter that doesn't work that way.

The [L] at the end of the RewriteRule means "last", and is normally what you want for this kind of rewrite rule. Use [R] ("redirect") instead if you wanted the URL to be rewritten (i.e. an HTTP redirect to be sent back). Useful troubleshooting tip: if you set the flag to [F] then you can immediately see if the first parameter to the rule is being recognized: if it is getting matched, you get a 403 (and if you don't then you have to fix the first parameter). If you get a 403 with an [F], but don't get the expected results when you change the the [F] to an [L] then it is the second parameter you need to fix.

So, to summarize, if your .htaccess file is in a subdirectory, remember that the RewriteRule has to be relative to that subdirectory.