rack-rewrite 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-rewrite (1.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ mocha (0.9.12)
10
+ rack (1.2.1)
11
+ shoulda (2.10.3)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.0.10)
18
+ mocha (~> 0.9.7)
19
+ rack
20
+ rack-rewrite!
21
+ shoulda (~> 2.10.2)
@@ -1,3 +1,10 @@
1
+ === 1.1.0 / 2011-08-15
2
+ * API
3
+ * :host and :method option to match SERVER_NAME and REQUEST_METHOD env params.
4
+ * :not option to negative match against path.
5
+ * Maintenance
6
+ * Refactored internals a bit.
7
+
1
8
  === 1.0.2 / 2010-10-01
2
9
  * Maintenance
3
10
  * :send_file rules return content in an Array for Ruby 1.9.2 compatibility
@@ -169,6 +169,25 @@ capture group and substitution pattern in your rewrite rule to achieve this.
169
169
  This rule will store the querystring in a capture group (via '(?.*)' ) and
170
170
  will substitute the querystring back into the rewritten URL (via $1).
171
171
 
172
+ === Matching on a host
173
+
174
+ Using the :host option you can match requests to a specific hostname.
175
+
176
+ r301 "/features", "/facial_features", :host => "facerecognizer.com"
177
+
178
+ This rule will only match when the hostname is "facerecognizer.com"
179
+
180
+ === Restrict rule to HTTP methods (GET, POST, PUT, DELETE, etc)
181
+
182
+ In certain scenarios you will want to restrict your rules by the HTTP method
183
+ of a given request. rack-rewrite exposes the :method option for this purpose.
184
+
185
+ # redirect GET's one way
186
+ r301 "/players", "/current_players", :method => :get
187
+
188
+ # and redirect POST's another way
189
+ r302 "/players", "/no_longer_available.html?message=No&longer&supported", :method => :post
190
+
172
191
  === Rule Guards
173
192
 
174
193
  All rules support passing guards as Procs/lambdas. Guards simply return
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.0
@@ -1,6 +1,7 @@
1
- require 'rack/rewrite/rule'
2
-
3
1
  module Rack
2
+ autoload :RuleSet, 'rack/rewrite/rule'
3
+ autoload :VERSION, 'rack/rewrite/version'
4
+
4
5
  # A rack middleware for defining and applying rewrite rules. In many cases you
5
6
  # can get away with rack-rewrite instead of writing Apache mod_rewrite rules.
6
7
  class Rewrite
@@ -19,36 +19,32 @@ module Rack
19
19
  # rewrite '/wiki/John_Trupiano', '/john'
20
20
  # rewrite %r{/wiki/(\w+)_\w+}, '/$1'
21
21
  # rewrite %r{(.*)}, '/maintenance.html', :if => lambda { File.exists?('maintenance.html') }
22
- def rewrite(from, to, *args)
23
- options = args.last.is_a?(Hash) ? args.last : {}
24
- @rules << Rule.new(:rewrite, from, to, options[:if])
22
+ def rewrite(*args)
23
+ add_rule :rewrite, *args
25
24
  end
26
25
 
27
26
  # Creates a redirect rule that will send a 301 when matching.
28
27
  #
29
28
  # r301 '/wiki/John_Trupiano', '/john'
30
29
  # r301 '/contact-us.php', '/contact-us'
31
- def r301(from, to, *args)
32
- options = args.last.is_a?(Hash) ? args.last : {}
33
- @rules << Rule.new(:r301, from, to, options[:if])
30
+ def r301(*args)
31
+ add_rule :r301, *args
34
32
  end
35
33
 
36
34
  # Creates a redirect rule that will send a 302 when matching.
37
35
  #
38
36
  # r302 '/wiki/John_Trupiano', '/john'
39
37
  # r302 '/wiki/(.*)', 'http://www.google.com/?q=$1'
40
- def r302(from, to, *args)
41
- options = args.last.is_a?(Hash) ? args.last : {}
42
- @rules << Rule.new(:r302, from, to, options[:if])
38
+ def r302(*args)
39
+ add_rule :r302, *args
43
40
  end
44
41
 
45
42
  # Creates a rule that will render a file if matched.
46
43
  #
47
44
  # send_file /*/, 'public/system/maintenance.html',
48
45
  # :if => Proc.new { File.exists?('public/system/maintenance.html') }
49
- def send_file(from, to, *args)
50
- options = args.last.is_a?(Hash) ? args.last : {}
51
- @rules << Rule.new(:send_file, from, to, options[:if])
46
+ def send_file(*args)
47
+ add_rule :send_file, *args
52
48
  end
