rack-rewrite 1.0.2 → 1.1.0

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/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)