Friday, March 30, 2012

HTTP Accept headers for PhoneGap and Rails

Building a PhoneGap mobile application with a Rails backend? You should know about HTTP Accept headers and Rails. The important thing to understand is that best practice in Rails is NOT to use the Accept headers. There is a nice writeup here that explains why in glorious detail. Summary: browser implementation of HTTP Accept headers is broken. Rails best practice is to set the :format parameter in the request. However, if you like the accept headers they are supported but the rules around what is a valid accept header in rails can be tricky. For example: if your accept header matches the following regex:

BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/


Then rails throws it away and defaults to text/html mime type. I know, right? We had a problem with backbone and JQuery. Our application was sending the following accept headers:
application/json, text/javascript, */*; q=0.01
Looking at that you would expect that because we ask for a json response we should get one. Rails returns text/html in this case because our accept headers looks like the kind of thing the browser would send along, thus broken and unreliable. You might be thinking: hey, every other rails app I've built hasn't had this problem. Well, the reason most people don't have this problem is that rails "fixes" the default jquery behavior in the rails jquery-ujs gem. They set a ajaxSetup beforeSend callback in JQuery that puts the */* at the beginning of the header, which is what the magic rails regex wants to see. Here is how I fixed my accept header in JQuery.


$(function() {
$.ajaxSetup({
'beforeSend': function(xhr) {
xhr.setRequestHeader("accept", "appplication/json");
}
});
});

Friday, March 23, 2012

Creating a new Rails app Segmentation Fault on Ruby 1.9.3

Ran across this one today. I was trying to create a new rails app on Ruby 1.9.3.


/Users/oldjosh/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/net/http.rb:799: [BUG] Segmentation fault
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]


It turns out that if you don't compile 1.9.3 against openSSL from macports or some other non-apple source, you end up with a ruby that segfaults when it tries to do ssl. Thus bundler fails to fetch gems when you create a rails app. My fix was to reinstall 1.9.3 and specify where my macports openssl installation was.


$ rvm reinstall 1.9.3 --with-openssl-dir=/opt/local


RVM has another option to get around this if you don't have macports or some other alternative. See their docs for more info. And see the bug that helped me solve my problem.

Wednesday, March 21, 2012

Vimeo's White Screen of Death in IE

Recently I noticed my embedded Vimeo players were all broken in IE. I was getting just a blank white screen. It turns out Vimeo requires you to have Flash version >= 10. That is fine, but unfortunately their player doesn't fail gracefully if you have an older flash version. My VM had Flash 6. It is simple to check for a particular version of flash in JS. That allows us to fail gracefully on behalf of Vimeo. Here is a snippet that can check if the client browser is good enough for vimeo.


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script>
function goodEnufForVimeo(){
var playerVersion = swfobject.getFlashPlayerVersion();
return (playerVersion.major >= 10);
}
</script>