53
49
 
54
50
  # Creates a rule that will render a file using x-send-file
@@ -56,29 +52,29 @@ module Rack
56
52
  #
57
53
  # x_send_file /*/, 'public/system/maintenance.html',
58
54
  # :if => Proc.new { File.exists?('public/system/maintenance.html') }
59
- def x_send_file(from, to, *args)
60
- options = args.last.is_a?(Hash) ? args.last : {}
61
- @rules << Rule.new(:x_send_file, from, to, options[:if])
62
- end
55
+ def x_send_file(*args)
56
+ add_rule :x_send_file, *args
57
+ end
58
+
59
+ private
60
+ def add_rule(method, from, to, options = {}) #:nodoc:
61
+ @rules << Rule.new(method.to_sym, from, to, options)
62
+ end
63
+
63
64
  end
64
65
 
65
66
  # TODO: Break rules into subclasses
66
67
  class Rule #:nodoc:
67
- attr_reader :rule_type, :from, :to, :guard
68
- def initialize(rule_type, from, to, guard=nil) #:nodoc:
69
- @rule_type, @from, @to, @guard = rule_type, from, to, guard
68
+ attr_reader :rule_type, :from, :to, :options
69
+ def initialize(rule_type, from, to, options={}) #:nodoc:
70
+ @rule_type, @from, @to, @options = rule_type, from, to, normalize_options(options)
70
71
  end
71
72
 
72
73
  def matches?(rack_env) #:nodoc:
73
- return false if !guard.nil? && !guard.call(rack_env)
74
+ return false if options[:if].respond_to?(:call) && !options[:if].call(rack_env)
74
75
  path = build_path_from_env(rack_env)
75
- if self.is_a_regexp?(self.from)
76
- path =~ self.from
77
- elsif self.from.is_a?(String)
78
- path == self.from
79
- else
80
- false
81
- end
76
+
77
+ self.match_options?(rack_env) && string_matches?(path, self.from)
82
78
  end
83
79
 
84
80
  # Either (a) return a Rack response (short-circuiting the Rack stack), or
@@ -128,8 +124,27 @@ module Rack
128
124
  def is_a_regexp?(obj)
129
125
  obj.is_a?(Regexp) || (Object.const_defined?(:Oniguruma) && obj.is_a?(Oniguruma::ORegexp))
130
126
  end
131
-
127
+
128
+ def match_options?(env, path = build_path_from_env(env))
129
+ matches = []
130
+
131
+ # negative matches
132
+ matches << !string_matches?(path, options[:not]) if options[:not]
133
+
134
+ # possitive matches
135
+ matches << string_matches?(env['REQUEST_METHOD'], options[:method]) if options[:method]
136
+ matches << string_matches?(env['SERVER_NAME'], options[:host]) if options[:host]
137
+
138
+ matches.all?
139
+ end
140
+
132
141
  private
142
+ def normalize_options(arg)
143
+ options = arg.respond_to?(:call) ? {:if => arg} : arg
144
+ options.symbolize_keys! if options.respond_to? :symbolize_keys!
145
+ options.freeze
146
+ end
147
+
133
148
  def interpret_to_proc(path, env)
134
149
  return self.to.call(match(path), env) if self.from.is_a?(Regexp)
135
150
  self.to.call(self.from, env)
@@ -142,6 +157,16 @@ module Rack
142
157
  def match(path)
143
158
  self.from.match(path)
144
159
  end
160
+
161
+ def string_matches?(string, matcher)
162
+ if self.is_a_regexp?(matcher)
163
+ string =~ matcher
164
+ elsif matcher.is_a?(String)
165
+ string == matcher
166
+ else
167
+ false
168
+ end
169
+ end
145
170
 
146
171
  def computed_to(path)
147
172
  # is there a better way to do this?
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class Rewrite
3
+ VERSION = File.read File.join(File.expand_path("..", __FILE__), "..", "..", "..", "VERSION")
4
+ end
5
+ end
@@ -1,10 +1,10 @@
1
1
  Gem::Specification.new do |s|
2
- s.name = %q{rack-rewrite}
3
- s.version = "1.0.2"
2
+ s.name = 'rack-rewrite'
3
+ s.version = File.read('VERSION')
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["John Trupiano"]
7
- s.date = %q{2010-10-01}
7
+ s.date = Date.today.to_s
8
8
  s.description = %q{A rack middleware for enforcing rewrite rules. In many cases you can get away with rack-rewrite instead of writing Apache mod_rewrite rules.}
