• 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.


  • Autumn beauty at Hanging Rock

    In November, I was blessed with the opportunity to visit Hanging Rock State Park with some friends from church. Though the fall colors were past peak, it was still an enjoyable and invigorating hike. I took this video clip from the top of Hanging Rock with my iPod Nano. It was a very windy day. The view off the southern side was clear enough that I could see Winston-Salem. What a beautiful experience!

    “The heavens declare the glory of God, and the sky above proclaims his handiwork. Day to day pours out speech, and night to night reveals knowledge.” Psalm 19:1-2

    “For what can be known about God is plain to them, because God has shown it to them. For his invisible attributes, namely, his eternal power and divine nature, have been clearly perceived, ever since the creation of the world, in the things that have been made. So they are without excuse.” Romans 1:19-20

  • test_spec_on_rails now runs on Rails 2.3

    If anyone still happens to be using test_spec, you’ll be thrilled to know that the test_spec_on_rails plugin is now compatible with Rails 2.3. It has also been converted to a gem. Install with:

    sudo gem install test_spec_on_rails
    

    Add to your Rails app’s test.rb like so:

    config.gem 'test_spec_on_rails'
    

    Enjoy the goodness of test-spec helpers from inside your Rails tests. Fork and submit patches via the GitHub project. Tell your friends. Donate money. Vote for Pedro.

  • Processing malformed files with FasterCSV

    On a recent project, I had to implement a CSV parser that would gracefully handle malformed files. I’m talking about files with unescaped quotes, wacky UTF-8 chars, and various other abominations of nature.

    I originally assumed FasterCSV would handle this automagically, but it turns out that the library’s most commonly used methods are pretty strict when it comes to handling CSV files.

    For example, parsing a malformed file one line at a time will result in an exception being thrown, even before any rows are yielded to the block:

    FasterCSV.foreach("malformed.csv") do |row|
      # use row here...
    end
    

    Not cool! I managed to get around this by manually looping over each row and rescuing a malformed CSV exception if one gets thrown:

    FasterCSV.open("malformed.csv", "rb") do |output|
      loop do
        begin
          break unless row = output.shift
          # use row here...
        rescue FasterCSV::MalformedCSVError => e
          # handle malformed row here...
        end
      end
    end
    

    Anyone have a better way to do this?

  • Time warping gem goodness

    The time zone warp code I posted about last week is now a gem:

    sudo gem install time-zone-warp
    

    To configure in your Rails app, add this line to the bottom of test.rb:

    config.gem 'time-zone-warp', :lib => 'time_zone_warp'
    

    You can also fork the code from the project on GitHub.