joshbuddy-rack-rewrite 0.0.2 → 0.0.3

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.rdoc CHANGED
@@ -10,31 +10,38 @@ Rack middleware for request rewriting.
10
10
 
11
11
  # When it sees /api or /test, it calls whatever is in the act block
12
12
  #
13
- on :uri => %r{/(api|test)} do
13
+ on :path_info => %r{/(api|test)} do
14
14
  act { puts "hey way to go!" }
15
15
  pass
16
16
  end
17
17
 
18
18
  # When it sees /google, it makes a redirect to google with the value of the query string as the search
19
19
  #
20
- on :uri => %r{/google.*} do
20
+ on :path_info => %r{/google.*} do
21
21
  redirect { "http://google.com/search?q=#{CGI.escape(query_string)}" }
22
22
  end
23
23
 
24
- # If a URI starts with /valid_place, it strips it off and keeps on truckin'
24
+ # If a PATH_INFO starts with /valid_place, it strips it off and keeps on truckin'
25
25
  #
26
- on :uri => %r{/valid_place/.*} do
27
- set(:uri) { uri[%r{/valid_place(/.*)}, 1] }
26
+ on :path_info => %r{/valid_place/.*} do
27
+ set(:path_info) { path_info[%r{/valid_place(/.*)}, 1] }
28
28
  pass
29
29
  end
30
30
 
31
- # If a URI starts with /hello_kitty, add a kitty header equal to your query string
31
+ # If a PATH_INFO starts with /hello_kitty, add a kitty header equal to your query string
32
32
  #
33
- on :uri => %r{/hello_kitty/.*} do
33
+ on :path_info => %r{/hello_kitty/.*} do
34
34
  act { header['kitty'] = query_string }
35
35
  pass
36
36
  end
37
37
 
38
+ # If the request has a has a param of kitten=cute or kitten=happy, lets log it and pass it on!
39
+ #
40
+ on :params => {:kitten => /cute|happy/} do
41
+ act { log('what a nice cat') }
42
+ pass
43
+ end
44
+
38
45
  fail
39
46
  end
40
47
 
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 0
4
- :patch: 2
4
+ :patch: 3
@@ -1,64 +1,38 @@
1
+ require 'rack'
2
+ require 'cgi'
3
+
1
4
  module Rack
2
5
  class Rewrite
3
6
  class Action
4
7
 
5
- def uri
6
- @env['PATH_INFO']
7
- end
8
-
9
- def uri=(uri)
10
- @env['PATH_INFO'] = uri
11
- update_uri_qs
12
- end
13
-
14
- def query_string
15
- @env['QUERY_STRING']
16
- end
17
-
18
- def query_string=(query_string)
19
- @env['QUERY_STRING'] = query_string
20
- update_uri_qs
21
- end
22
-
23
- def update_uri_qs
24
- @env['REQUEST_PATH'] = uri
25
- @env['REQUEST_URI'] = query_string.empty? ? uri : "#{uri}?#{query_string}"
26
- end
27
-
28
- def method
29
- @env['REQUEST_METHOD']
30
- end
31
-
32
- def method=(method)
33
- @env['REQUEST_METHOD'] = method.to_s.upcase
34
- end
35
-
36
- def host
37
- @env['HTTP_HOST']
38
- end
39
-
40
- def host=(host)
41
- @env['HTTP_HOST'] = host
42
- end
43
-
44
- def port
45
- @env['SERVER_PORT']
8
+ def setup(env)
9
+ @request = Rack::Request.new(env)
46
10
  end
47
11
 
48
- def port=(port)
49
- @env['SERVER_PORT'] = port.to_s
12
+ def respond_to?(method)
13
+ @request.respond_to?(method) || super
50
14
  end
51
15
 
52
- def scheme
53
- @env['rack.url_scheme']
16
+ def query_string=(params)
17
+ env = @request.env
18
+ env['QUERY_STRING'] = case params
19
+ when Hash
20
+ params.inject([]) { |qs, (k, v)| qs << "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"} * '&'
21
+ else
22
+ params
23
+ end
24
+
25
+ @request = Rack::Request.new(env)
54
26
  end
55
27
 
56
28
  def scheme=(scheme)
57
- @env['rack.url_scheme'] = scheme
29
+ env = @request.env
30
+ env['rack.url_scheme'] = scheme
31
+ @request = Rack::Request.new(env)
58
32
  end
59
33
 
60
- def setup(env)
61
- @env = env
34
+ def method_missing(method, *args, &block)
35
+ @request.send(method, *args, &block)
62
36
  end