9
9
  s.email = %q{jtrupiano@gmail.com}
10
10
  s.extra_rdoc_files = [
@@ -13,16 +13,17 @@ Gem::Specification.new do |s|
13
13
  "README.rdoc"
14
14
  ]
15
15
  s.files = [
16
- ".document",
17
- ".gitignore",
18
16
  "History.rdoc",
19
17
  "LICENSE",
20
18
  "README.rdoc",
21
19
  "Rakefile",
22
- "RELEASING",
20
+ "VERSION",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
23
  "lib/rack-rewrite.rb",
24
24
  "lib/rack/rewrite.rb",
25
25
  "lib/rack/rewrite/rule.rb",
26
+ "lib/rack/rewrite/version.rb",
26
27
  "rack-rewrite.gemspec",
27
28
  "test/geminstaller.yml",
28
29
  "test/rack-rewrite_test.rb",
@@ -36,11 +37,19 @@ Gem::Specification.new do |s|
36
37
  s.rubygems_version = %q{1.3.7}
37
38
  s.summary = %q{A rack middleware for enforcing rewrite rules}
38
39
  s.test_files = [
40
+ "test/rack-rewrite_test.rb",
41
+ "test/geminstaller.yml",
39
42
  "test/rack-rewrite_test.rb",
40
43
  "test/rule_test.rb",
41
44
  "test/test_helper.rb"
42
45
  ]
43
-
46
+ #s.add_dependency 'rack'
47
+
48
+ s.add_development_dependency 'bundler', '~> 1.0.10'
49
+ s.add_development_dependency 'shoulda', '~> 2.10.2'
50
+ s.add_development_dependency 'mocha', '~> 0.9.7'
51
+ s.add_development_dependency 'rack'
52
+
44
53
  if s.respond_to? :specification_version then
45
54
  s.specification_version = 3
46
55
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'test_helper')
1
+ require 'test_helper'
2
2
 
3
3
  class RuleTest < Test::Unit::TestCase
4
4
 
@@ -146,6 +146,46 @@ class RuleTest < Test::Unit::TestCase
146
146
  end
147
147
 
148
148
  context 'Rule#matches' do
149
+ context 'Given rule with :not option which matches "from" string' do
150
+ setup do
151
+ @rule = Rack::Rewrite::Rule.new(:rewrite, /^\/features/, '/facial_features', :not => '/features')
152
+ end
153
+ should 'not match PATH_INFO of /features' do
154
+ assert !@rule.matches?(rack_env_for("/features"))
155
+ end
156
+ should 'match PATH_INFO of /features.xml' do
157
+ assert @rule.matches?(rack_env_for("/features.xml"))
158
+ end
159
+ end
160
+
161
+ context 'Given rule with :host option of testapp.com' do
162
+ setup do
163
+ @rule = Rack::Rewrite::Rule.new(:rewrite, /^\/features/, '/facial_features', :host => 'testapp.com')
164
+ end
165
+
166
+ should 'match PATH_INFO of /features and HOST of testapp.com' do
167
+ assert @rule.matches?(rack_env_for("/features", 'SERVER_NAME' => 'testapp.com'))
168
+ end
169
+
170
+ should 'not match PATH_INFO of /features and HOST of nottestapp.com' do
171
+ assert ! @rule.matches?(rack_env_for("/features", 'SERVER_NAME' => 'nottestapp.com'))
172
+ end
173
+ end
174
+
175
+ context 'Given rule with :method option of POST' do
176
+ setup do
177
+ @rule = Rack::Rewrite::Rule.new(:rewrite, '/features', '/facial_features', :method => 'POST')
178
+ end
179
+
180
+ should 'match PATH_INFO of /features and REQUEST_METHOD of POST' do
181
+ assert @rule.matches?(rack_env_for("/features", 'REQUEST_METHOD' => 'POST'))
182
+ end
183
+
184
+ should 'not match PATH_INFO of /features and REQUEST_METHOD of DELETE' do
185
+ assert ! @rule.matches?(rack_env_for("/features", 'REQUEST_METHOD' => 'DELETE'))
186
+ end
187
+ end
188
+
149
189
  context 'Given any rule with a "from" string of /features' do
150
190
  setup do
151
191
  @rule = Rack::Rewrite::Rule.new(:rewrite, '/features', '/facial_features')
@@ -307,8 +347,8 @@ class RuleTest < Test::Unit::TestCase
307
347
  end
308
348
  end
309
349
 
