qoobaa

Karma Chameleon

Submitted by qoobaa at 12 Oct 13:42
Hide details

About

client: there’s a huge project to be done for a lot of money
ror developer: great!
client: there’s only one requirement – it has to be written in ASP/PHP/JSP/…
ror developer: uhm, sorry – we use Rails
client: can’t be, it has to be stable and scalable. Rails can’t scale!

Sounds familiar? Are you thinking about switching to the other framework? Now you don’t need to – we come up with a great solution!

KARMA CHAMELEON – it’s a middleware that adds the “.aspx”, “.php” or any other (configurable) extension to your application’s URIs. Helps to switch the technology of your app in few seconds, ridiculously easy! We also think about additional middleware that could provide:

  • HTML obfuscation, with indentation breaking support
  • adding useless inline CSS/JavaScript
  • adding random (undocumented) tags and attributes

Stay in touch and sing with us: Karma, Karma, Karma, Karma, Karma Chameleooon

Authors: Jakub Kuźma, Mirosław Boruta, Wojciech Wnętrzak, Szymon Nowak

Usage

use KarmaChameleon, :extension => “jsp”

Code

require "rubygems"
require "nokogiri"
require "uri"
 
module Rack
  class KarmaChameleon
    def initialize(app, options = {})
      @ext = options[:extension] || "aspx"
      @ext_regexp = /\.#@ext$/
      @app = app
    end
 
    def call(env)
      if env["PATH_INFO"] =~ @ext_regexp || env["PATH_INFO"] == "/"
        env["PATH_INFO"] = remove_ext(env, env["PATH_INFO"])
        env["REQUEST_URI"] = remove_ext(env, env["REQUEST_URI"])
 
        status, headers, response = @app.call(env)
 
        if (300...400).include?(status) && headers["Location"]
          headers["Location"] = add_ext(env, headers["Location"])
        end
 
        if headers["Content-Type"] =~ /\bhtml\b/
          response = enhance_html(env, response)
          headers["Content-Length"] = response[0].size.to_s
        end
 
        [status, headers, response]
      else
        [404, {"Content-Type" => "text/html"}, ["Not Found"]]
      end
    end
 
    private
 
    def add_ext(env, path)
      uri = URI.parse(path)
      if uri.relative? || uri.host.casecmp(env["SERVER_NAME"]) && uri.port == env["SERVER_PORT"].to_i
        uri.path = uri.path.sub(/\/$/, "") + ".#@ext" unless uri.path == "/"
      end
      uri.to_s
    end
 
    def remove_ext(env, path)
      uri = URI.parse(path)
      uri.path = uri.path.sub(@ext_regexp, "/")
      uri.to_s
    end
 
    def enhance_html(env, response)
      body = ""
      response.each { |res| body += res }
      doc = Nokogiri::HTML(body)
 
      doc.css("a").each { |link| link["href"] = add_ext(env, link["href"]) if link["href"] }
      doc.css("form").each { |form| form["action"] = add_ext(env, form["action"]) if form["action"] }
 
      response = [doc.to_s]
    end
  end
end
 
view raw gistfile1.rb This Gist brought to you by GitHub.
blog comments powered by Disqus