refraction 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -0
- data/VERSION +1 -1
- data/init.rb +1 -0
- data/lib/refraction.rb +63 -83
- data/refraction.gemspec +4 -3
- data/spec/refraction_spec.rb +70 -10
- metadata +21 -9
    
        data/README.md
    CHANGED
    
    
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0.1. | 
| 1 | 
            +
            0.1.4
         | 
    
        data/init.rb
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            require "refraction"
         | 
    
        data/lib/refraction.rb
    CHANGED
    
    | @@ -2,83 +2,24 @@ require 'rack' | |
| 2 2 | 
             
            require 'uri'
         | 
| 3 3 |  | 
| 4 4 | 
             
            class Refraction
         | 
| 5 | 
            -
              class RequestContext
         | 
| 6 | 
            -
                attr_reader :env
         | 
| 7 | 
            -
                attr_reader :status, :message, :action
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                def initialize(env)
         | 
| 10 | 
            -
                  @action = nil
         | 
| 11 | 
            -
                  @env = env
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                  hostname = env['SERVER_NAME']   # because the rack mock doesn't set the HTTP_HOST
         | 
| 14 | 
            -
                  hostname = env['HTTP_HOST'].split(':').first if env['HTTP_HOST']
         | 
| 15 | 
            -
                  env_path = env['PATH_INFO'] || env['REQUEST_PATH']
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  @uri = URI::Generic.build(
         | 
| 18 | 
            -
                    :scheme => env['rack.url_scheme'],
         | 
| 19 | 
            -
                    :host   => hostname,
         | 
| 20 | 
            -
                    :path   => env_path.empty? ? '/' : env_path
         | 
| 21 | 
            -
                  )
         | 
| 22 | 
            -
                  unless [URI::HTTP::DEFAULT_PORT, URI::HTTPS::DEFAULT_PORT].include?(env['SERVER_PORT'].to_i)
         | 
| 23 | 
            -
                    @uri.port = env['SERVER_PORT']
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
                  @uri.query = env['QUERY_STRING'] if env['QUERY_STRING'] && !env['QUERY_STRING'].empty?
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                def response
         | 
| 29 | 
            -
                  headers = @headers || { 'Location' => location, 'Content-Type' => 'text/plain' }
         | 
| 30 | 
            -
                  headers['Content-Length'] = message.length.to_s
         | 
| 31 | 
            -
                  [status, headers, [message]]
         | 
| 32 | 
            -
                end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                # URI part accessors
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                def scheme
         | 
| 37 | 
            -
                  @uri.scheme
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                def host
         | 
| 41 | 
            -
                  @uri.host
         | 
| 42 | 
            -
                end
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                def port
         | 
| 45 | 
            -
                  @uri.port
         | 
| 46 | 
            -
                end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                def path
         | 
| 49 | 
            -
                  @uri.path
         | 
| 50 | 
            -
                end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                def query
         | 
| 53 | 
            -
                  @uri.query
         | 
| 54 | 
            -
                end
         | 
| 55 5 |  | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
                end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                # borrowed from Rack Request class, i.e. time to refactor
         | 
| 61 | 
            -
                def ip
         | 
| 62 | 
            -
                  if addr = @env['HTTP_X_FORWARDED_FOR']
         | 
| 63 | 
            -
                    addr.split(',').last.strip
         | 
| 64 | 
            -
                  else
         | 
| 65 | 
            -
                    @env['REMOTE_ADDR']
         | 
| 66 | 
            -
                  end
         | 
| 67 | 
            -
                end
         | 
| 6 | 
            +
              class Request < Rack::Request
         | 
| 7 | 
            +
                attr_reader :action, :status, :message
         | 
| 8 | 
            +
                def method; request_method; end
         | 
| 9 | 
            +
                def query;  query_string;   end
         | 
| 68 10 |  | 
| 69 | 
            -
                 | 
| 11 | 
            +
                ### actions
         | 
| 70 12 |  | 
| 71 13 | 
             
                def set(options)
         | 
| 72 14 | 
             
                  if options.is_a?(String)
         | 
| 73 | 
            -
                    @ | 
| 15 | 
            +
                    @re_location = options
         | 
