rewritten 0.3.3 → 0.4.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.
- checksums.yaml +7 -0
- data/lib/rack/url.rb +19 -4
- data/lib/rewritten/version.rb +1 -1
- data/lib/rewritten.rb +32 -9
- data/rewritten.gemspec +4 -0
- data/test/rewritten_url_test.rb +89 -0
- metadata +71 -32
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0c3f8baf622f9b4ce4351475c13fc1dc0eb73d86
|
4
|
+
data.tar.gz: 0afcf0f5c164bbae531c82692702305818cee956
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: efb7ccf5dfa9d2b060c97960a677da421651dcc7ed6ba91f12d8373754d7bd6e4c682e8234106ea3ac4fd91af0dbab92bc950e7d44de08b8067d4afb2440d2a6
|
7
|
+
data.tar.gz: 0380009037fce092fabab01e3fbf902521513fe52470f8f0158313ba4c4c118c57eb88735db61d6b35c5e3fbe7d6b46ec5fc203bbc383be3ffaf0c50e44a0202
|
data/lib/rack/url.rb
CHANGED
@@ -6,8 +6,10 @@ module Rack
|
|
6
6
|
|
7
7
|
class Url
|
8
8
|
|
9
|
-
def initialize(app,
|
9
|
+
def initialize(app, &block)
|
10
10
|
@app = app
|
11
|
+
|
12
|
+
self.instance_eval(&block) if block_given?
|
11
13
|
end
|
12
14
|
|
13
15
|
def call(env)
|
@@ -15,9 +17,10 @@ module Rack
|
|
15
17
|
|
16
18
|
subdomain = env["SUBDOMAIN"] ? "#{env["SUBDOMAIN"]}:" : ""
|
17
19
|
|
18
|
-
if to = ::Rewritten.
|
19
|
-
current_path = ::Rewritten.
|
20
|
+
if to = ::Rewritten.includes?("#{subdomain}#{req.path_info}")
|
21
|
+
current_path = ::Rewritten.get_current_translation(to)
|
20
22
|
current_path = current_path.split(":").last
|
23
|
+
|
21
24
|
if current_path == req.path_info
|
22
25
|
# if this is the current path, rewrite path and parameters
|
23
26
|
tpath, tparams = split_to_path_params(to)
|
@@ -26,13 +29,15 @@ module Rack
|
|
26
29
|
@app.call(req.env)
|
27
30
|
else
|
28
31
|
# if this is not the current path, redirect to current path
|
29
|
-
r = Rack::Response.new
|
30
32
|
# NOTE: assuming redirection is always to non-subdomain-path
|
31
33
|
|
34
|
+
r = Rack::Response.new
|
35
|
+
|
32
36
|
new_path = env["rack.url_scheme"].dup
|
33
37
|
new_path << "://"
|
34
38
|
new_path << env["HTTP_HOST"].dup.sub(/^#{subdomain.chomp(':')}\./, '')
|
35
39
|
new_path << current_path
|
40
|
+
new_path << '?' << env["QUERY_STRING"] unless (env["QUERY_STRING"]||'').empty?
|
36
41
|
|
37
42
|
r.redirect(new_path, 301)
|
38
43
|
a = r.finish
|
@@ -47,6 +52,16 @@ module Rack
|
|
47
52
|
[path, Rack::Utils.parse_query(query_string)]
|
48
53
|
end
|
49
54
|
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def add_translation(from,to)
|
59
|
+
::Rewritten.redis = :test unless ::Rewritten.redis == :test
|
60
|
+
::Rewritten.add_translation(from, to)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
50
65
|
end
|
51
66
|
end
|
52
67
|
|
data/lib/rewritten/version.rb
CHANGED
data/lib/rewritten.rb
CHANGED
@@ -34,6 +34,9 @@ module Rewritten
|
|
34
34
|
@redis = Redis::Namespace.new(namespace, :redis => redis)
|
35
35
|
when Redis::Namespace
|
36
36
|
@redis = server
|
37
|
+
when :test
|
38
|
+
@redis = :test
|
39
|
+
@static_translations = {}
|
37
40
|
else
|
38
41
|
@redis = Redis::Namespace.new(:rewritten, :redis => server)
|
39
42
|
end
|
@@ -126,10 +129,14 @@ module Rewritten
|
|
126
129
|
#
|
127
130
|
|
128
131
|
def add_translation(from, to)
|
129
|
-
redis
|
130
|
-
|
131
|
-
|
132
|
-
|
132
|
+
if @redis == :test
|
133
|
+
@static_translations[from] = to
|
134
|
+
else
|
135
|
+
redis.set("from:#{from}", to)
|
136
|
+
redis.lpush(:froms, from)
|
137
|
+
redis.lpush(:tos, to)
|
138
|
+
redis.rpush("to:#{to}", from)
|
139
|
+
end
|
133
140
|
end
|
134
141
|
|
135
142
|
def add_translations(to, froms)
|
@@ -158,9 +165,21 @@ module Rewritten
|
|
158
165
|
end
|
159
166
|
|
160
167
|
def get_current_translation(path)
|
161
|
-
|
162
|
-
|
163
|
-
|
168
|
+
if @redis == :test
|
169
|
+
|
170
|
+
translations = @static_translations.select{|k,v| v == path}
|
171
|
+
|
172
|
+
if translations.size > 0
|
173
|
+
return translations.keys.last
|
174
|
+
else
|
175
|
+
return path
|
176
|
+
end
|
177
|
+
|
178
|
+
else
|
179
|
+
translation = Rewritten.list_range("to:#{path}", -1)
|
180
|
+
return translation if translation
|
181
|
+
return path
|
182
|
+
end
|
164
183
|
end
|
165
184
|
|
166
185
|
|
@@ -174,8 +193,12 @@ module Rewritten
|
|
174
193
|
Rewritten.redis.smembers("hits").map{|e| decode(e)}
|
175
194
|
end
|
176
195
|
|
177
|
-
def
|
178
|
-
|
196
|
+
def includes?(path)
|
197
|
+
if @redis == :test
|
198
|
+
@static_translations[path]
|
199
|
+
else
|
200
|
+
Rewritten.redis.get("from:#{path}")
|
201
|
+
end
|
179
202
|
end
|
180
203
|
|
181
204
|
#
|
data/rewritten.gemspec
CHANGED
@@ -22,6 +22,10 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency "sinatra", ">= 0.9.2"
|
23
23
|
s.add_dependency "multi_json", "~> 1.0"
|
24
24
|
|
25
|
+
s.add_development_dependency "rake"
|
26
|
+
s.add_development_dependency "minitest"
|
27
|
+
s.add_development_dependency "pry"
|
28
|
+
|
25
29
|
s.description = <<description
|
26
30
|
Rewritten is a lookup-based rewriting engine that rewrites requested
|
27
31
|
URLs on the fly. The URL manipulations depend on translations found in
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rewritten'
|
2
|
+
require 'rack/mock'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
describe Rack::Rewritten::Url do
|
7
|
+
|
8
|
+
def call_args(overrides={})
|
9
|
+
{'HTTP_HOST' => 'www.example.org',
|
10
|
+
'REQUEST_URI' => '/foo/with/params',
|
11
|
+
'SCRIPT_INFO'=> '',
|
12
|
+
'PATH_INFO' => '/foo/with/params',
|
13
|
+
'QUERY_STRING' => '',
|
14
|
+
'rack.input' => '',
|
15
|
+
'rack.url_scheme' => 'http'}.merge(overrides)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "redirection behavior" do
|
19
|
+
|
20
|
+
before {
|
21
|
+
@app = MiniTest::Mock.new
|
22
|
+
|
23
|
+
@rack = Rack::Rewritten::Url.new(@app) do
|
24
|
+
add_translation '/foo/bar', '/products/1'
|
25
|
+
add_translation '/foo/baz', '/products/1'
|
26
|
+
add_translation '/foo/with/params', '/products/2?w=1'
|
27
|
+
end
|
28
|
+
}
|
29
|
+
|
30
|
+
it "must not redirect if there are no entries" do
|
31
|
+
@app.expect :call, [200, {'Content-Type' => 'text/plain'},[""]], [Hash]
|
32
|
+
@rack.call(call_args)
|
33
|
+
@app.verify
|
34
|
+
end
|
35
|
+
|
36
|
+
it "must 301 redirect to latest translation" do
|
37
|
+
ret = @rack.call( call_args.merge('REQUEST_URI' => '/foo/bar', 'PATH_INFO' => '/foo/bar' ))
|
38
|
+
@app.verify
|
39
|
+
ret[0].must_equal 301
|
40
|
+
ret[1]['Location'].must_equal "http://www.example.org/foo/baz"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "must keep the query parameters in the 301 redirect" do
|
44
|
+
ret = @rack.call( call_args.merge('REQUEST_URI' => '/foo/bar', 'PATH_INFO' => '/foo/bar', 'QUERY_STRING' => 'w=1' ))
|
45
|
+
@app.verify
|
46
|
+
ret[0].must_equal 301
|
47
|
+
ret[1]['Location'].must_equal "http://www.example.org/foo/baz?w=1"
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
it "must stay on latest translation" do
|
52
|
+
@app.expect :call, [200, {'Content-Type' => 'text/plain'},[""]], [Hash]
|
53
|
+
ret = @rack.call( call_args.merge('REQUEST_URI' => '/foo/baz', 'PATH_INFO' => '/foo/baz' ))
|
54
|
+
@app.verify
|
55
|
+
ret[0].must_equal 200
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
describe "the env" do
|
62
|
+
|
63
|
+
before {
|
64
|
+
@initial_args = call_args.dup
|
65
|
+
@rack = Rack::Rewritten::Url.new(lambda{|env| [200, {}, [""]]})
|
66
|
+
}
|
67
|
+
|
68
|
+
it "must set PATH_INFO to /products/2" do
|
69
|
+
@rack.call(@initial_args)
|
70
|
+
@initial_args['PATH_INFO'].must_equal "/products/2"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "must set QUERY_STRING to w=1" do
|
74
|
+
@rack.call(@initial_args)
|
75
|
+
@initial_args['QUERY_STRING'].must_equal 'w=1'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "must merge QUERY parameters" do
|
79
|
+
@initial_args.merge!('QUERY_STRING' => 's=1')
|
80
|
+
@rack.call(@initial_args)
|
81
|
+
@initial_args['QUERY_STRING'].split('&').sort.must_equal ['s=1', 'w=1']
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
end
|
89
|
+
|
metadata
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rewritten
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Kai Rubarth
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-05-03 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: redis-namespace
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: vegas
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,23 +41,20 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: sinatra
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 0.9.2
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 0.9.2
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: multi_json
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,22 +62,69 @@ dependencies:
|
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '1.0'
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: |2
|
112
|
+
Rewritten is a lookup-based rewriting engine that rewrites requested
|
113
|
+
URLs on the fly. The URL manipulations depend on translations found in
|
114
|
+
a redis database.
|
115
|
+
|
116
|
+
If a matching translation is found, the result of a request is either a
|
117
|
+
redirection or a modification of path and request parameters. For URLs
|
118
|
+
without translation entries the request is left unmodified.
|
119
|
+
|
120
|
+
Rewritten takes larges parts from the Resque codebase (which rocks). The
|
121
|
+
gem is compromised of four parts:
|
122
|
+
|
123
|
+
1. A Ruby library for creating, modifying and querying translations
|
124
|
+
2. A Sinatra app for displaying and managing translations
|
125
|
+
3. A Rack app for rewriting and redirecting request (Rack::Rewritten::Url)
|
126
|
+
4. A Rack app for substituting URLs in HTML pages with their current translation (Rack::Rewritten::Html)
|
127
|
+
5. A Rack app for recording successful request (Rack::Rewritten::Record)
|
89
128
|
email:
|
90
129
|
- kai@doxter.de
|
91
130
|
executables:
|
@@ -137,29 +176,29 @@ files:
|
|
137
176
|
- lib/rewritten/version.rb
|
138
177
|
- lib/test.ru
|
139
178
|
- rewritten.gemspec
|
179
|
+
- test/rewritten_url_test.rb
|
140
180
|
- test/test_rewritten.rb
|
141
181
|
homepage: ''
|
142
182
|
licenses: []
|
183
|
+
metadata: {}
|
143
184
|
post_install_message:
|
144
185
|
rdoc_options: []
|
145
186
|
require_paths:
|
146
187
|
- lib
|
147
188
|
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
-
none: false
|
149
189
|
requirements:
|
150
|
-
- -
|
190
|
+
- - '>='
|
151
191
|
- !ruby/object:Gem::Version
|
152
192
|
version: '0'
|
153
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
-
none: false
|
155
194
|
requirements:
|
156
|
-
- -
|
195
|
+
- - '>='
|
157
196
|
- !ruby/object:Gem::Version
|
158
197
|
version: '0'
|
159
198
|
requirements: []
|
160
199
|
rubyforge_project: rewritten
|
161
|
-
rubygems_version:
|
200
|
+
rubygems_version: 2.0.0
|
162
201
|
signing_key:
|
163
|
-
specification_version:
|
202
|
+
specification_version: 4
|
164
203
|
summary: A redis-based URL rewriting engine
|
165
204
|
test_files: []
|