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
|