| 74 16 | 
             
                  else
         | 
| 75 | 
            -
                     | 
| 76 | 
            -
             | 
| 77 | 
            -
                     | 
| 78 | 
            -
                    options | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
                    end
         | 
| 17 | 
            +
                    @re_scheme = options[:protocol] if options[:protocol] # :protocol is alias for :scheme
         | 
| 18 | 
            +
                    @re_scheme = options[:scheme]   if options[:scheme]
         | 
| 19 | 
            +
                    @re_host   = options[:host]     if options[:host]
         | 
| 20 | 
            +
                    @re_port   = options[:port]     if options[:port]
         | 
| 21 | 
            +
                    @re_path   = options[:path]     if options[:path]
         | 
| 22 | 
            +
                    @re_query  = options[:query]    if options[:query]
         | 
| 82 23 | 
             
                  end
         | 
| 83 24 | 
             
                end
         | 
| 84 25 |  | 
| @@ -108,11 +49,39 @@ class Refraction | |
| 108 49 | 
             
                  @message = content
         | 
| 109 50 | 
             
                end
         | 
| 110 51 |  | 
| 52 | 
            +
                ### response
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def response
         | 
| 55 | 
            +
                  headers = @headers || { 'Location' => location, 'Content-Type' => 'text/plain' }
         | 
| 56 | 
            +
                  headers['Content-Length'] = message.length.to_s
         | 
| 57 | 
            +
                  [status, headers, [message]]
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 111 60 | 
             
                def location
         | 
| 112 | 
            -
                  @ | 
| 61 | 
            +
                  @re_location || url
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                def scheme;       @re_scheme || super; end
         | 
| 65 | 
            +
                def host;         @re_host   || super; end
         | 
| 66 | 
            +
                def path;         @re_path   || super; end
         | 
| 67 | 
            +
                def query_string; @re_query  || super; end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def port
         | 
| 70 | 
            +
                  @re_port || ((@re_scheme || @re_host) && default_port) || super
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                def default_port
         | 
| 74 | 
            +
                  case scheme
         | 
| 75 | 
            +
                  when "http"  ; 80
         | 
| 76 | 
            +
                  when "https" ; 443
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                def http_host
         | 
| 81 | 
            +
                  self.port ? "#{self.host}:#{self.port}" : self.host
         | 
| 113 82 | 
             
                end
         | 
| 114 83 |  | 
| 115 | 
            -
              end | 
| 84 | 
            +
              end ### class Request
         | 
| 116 85 |  | 
| 117 86 | 
             
              def self.configure(&block)
         | 
| 118 87 | 
             
                @rules = block
         | 
| @@ -132,20 +101,21 @@ class Refraction | |
| 132 101 |  | 
| 133 102 | 
             
              def call(env)
         | 
| 134 103 | 
             
                if self.rules
         | 
| 135 | 
            -
                   | 
| 104 | 
            +
                  request = Request.new(env)
         | 