63
37
 
64
38
  class Pass < Action
@@ -69,7 +43,7 @@ module Rack
69
43
 
70
44
  class Fail < Action
71
45
  def call(env)
72
- raise
46
+ raise Rack::Rewrite::FailError.new
73
47
  end
74
48
  end
75
49
 
@@ -82,12 +56,7 @@ module Rack
82
56
 
83
57
  def call(env)
84
58
  setup(env)
85
- self.send :"#{@variable}=", case @action
86
- when Proc
87
- instance_eval(&@action)
88
- else
89
- instance_eval(@action)
90
- end
59
+ self.send(:"#{@variable}=", instance_eval(&@action))
91
60
  env
92
61
  end
93
62
 
@@ -98,37 +67,37 @@ module Rack
98
67
  @caller = caller
99
68
  @action = action
100
69
  end
101
-
70
+
102
71
  def method_missing(method, *args, &block)
103
- @caller.send(method, *args, &block)
72
+ if respond_to?(method)
73
+ super
74
+ else
75
+ @caller.send(method, *args, &block)
76
+ end
104
77
  end
105
-
78
+
106
79
  def call(env)
107
80
  setup(env)
108
- case @action
109
- when Proc
110
- instance_eval(&@action)
111
- else
112
- instance_eval(@action)
113
- end
81
+ instance_eval(&@action)
114
82
  env
115
83
  end
116
84
 
117
85
  end
118
86
 
119
87
  class Redirect < Action
120
- def initialize(caller, action)
88
+ def initialize(caller, action, status)
121
89
  @caller = caller
122
90
  @action = action
91
+ @status = status
123
92
  end
124
93
 
125
94
  def call(env)
126
95
  setup(env)