310
- def rack_env_for(url)
350
+ def rack_env_for(url, options = {})
311
351
  components = url.split('?')
312
- {'PATH_INFO' => components[0], 'QUERY_STRING' => components[1] || ''}
352
+ {'PATH_INFO' => components[0], 'QUERY_STRING' => components[1] || ''}.merge(options)
313
353
  end
314
354
  end
@@ -1,13 +1,9 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
3
- gem 'shoulda', '~> 2.10.2'
4
- require 'shoulda'
5
- gem 'mocha', '~> 0.9.7'
6
- require 'mocha'
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require :default, :development
7
5
 
8
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
- $LOAD_PATH.unshift(File.dirname(__FILE__))
10
- require 'rack/rewrite'
6
+ require 'test/unit'
11
7
 
12
8
  class Test::Unit::TestCase
13
9
  end
metadata CHANGED
@@ -1,45 +1,82 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rack-rewrite
3
- version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 0
9
- - 2
10
- version: 1.0.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - John Trupiano
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2010-10-01 00:00:00 -04:00
12
+ date: 2011-08-15 00:00:00.000000000 -04:00
19
13
  default_executable:
20
- dependencies: []
21
-
22
- description: A rack middleware for enforcing rewrite rules. In many cases you can get away with rack-rewrite instead of writing Apache mod_rewrite rules.
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: &2152850260 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.10
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *2152850260
26
+ - !ruby/object:Gem::Dependency
27
+ name: shoulda
28
+ requirement: &2152849800 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 2.10.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2152849800
37
+ - !ruby/object:Gem::Dependency
38
+ name: mocha
39
+ requirement: &2152849340 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 0.9.7
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2152849340
48
+ - !ruby/object:Gem::Dependency
49
+ name: rack
50
+ requirement: &2152848960 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2152848960
59
+ description: A rack middleware for enforcing rewrite rules. In many cases you can
60
+ get away with rack-rewrite instead of writing Apache mod_rewrite rules.
23
61
  email: jtrupiano@gmail.com
24
62
  executables: []
25
-
26
63
  extensions: []
27
-
28
- extra_rdoc_files:
64
+ extra_rdoc_files:
29
65
  - LICENSE
30
66
  - History.rdoc
31
67
  - README.rdoc
32
- files:
33
- - .document
34
- - .gitignore
68
+ files:
35
69
  - History.rdoc
36
70
  - LICENSE
37
71
  - README.rdoc
38
72
  - Rakefile
39
- - RELEASING
73
+ - VERSION
74
+ - Gemfile
75
+ - Gemfile.lock
40
76
  - lib/rack-rewrite.rb
41
77
  - lib/rack/rewrite.rb
42
78
  - lib/rack/rewrite/rule.rb
79
+ - lib/rack/rewrite/version.rb
43
80
  - rack-rewrite.gemspec
44
81
  - test/geminstaller.yml
45
82
  - test/rack-rewrite_test.rb
@@ -48,38 +85,32 @@ files:
48
85
  has_rdoc: true
49
86
  homepage: http://github.com/jtrupiano/rack-rewrite
50
87
  licenses: []
51
-
52
88
  post_install_message:
53
- rdoc_options:
89
+ rdoc_options:
54
90
  - --charset=UTF-8
55
- require_paths:
91
+ require_paths:
56
92
  - lib
57
- required_ruby_version: !ruby/object:Gem::Requirement
93
+ required_ruby_version: !ruby/object:Gem::Requirement
58
94
  none: false
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
64
- - 0
65
- version: "0"
66
- required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
100
  none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
75
105
  requirements: []
76
-
77
106
  rubyforge_project: johntrupiano
78
- rubygems_version: 1.3.7
107
+ rubygems_version: 1.6.2
79
108
  signing_key:
80
109
  specification_version: 3
81
110
  summary: A rack middleware for enforcing rewrite rules
82
- test_files:
111
+ test_files:
112
+ - test/rack-rewrite_test.rb
113
+ - test/geminstaller.yml
83
114
  - test/rack-rewrite_test.rb
84
115
  - test/rule_test.rb
85
116
  - test/test_helper.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- *.sw?
2
- .DS_Store
3
- coverage
4
- rdoc
5
- pkg
data/RELEASING DELETED
@@ -1,4 +0,0 @@
1
- Update History.txt with relevant details
2
- Manually edit .gemspec updating file list, version, and date.
3
- Tag the new version (git tag -a vX.X.X)
4
- Build and push the gem (gem build rack-rewrite.gemspec && gem push rack-rewrite-X.X.X.gem)