| 136 105 |  | 
| 137 | 
            -
                  self.rules.call( | 
| 106 | 
            +
                  self.rules.call(request)
         | 
| 138 107 |  | 
| 139 | 
            -
                  case  | 
| 108 | 
            +
                  case request.action
         | 
| 140 109 | 
             
                  when :permanent, :found, :respond
         | 
| 141 | 
            -
                     | 
| 110 | 
            +
                    request.response
         | 
| 142 111 | 
             
                  when :rewrite
         | 
| 143 | 
            -
                    env["rack.url_scheme"] | 
| 144 | 
            -
                    env["HTTP_HOST"] | 
| 145 | 
            -
                    env[" | 
| 146 | 
            -
                    env[" | 
| 147 | 
            -
                    env[" | 
| 148 | 
            -
                    env[" | 
| 112 | 
            +
                    env["rack.url_scheme"]  = request.scheme
         | 
| 113 | 
            +
                    env["HTTP_HOST"]        = request.http_host
         | 
| 114 | 
            +
                    env["SERVER_NAME"]      = request.host
         | 
| 115 | 
            +
                    env["HTTP_PORT"]        = request.port if request.port
         | 
| 116 | 
            +
                    env["PATH_INFO"]        = request.path
         | 
| 117 | 
            +
                    env["QUERY_STRING"]     = request.query
         | 
| 118 | 
            +
                    env["REQUEST_URI"]      = request.fullpath
         | 
| 149 119 | 
             
                    @app.call(env)
         | 
| 150 120 | 
             
                  else
         | 
| 151 121 | 
             
                    @app.call(env)
         | 
| @@ -155,3 +125,13 @@ class Refraction | |
| 155 125 | 
             
                end
         | 
| 156 126 | 
             
              end
         | 
| 157 127 | 
             
            end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            # Rack version compatibility shim
         | 
| 130 | 
            +
             | 
| 131 | 
            +
            if Rack.release == "1.0"
         | 
| 132 | 
            +
              class Rack::Request
         | 
| 133 | 
            +
                def path
         | 
| 134 | 
            +
                  script_name + path_info
         | 
| 135 | 
            +
                end
         | 
| 136 | 
            +
              end
         | 
| 137 | 
            +
            end
         | 
    
        data/refraction.gemspec
    CHANGED
    
    | @@ -5,11 +5,11 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |s|
         | 
| 7 7 | 
             
              s.name = %q{refraction}
         | 
| 8 | 
            -
              s.version = "0.1. | 
| 8 | 
            +
              s.version = "0.1.4"
         | 
| 9 9 |  | 
| 10 10 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 11 11 | 
             
              s.authors = ["Pivotal Labs", "Josh Susser", "Sam Pierson", "Wai Lun Mang"]
         | 
| 12 | 
            -
              s.date = %q{ | 
| 12 | 
            +
              s.date = %q{2010-07-01}
         | 
| 13 13 | 
             
              s.description = %q{Reflection is a Rails plugin and standalone Rack middleware library. Give up quirky config syntax and use plain old Ruby for your rewrite and redirection rules.}
         | 
| 14 14 | 
             
              s.email = %q{gems@pivotallabs.com}
         | 
| 15 15 | 
             
              s.extra_rdoc_files = [
         | 
| @@ -21,6 +21,7 @@ Gem::Specification.new do |s| | |
| 21 21 | 
             
                 "Rakefile",
         | 
| 22 22 | 
             
                 "VERSION",
         | 
| 23 23 | 
             
                 "geminstaller.yml",
         | 
| 24 | 
            +
                 "init.rb",
         | 
| 24 25 | 
             
                 "install.rb",
         | 
| 25 26 | 
             
                 "lib/refraction.rb",
         | 
| 26 27 | 
             
                 "refraction.gemspec",
         | 
| @@ -30,7 +31,7 @@ Gem::Specification.new do |s| | |
| 30 31 | 
             
              s.homepage = %q{http://github.com/pivotal/refraction}
         | 
| 31 32 | 
             
              s.rdoc_options = ["--charset=UTF-8"]
         | 
| 32 33 | 
             
              s.require_paths = ["lib"]
         | 
| 33 | 
            -
              s.rubygems_version = %q{1.3. | 
| 34 | 
            +
              s.rubygems_version = %q{1.3.6}
         | 
| 34 35 | 
             
              s.summary = %q{Rack middleware replacement for mod_rewrite}
         | 
| 35 36 | 
             
              s.test_files = [
         | 
| 36 37 | 
             
                "spec/refraction_spec.rb",
         | 
    
        data/spec/refraction_spec.rb
    CHANGED
    
    | @@ -91,21 +91,81 @@ describe Refraction do | |
| 91 91 | 
             
                    response[1]['Location'].should == "http://foo.com/bar?baz"
         | 
| 92 92 | 
             
                  end
         | 
| 93 93 | 
             
                end
         | 
| 94 | 
            -
              end
         | 
| 95 94 |  | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 95 | 
            +
                describe "using hash arguments but not changing scheme, host, or port" do
         | 
| 96 | 
            +
                  before do
         | 
| 97 | 
            +
                    Refraction.configure do |req|
         | 
| 98 | 
            +
                      req.permanent! :path => "/bar", :query => "baz"
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  it "should not clear the port" do
         | 
| 103 | 
            +
                    env = Rack::MockRequest.env_for('http://bar.com:3000/', :method => 'get')
         | 
| 104 | 
            +
                    app = mock('app')
         | 
| 105 | 
            +
                    response = Refraction.new(app).call(env)
         | 
| 106 | 
            +
                    response[0].should == 301
         | 
| 107 | 
            +
                    response[1]['Location'].should == "http://bar.com:3000/bar?baz"
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                describe "with or without port number" do
         | 
| 112 | 
            +
                before(:each) do
         | 
| 98 113 | 
             
                  Refraction.configure do |req|
         | 
| 99 | 
            -
                    req. | 
| 114 | 
            +
                    case req.host 
         | 
| 115 | 
            +
                    when "asterix.example.com"
         | 
| 116 | 
            +
                      req.permanent! :path => "/potion#{req.path}"
         | 
| 117 | 
            +
                    when "obelix.example.com"
         | 
| 118 | 
            +
                      req.permanent! :host => "menhir.example.com"
         | 
| 119 | 
            +
                    when "getafix.example.com"
         | 
| 120 | 
            +
                      req.permanent! :scheme => "https"
         | 
| 121 | 
            +
                    when "dogmatix.example.com"
         | 
| 122 | 
            +
                      req.permanent! :port => 3001
         | 
| 123 | 
            +
                    end
         | 
| 100 124 | 
             
                  end
         | 
| 101 125 | 
             
                end
         | 
| 102 126 |  | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 127 | 
            +
                  it "should include port in Location if request had a port and didn't change scheme, host, or port" do
         | 
| 128 | 
            +
                    env = Rack::MockRequest.env_for('http://asterix.example.com:3000/1', :method => 'get')
         | 
| 129 | 
            +
                    app = mock('app')
         | 
| 130 | 
            +
                    response = Refraction.new(app).call(env)
         | 
| 131 | 
            +
                    response[0].should == 301
         | 
| 132 | 
            +
                    response[1]['Location'].should include("asterix.example.com:3000")
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  it "should not include port in Location if request didn't specify a port" do
         | 
| 136 | 
            +
                    env = Rack::MockRequest.env_for('http://asterix.example.com/1', :method => 'get')
         | 
| 137 | 
            +
                    app = mock('app')
         | 
| 138 | 
            +
                    response = Refraction.new(app).call(env)
         | 
| 139 | 
            +
                    response[0].should == 301
         | 
| 140 | 
            +
                    response[1]['Location'].should include("asterix.example.com")
         | 
| 141 | 
            +
                    response[1]['Location'].should_not include(":3000")
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                  it "should remove port from Location if host was changed" do
         | 
| 145 | 
            +
                    env = Rack::MockRequest.env_for('http://obelix.example.com:3000/1', :method => 'get')
         | 
| 146 | 
            +
                    app = mock('app')
         | 
| 147 | 
            +
                    response = Refraction.new(app).call(env)
         | 
| 148 | 
            +
                    response[0].should == 301
         | 
| 149 | 
            +
                    response[1]['Location'].should include("menhir.example.com")
         | 
| 150 | 
            +
                    response[1]['Location'].should_not include(":3000")
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  it "should remove port from Location if scheme was changed" do
         | 
| 154 | 
            +
                    env = Rack::MockRequest.env_for('http://getafix.example.com:3000/1', :method => 'get')
         | 
| 155 | 
            +
                    app = mock('app')
         | 
| 156 | 
            +
                    response = Refraction.new(app).call(env)
         | 
| 157 | 
            +
                    response[0].should == 301
         | 
| 158 | 
            +
                    response[1]['Location'].should include("getafix.example.com")
         | 
| 159 | 
            +
                    response[1]['Location'].should_not include(":3000")
         | 
| 160 | 
            +
                  end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                  it "should change port in Location if port was changed" do
         | 
| 163 | 
            +
                    env = Rack::MockRequest.env_for('http://dogmatix.example.com:3000/1', :method => 'get')
         | 
| 164 | 
            +
                    app = mock('app')
         | 
| 165 | 
            +
                    response = Refraction.new(app).call(env)
         | 
| 166 | 
            +
                    response[0].should == 301
         | 
| 167 | 
            +
                    response[1]['Location'].should include("dogmatix.example.com:3001")
         | 
| 168 | 
            +
                  end
         | 
| 109 169 | 
             
                end
         | 
| 110 170 | 
             
              end
         | 
| 111 171 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,12 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: refraction
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
               | 
| 4 | 
            +
              prerelease: false
         | 
| 5 | 
            +
              segments: 
         | 
| 6 | 
            +
              - 0
         | 
| 7 | 
            +
              - 1
         | 
| 8 | 
            +
              - 4
         | 
| 9 | 
            +
              version: 0.1.4
         | 
| 5 10 | 
             
            platform: ruby
         | 
| 6 11 | 
             
            authors: 
         | 
| 7 12 | 
             
            - Pivotal Labs
         | 
| @@ -12,19 +17,23 @@ autorequire: | |
| 12 17 | 
             
            bindir: bin
         | 
| 13 18 | 
             
            cert_chain: []
         | 
| 14 19 |  | 
| 15 | 
            -
            date:  | 
| 20 | 
            +
            date: 2010-07-01 00:00:00 -07:00
         | 
| 16 21 | 
             
            default_executable: 
         | 
| 17 22 | 
             
            dependencies: 
         | 
| 18 23 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 19 24 | 
             
              name: rspec
         | 
| 20 | 
            -
               | 
| 21 | 
            -
               | 
| 22 | 
            -
              version_requirements: !ruby/object:Gem::Requirement 
         | 
| 25 | 
            +
              prerelease: false
         | 
| 26 | 
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 23 27 | 
             
                requirements: 
         | 
| 24 28 | 
             
                - - ">="
         | 
| 25 29 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 30 | 
            +
                    segments: 
         | 
| 31 | 
            +
                    - 1
         | 
| 32 | 
            +
                    - 2
         | 
| 33 | 
            +
                    - 9
         | 
| 26 34 | 
             
                    version: 1.2.9
         | 
| 27 | 
            -
             | 
| 35 | 
            +
              type: :development
         | 
| 36 | 
            +
              version_requirements: *id001
         | 
| 28 37 | 
             
            description: Reflection is a Rails plugin and standalone Rack middleware library. Give up quirky config syntax and use plain old Ruby for your rewrite and redirection rules.
         | 
| 29 38 | 
             
            email: gems@pivotallabs.com
         | 
| 30 39 | 
             
            executables: []
         | 
| @@ -39,6 +48,7 @@ files: | |
| 39 48 | 
             
            - Rakefile
         | 
| 40 49 | 
             
            - VERSION
         | 
| 41 50 | 
             
            - geminstaller.yml
         | 
| 51 | 
            +
            - init.rb
         | 
| 42 52 | 
             
            - install.rb
         | 
| 43 53 | 
             
            - lib/refraction.rb
         | 
| 44 54 | 
             
            - refraction.gemspec
         | 
| @@ -57,18 +67,20 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 57 67 | 
             
              requirements: 
         | 
| 58 68 | 
             
              - - ">="
         | 
| 59 69 | 
             
                - !ruby/object:Gem::Version 
         | 
| 70 | 
            +
                  segments: 
         | 
| 71 | 
            +
                  - 0
         | 
| 60 72 | 
             
                  version: "0"
         | 
| 61 | 
            -
              version: 
         | 
| 62 73 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 63 74 | 
             
              requirements: 
         | 
| 64 75 | 
             
              - - ">="
         | 
| 65 76 | 
             
                - !ruby/object:Gem::Version 
         | 
| 77 | 
            +
                  segments: 
         | 
| 78 | 
            +
                  - 0
         | 
| 66 79 | 
             
                  version: "0"
         | 
| 67 | 
            -
              version: 
         | 
| 68 80 | 
             
            requirements: []
         | 
| 69 81 |  | 
| 70 82 | 
             
            rubyforge_project: 
         | 
| 71 | 
            -
            rubygems_version: 1.3. | 
| 83 | 
            +
            rubygems_version: 1.3.6
         | 
| 72 84 | 
             
            signing_key: 
         | 
| 73 85 | 
             
            specification_version: 3
         | 
| 74 86 | 
             
            summary: Rack middleware replacement for mod_rewrite
         |