127
- @caller.redirect = [ 302, {'Location'=> case @action
96
+ @caller.redirect = [ @status, {'Location'=> case @action
128
97
  when Proc
129
98
  instance_eval(&@action)
130
99
  else
131
- instance_eval(@action)
100
+ @action
132
101
  end}, []]
133
102
  throw :pass
134
103
  end
@@ -0,0 +1,40 @@
1
+ module Rack
2
+ class Rewrite
3
+ class ConditionSet
4
+
5
+ attr_reader :parent_set, :actions, :conditions
6
+
7
+ def initialize(parent_set, conditions = nil)
8
+ @parent_set = parent_set
9
+ @conditions = conditions
10
+ @actions = []
11
+ end
12
+
13
+ def satisfied?(env)
14
+ if conditions
15
+
16
+ uri_ok = conditions.key?(:uri) ? conditions[:uri] === env['PATH_INFO'] : true
17
+ method_ok = conditions.key?(:method) ? conditions[:method] === env['REQUEST_METHOD'].downcase : true
18
+ host_ok = conditions.key?(:host) ? conditions[:host] === env['HTTP_HOST'] : true
19
+ port_ok = conditions.key?(:port) ? conditions[:port] === env['SERVER_PORT'].to_i : true
20
+ scheme_ok = conditions.key?(:scheme) ? conditions[:scheme] === env['rack.url_scheme'] : true
21
+ if conditions.key?(:params)
22
+ req = Rack::Request.new(env)
23
+ params_ok = true
24
+ conditions[:params].each do |key, test|
25
+ params_ok = test === req.params[key.to_s]
26
+ break unless params_ok
27
+ end
28
+ else
29
+ params_ok = true
30
+ end
31
+
32
+ uri_ok && method_ok && host_ok && port_ok && scheme_ok && params_ok
33
+ else
34
+ true
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
data/lib/rack_rewrite.rb CHANGED
@@ -1,43 +1,14 @@
1
1
  $:.unshift(File.dirname(__FILE__))
2
+ require 'rack'
2
3
  require 'rack_rewrite/actions'
4
+ require 'rack_rewrite/condition_set'
3
5
 
4
6
  module Rack
5
7
  class Rewrite
6
8
 
7
- attr_accessor :path, :redirect, :headers
9
+ FailError = Class.new(RuntimeError)
8
10
 
9
- class ConditionSet
10
-
11
- attr_reader :parent_set, :actions, :conditions
12
-
13
- def initialize(parent_set, conditions = nil)
14
- @parent_set = parent_set
15
- @conditions = conditions
16
- @actions = []
17
- end
18
-
19
- def satisfied?(env)
20
- if conditions
21
-
22
- uri_ok = conditions.key?(:uri) ? conditions[:uri] === env['PATH_INFO'] : true
23
- method_ok = conditions.key?(:method) ? conditions[:method] === env['REQUEST_METHOD'].downcase : true
24
- host_ok = conditions.key?(:host) ? conditions[:host] === env['HTTP_HOST'] : true
25
- port_ok = conditions.key?(:port) ? conditions[:port] === env['SERVER_PORT'].to_i : true
26
- scheme_ok = conditions.key?(:scheme) ? conditions[:scheme] === env['rack.url_scheme'] : true
27
-
28
- #puts "uri_ok: #{uri_ok} method_ok #{method_ok} host_ok #{host_ok} port_ok #{port_ok} scheme_ok #{scheme_ok} for conditions #{conditions.inspect}"
29
-
30
- uri_ok && method_ok && host_ok && port_ok && scheme_ok
31
- else
32
- true
33
- end
34
- end
35
-
36
- def inspect
37
- "#{id} .. conditions=#{conditions.inspect}\nactions=#{actions.inspect}"
38
- end
39
-
40
- end
11
+ attr_accessor :path, :redirect, :headers
41
12
 
42
13
  def initialize(app, options = {}, &block)
43
14
  @app = app
@@ -69,15 +40,17 @@ module Rack
69
40
  @current_condition_set.actions << Action::Fail.new
70
41
  end
71
42
 
72
- def redirect(pattern = nil, &block)
73
- @current_condition_set.actions << Action::Redirect.new(self, pattern || block)
43
+ def redirect(*args, &block)
44
+ options = args.last.is_a?(Hash) ? args.pop : {}
45
+ pattern = args.first
46
+ @current_condition_set.actions << Action::Redirect.new(self, pattern || block, options[:status] || 302)
74
47
  end
75
48
 
76
49
  def call(env)
77
50
  @headers = {}
78
51
  catch(:pass) {
79
52
  env = call_conditions(env, @root)
80
- raise
53
+ raise FailError.new
81
54
  }
82
55
  if @redirect
83
56
  redirect = @redirect
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Rack::Rewrite Rewriting" do
4
+
5
+ it "should rewrite a path_info" do
6
+ env = Rack::MockRequest.env_for('/test', :method => 'get')
7
+ app = mock('app')
8
+ app.should_receive(:call) { |resp|
9
+ resp['PATH_INFO'].should == '/test/test'
10
+ [200, {}, ["body"]]
11
+ }
12
+
13
+ Rack::Rewrite.new(app) { on(:path_info => '/test') { set(:path_info) { "/test#{path_info}" }; pass } }.call(env)
14
+ end
15
+
16
+ it "should rewrite a scheme" do
17
+ env = Rack::MockRequest.env_for('/test', :method => 'get')
18
+ app = mock('app')
19
+ app.should_receive(:call) { |resp|
20
+ resp['rack.url_scheme'].should == 'https'
21
+ [200, {}, ["body"]]
22
+ }
23
+
24
+ Rack::Rewrite.new(app) { on(:path_info => '/test') { set(:scheme) { "https" }; pass } }.call(env)
25
+ end
26
+
27
+ it "should arbitrarily add a new header" do
28
+ env = Rack::MockRequest.env_for('/test?Happy-Land', :method => 'get')
29
+ app = mock('app')
30
+ app.should_receive(:call).and_return([200, {'Content-type' => 'text/html'}, ['mybody']])
31
+ response = Rack::Rewrite.new(app) { on(:path_info => '/test') { act{ headers['My-special-header'] = query_string }; pass } }.call(env)
32
+ response[1]['My-special-header'].should == 'Happy-Land'
33
+ end
34
+
35
+ it "should let you create a new querystring from a hash" do
36
+ env = Rack::MockRequest.env_for('/test?Happy=Land', :method => 'get')
37
+ app = mock('app')
38
+ app.should_receive(:call) { |resp|
39
+ ['Happy=Land&more=query_goodness', 'more=query_goodness&Happy=Land'].should include(resp['QUERY_STRING'])
40
+ [200, {}, ["body"]]
41
+ }
42
+ response = Rack::Rewrite.new(app) { on(:path_info => '/test') { set(:query_string) { params.merge(:more => :query_goodness)}; pass } }.call(env)
43
+ end
44
+
45
+ it "should let you create a new querystring from a string" do
46
+ env = Rack::MockRequest.env_for('/test?Happy=Land', :method => 'get')
47
+ app = mock('app')
48
+ app.should_receive(:call) { |resp|
49
+ resp['QUERY_STRING'].should == 'this_is_my_query_string'
50
+ [200, {}, ["body"]]
51
+ }
52
+ response = Rack::Rewrite.new(app) { on(:path_info => '/test') { set(:query_string) { "this_is_my_query_string" }; pass } }.call(env)
53
+
54
+ end
55
+
56
+ it "should fail" do
57
+ env = Rack::MockRequest.env_for('/test', :method => 'get')
58
+ app = mock('app')
59
+ proc { Rack::Rewrite.new(app) { on(:path_info => '/test') { fail }; pass }.call(env) }.should raise_error Rack::Rewrite::FailError
60
+ end
61
+
62
+ it "should redirect from a proc" do
63
+ env = Rack::MockRequest.env_for('/test', :method => 'get')
64
+ app = mock('app')
65
+ Rack::Rewrite.new(app) { on(:path_info => '/test') { redirect {"/another/place"} }; fail }.call(env).should == [302, {'Location' => '/another/place'}, []]
66
+ end
67
+
68
+ it "should redirect from a proc (with a special status)" do
69
+ env = Rack::MockRequest.env_for('/test', :method => 'get')
70
+ app = mock('app')
71
+ Rack::Rewrite.new(app) { on(:path_info => '/test') { redirect(:status => 304) {"/another/place"} }; fail }.call(env).should == [304, {'Location' => '/another/place'}, []]
72
+ end
73
+
74
+ it "should redirect from a string" do
75
+ env = Rack::MockRequest.env_for('/test', :method => 'get')
76
+ app = mock('app')
77
+ Rack::Rewrite.new(app) { on(:path_info => '/test') { redirect "/another/place" }; fail }.call(env).should == [302, {'Location' => '/another/place'}, []]
78
+ end
79
+
80
+ end
@@ -12,11 +12,19 @@ describe "Rack::Rewrite Conditions" do
12
12
  end
13
13
  end
14
14
 
15
- it "should detect a simple uri" do
15
+ it "should detect a simple path_info" do
16
16
  env = Rack::MockRequest.env_for('/test', :method => 'get')
17
17
  app = mock('app')
18
18
  app.should_receive(:call).with(env).and_return([200, {}, ["body"]])
19
- Rack::Rewrite.new(app) { on(:uri => '/test') { pass } }.call(env)
19
+ Rack::Rewrite.new(app) { on(:path_info => '/test') { pass } }.call(env)
20
20
  end
21
21
 
22
+ it "should detect a param in the query string" do
23
+ env = Rack::MockRequest.env_for('/test?test=helpme', :method => 'get')
24
+ app = mock('app')
25
+ app.should_receive(:call).with(env).and_return([200, {}, ["body"]])
26
+ Rack::Rewrite.new(app) { on(:params => {:test => 'helpme'}) { pass } }.call(env)
27
+ proc { Rack::Rewrite.new(app) { on(:params => {:test => 'helpme2'}) { pass } }.call(env) }.should raise_error
28
+ end
29
+
22
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joshbuddy-rack-rewrite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Hull
@@ -26,9 +26,10 @@ files:
26
26
  - VERSION.yml
27
27
  - lib/rack_rewrite
28
28
  - lib/rack_rewrite/actions.rb
29
+ - lib/rack_rewrite/condition_set.rb
29
30
  - lib/rack_rewrite.rb
31
+ - spec/action_spec.rb
30
32
  - spec/conditions_spec.rb
31
- - spec/rewrite_spec.rb
32
33
  - spec/spec_helper.rb
33
34
  has_rdoc: true
34
35
  homepage: http://github.com/joshbuddy/rack-rewrite
data/spec/rewrite_spec.rb DELETED
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Rack::Rewrite Rewriting" do
4
-
5
- it "should rewrite a uri" do
6
- env = Rack::MockRequest.env_for('/test', :method => 'get')
7
- app = mock('app')
8
- app.should_receive(:call) { |resp|
9
- resp['PATH_INFO'].should == '/test/test'
10
- [200, {}, ["body"]]
11
- }
12
-
13
- Rack::Rewrite.new(app) { on(:uri => '/test') { set(:uri) { "/test#{uri}" }; pass } }.call(env)
14
- end
15
-
16
- it "should arbitrarily add a new header" do
17
- env = Rack::MockRequest.env_for('/test?Happy-Land', :method => 'get')
18
- app = mock('app')
19
- app.should_receive(:call).and_return([200, {'Content-type' => 'text/html'}, ['mybody']])
20
- response = Rack::Rewrite.new(app) { on(:uri => '/test') { act{ headers['My-special-header'] = query_string }; pass } }.call(env)
21
- response[1]['My-special-header'].should == 'Happy-Land'
22
- end
23
-
24
- end