• CORS woes on Heroku

    ,

    After spending the past 4 hours attempting to solve what boiled down to a rather simple problem, I figure I’d better blog about it to save someone else the time and effort.

    If you’ve been leveraging Passenger’s new –nginx-config-template command line option to add CORS headers to static assets served from a Rails app hosted on Heroku, and the CORS headers recently disappeared under mysterious circumstances… read on.

    I’ve been using the method described here to add CORS headers to custom fonts served from a Heroku-hosted Rails app that’s proxied by Nginx which handles serving static files. I recently updated to Rails 4.2.2 and suddenly, my custom fonts (.woff and .woff2 files) no longer had CORS headers on them.

    After the aforementioned hours spent scratching my head, I discovered that the latest version of the sprockets gem is generating asset digests that are 64 chars in length, where previously they had been 32. Nginx’s default regexp for identifying requests for static assets assumes the digest will be 32 chars long, like so:

    # Rails asset pipeline support.
    location ~ "^/assets/.+-[0-9a-f]{32}\..+" {
      error_page 490 = @static_asset;
      error_page 491 = @dynamic_request;
      recursive_error_pages on;</code>
    
      if (-f $request_filename) {
        return 490;
      }
      if (!-f $request_filename) {
        return 491;
      }
    }
    

    Changing the regexp to recognize digests that are 64 chars in length immediately solved the problem:

    location ~ "^/assets/.+-[0-9a-f]{64}\..+" {
       ...
    }
    

    I had to laugh after something so stupid and silly cost me a good chunk of my Saturday to debug. But at least it’s working now. My statically served custom fonts have the correct CORS headers and Chrome and Firefox are happy again.


Need help?

I’m an independent software developer available for consulting, contract work, or training. Contact me if you’re interested.


  • Career 2.0 book mention

    Mark Mzyk gave a brief review of Career 2.0, the book by Jared Richardson that I contributed to, over on his blog. He also recommends The Passionate Programmer by Chad Fowler, another excellent career-boosting read. (If you’ve posted a review of Career 2.0 on your own blog, let me know.)

  • Auto timeout sessions in Rails

    Time Out!I released the initial version of my auto-session-timeout plugin for Rails at West End Ruby tonight.

    Have you ever wanted to force your users off your app if they go idle for a certain period of time? Many online banking sites use this technique. If your app is used on any kind of public computer system, this type of functionality is essential for maintaining the privacy of your data.

    After installing the plugin, a small snippet of JavaScript is placed on each page. The JS polls the server every minute to see if the session is still active. If the user has been idle for at least an hour, they are immediately redirected to a timeout page. The session will not timeout as long as the user keeps clicking around. The timeout and polling intervals are both configurable.

    The plugin is dead simple to install and configure. To get started:

    script/plugin install git://github.com/pelargir/auto-session-timeout.git
    

    Then hit the README for step-by-step instructions.

  • Introducing my latest Rails app: Fuelinator

    Gas CanI started building Fuelinator at the last West End Ruby meetup. The motivation behind the project was the lack of a decent system for tracking my business mileage. Existing apps like Fuelly and My Mile Marker make it unnecessarily difficult to enter mileage, and the statistics they produce just aren’t that useful to me.

    My initial goal with Fuelinator is to make mileage entry dead simple and to provide some compelling new features… for example, alerts via email or SMS when my vehicle’s mileage changes suddenly. This helps me track down maintenance problems early and gives me valuable information about what does and doesn’t improve my gas mileage. For example, I changed my air filter and inflated my tires last week. If my mileage changes drastically this week, I want to know. Now, Fuelinator will tell me.

    The ultimate goal is for Fuelinator to save its users gobs of money on their gas bills. I haven’t made Fuelinator public yet, but if you’d like to participate in the beta program make sure you sign up. It’s going to be a fun ride!

  • How to safely transpose Ruby arrays

    Ruby arrays have this handy method called transpose which takes an existing 2-dimensional array (i.e. a matrix) and flips it on its side:

    >> a = [[1,2], [3,4], [5,6]]
    >> puts a.transpose.inspect
    [[1, 3, 5], [2, 4, 6]]
    

    Each row becomes a column, essentially. This is fine and dandy for polite arrays. If one of the rows in the original array is not as long as the others, though, Ruby chunders thusly:

    >> a = [[1,2], [3,4], [5]]
    >> a.transpose 
    IndexError: element size differs (1 should be 2)
    	from (irb):3:in `transpose'
    	from (irb):3
    

    That ain’t pretty, especially if the intent behind using transpose is to render data in a nice columnar fashion. For example, what if we wanted to render a list of high school courses in columns, one column per semester? Grouping the courses by semester and then transposing would do the trick, but only if there were exactly the same number of courses taken each semester. If even one semester differs, Ruby will blow up. What we really want is for Ruby to just ignore the fact that each grouping may have differently sized arrays and transpose anyway, filling in the empty spaces with nils.

    Here’s how to do just that:

    class Array
      def safe_transpose
        result = []
        max_size = self.max { |a,b| a.size <=> b.size }.size
        max_size.times do |i|
          result[i] = Array.new(self.first.size)
          self.each_with_index { |r,j| result[i][j] = r[i] }
        end
        result
      end
    end
    

    Now we call safe_transpose on our matrix of courses and Ruby does the right thing. It calculates the length of the longest row and uses that as the baseline to perform the transposition. So our original example becomes:

    >> a = [[1,2], [3,4], [5]]
    >> puts a.transpose.inspect
    [[1, 3, 5], [2, 4, nil]]
    

    Nice and neat. Caveats: the code above hasn’t been refactored or tested. Your mileage may vary. If you see a better way to do this, let me know and I’ll post an update.