Archive for August, 2009

Request Translation

Request: Can you give me expected adoption rates of the new XYZ feature so we can estimate whether we have sufficient capacity to handle incoming traffic?

Translation: Can you pretend to understand the unknowable well enough to pull a random but superficially believable number out of your ass which I will crucify you with later on if it turns out that whatever I did to prepare was insufficient and/or people generally believe that the failure was my fault.

0 comments

Update on nginx and Piwik

In my previous post I summoned some hackish magic to fix something that I didn’t really understand. That’s usually not good practice. Most experienced developers have a well-tuned b.s. detection system and will return to unnecessarily hackish code almost as a matter of necessity. That was the case here, and what I found was that the error was in my nginx conf file. For whatever reason I had nginx misconfigured and content JavaScript, CSS, and SWF files were being served up by fast-cgi instead of being handled by nginx directly. Here’s a relevant section of my updated conf file:

# Stop Image and Document Hijacking
# Also have to handle these file types for piwik before they get processed by PHP below
location ~* (\.jpg|\.png|\.css|\.gif|\.jpeg|\.js|\.swf)$ {

   if ($http_referer ~* ^(http://my.domain.com) ) {
      expires max;
      break;
   }

   return 444;

}

location / {

   root   /home/public_html/my.domain.com/public/;
   index  index.php index.html;

   # this serves static files that exist without running other rewrite tests
   if (-f $request_filename) {
      expires max;
      break;
   }

   fastcgi_pass 127.0.0.1:9000;
   fastcgi_index index.php;
   include /usr/local/nginx/conf/fastcgi_params;
   fastcgi_param SCRIPT_FILENAME /home/public_html/my.domain.com/public/$fastcgi_script_name;
   include fastcgi_params;
}

Everything got better after that. Not sure who I thought I was fooling with my first solution, but it didn’t even work on myself.

2 comments

Nginx, Piwik, and Content Type Headers

Note this Update: read update

I decided to give Piwik a try as my web analytics tool. I’ve used Mint in the past and am mostly happy with it, but I sometimes feel Shaun Inman has no sense of urgency to make improvements to catch up to the big guys. I also considered Google Analytics and GetClicky but can’t get over the idea of someone else owning my analytics data. Sure, that’s fine for my blog or other smaller sites, but for something “important”, I’d rather hold onto it myself.

Piwik installation was pretty straightforward, typical fare these days. First thing I noticed was that the site was completely broken in FireFox, but seemed to work fine in IE. Firing up Charles I saw 2 things that smelled wrong:

  1. Requests for JavaScript and CSS files had a cache-busting query parameters stuck on the end of it, e.g. /piwik/themes/default/common.css?piwik=0.4.2. The idea here is that they can set a far-futures expires header on that file and let the browser cache it forever. When they release a new version of the site, they increment the version number on the request parameter and the browser goes and fetches the new styles or scripts. I thought this was an interesting technique, but possibly confusing nginx because….
  2. The “Content-Type” header was coming back as “text/html” for both JavaScript and CSS files.

IE doesn’t seem to mind that the content type was set incorrectly but Firefox refused to apply the styles because of it. So I started tinkering to see what I could do. Worst case scenario I would just have to use piwik only in IE, but that seemed kind of defeatist. Strangely, no one else on the interwebs seemed to be having the same issue, which lead me to think it was something specific to my environment.

The first thing I tried was to remove the cache busting request parameter by commenting out this line of code in the piwik source code:

$this->smarty->load_filter(‘output’, ‘cachebuster’);

I found that line in the file core/View.php on line 54 in version 0.4.2. That got rid of the cache busting query parameter, but didn’t fix the content type issue, so I ended up putting that line back in. I tried dropping one of the CSS files I was testing on another server and requesting that to see the headers. They turned out to be fine, at which point I decided it had to be an nginx issue. A couple of hacky attempts later I came up with the idea of just adding another header to JavaScript or CSS files as such:

   if ( $request_filename ~* (\.css) ){
      add_header Content-Type "text/css; charset=UTF-8";
      break;
   }

   if ( $request_filename ~* (\.js) ){
      add_header Content-Type "application/x-javascript; charset=UTF-8";
      break;
   }

That seems to work. Not entirely thrilled about it since I still don’t fully understand why it’s happening. Two Content-Type headers are getting set, but Firefox is ok with that for now. Oh well.

Note this Update: read update

3 comments