iCoreTech Research Labs Just a placeholder

22Oct/093

Foundation.j and AppKit.j 404

During some Rails integration with Cappuccino I noticed that my Rails' logs were filling fast with 404s.

At first I thought I did something wrong in including my Frameworks, however it turns out that's a normal behaviour by design.

I won't go into the details here on why it's happening, but here's a solution:

Ruby on Rails

To avoid the stack trace generation overhead in Rails simply put down those routes:

  map.connect '/Frameworks/Foundation/Foundation.j',
    :controller => 'application',
    :action     => 'handle_cappuccino_404',
    :conditions => { :method => :get }
  map.connect '/Frameworks/AppKit/AppKit.j',
    :controller => 'application',
    :action     => 'handle_cappuccino_404',
    :conditions => { :method => :get }

Then in your handle_cappuccino_404 method you can simply render :nothing => true:

class ApplicationController < ActionController::Base
  def handle_cappuccino_404
    render :nothing => true
  end
end

I think we can't rescue_from ActionController::RoutingError at this point.
Please also read another solution involving Rails Metal below.

Rails Metal

I was thinking about using Rails Metal to avoid even the extra bits:

script/generate metal cappuccino

Then in app/metal/cappuccino.rb:

require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
 
class Cappuccino
  def self.call(env)
    if env["PATH_INFO"] =~ /^\/Frameworks\/Foundation|AppKit\/Foundation|AppKit.j/
      [200, {"Content-Type" => "text/html"}, []]
    else
      [404, {"Content-Type" => "text/html"}, ["Not Found"]]
    end
  end
end

No need for the method described above: you can safely remove routes and the 404 handling method from your controller.

Sinatra

To avoid it in Sinatra:

# from http://github.com/mchung/cappuccino_sandbox
get "/Frameworks/AppKit/AppKit.j" do
  [404, {}, "Look elsewhere"]
end
get "/Frameworks/AppKit/Foundation.j" do
  [404, {}, "Look elsewhere"]
end

No related posts.

Comments (3) Trackbacks (0)
  1. Yes, I believe the rack metal solution is optimal for performance and to keep the app’s routes & application controller clean. Well done.

    I think its safe to simplify the if condition to a single regex match if you use this one instead:

    if env["PATH_INFO"] =~ /^\/Frameworks\/Foundation|AppKit\/Foundation|AppKit.j/

  2. Jerod, as you may have noticed I’m terrible at regex :)
    I’m updating the code, thanks for your valuable contribution!

  3. I am so glad you figured this out… I didn’t… I wish I had seen this sooner :) Thanks


Leave a comment


No trackbacks yet.

Additional comments powered by BackType