rack-magic-incoming-url 0.0.1

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
+
2
+ gemspec
3
+
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ magic-incoming-url (0.0.1)
5
+ rack
6
+
7
+ GEM
8
+ specs:
9
+ rack (1.4.5)
10
+ rack-test (0.6.2)
11
+ rack (>= 1.0)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ magic-incoming-url!
18
+ rack-test
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ Rack::MagicIncomingUrl
2
+ ----------------------
3
+
4
+ Magic Incoming URL is a piece of rack middleware that redirects a URL to
5
+ another one - but only when it's not a local link.
6
+
7
+ It's *not* designed to prevent hot-linking - it's designed for sites
8
+ that respond to multiple domains, where different domains should lead to
9
+ different landing pages.
10
+
11
+ e.g. You run Simon's Shoes and have two domains: simons-shoes.net and simons-boots.net.
12
+ They both point to the same site, but you want customers who enter the
13
+ simons-boots.net URL to start off looking at boots.
14
+
15
+ So entering:
16
+
17
+ `http://www.simons-shoes.net` goes to `http://www.simons-shoes.net/`
18
+
19
+ But entering:
20
+
21
+ `http://www.simons-boots.net` goes to
22
+ `http://www.simons-boots.net/boots`
23
+
24
+ Rack::MagicIncomingUrl allows this to be easily configured:
25
+
26
+ ```` ruby
27
+ require 'rack/magic-incoming-url'
28
+
29
+ map '/' do
30
+ use Rack::MagicIncomingUrl, { 'www.simons-boots.net' => { '/' => 'http://www.simons-boots.net/boots' } }
31
+ run MyWebApp
32
+ end
33
+ ````
34
+
35
+ Installation
36
+ ============
37
+
38
+ `gem install rack-magic-incoming-url`
39
+
40
+ or add
41
+
42
+ `gem 'rack-magic-incoming-url'`
43
+
44
+ to your Gemfile.
45
+
46
+ License (MIT)
47
+ ==========================================
48
+ (c) Geoff Youngs, 2013
49
+
50
+ Permission is hereby granted, free of charge, to any person obtaining a
51
+ copy of this software and associated documentation files (the
52
+ "Software"), to deal in the Software without restriction, including
53
+ without limitation the rights to use, copy, modify, merge, publish,
54
+ distribute, sublicense, and/or sell copies of the Software, and to permit
55
+ persons to whom the Software is furnished to do so, subject to the
56
+ following conditions:
57
+
58
+ The above copyright notice and this permission notice shall be included
59
+ in all copies or substantial portions of the Software.
60
+
61
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
62
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
63
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
64
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
65
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
66
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
67
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68
+
69
+
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new do |t|
5
+ t.test_files = FileList['test/*_test.rb']
6
+ end
7
+
data/example/config.ru ADDED
@@ -0,0 +1,50 @@
1
+ $: << File.dirname(__FILE__)+"../lib"
2
+ $: << './lib'
3
+ require 'rack'
4
+ require 'rack/magic-incoming-url'
5
+
6
+ app = lambda do |env|
7
+ port = env["SERVER_PORT"]
8
+ [
9
+ 200,
10
+ {'Content-Type' => 'text/html'},
11
+ [
12
+ %Q[
13
+ <!DOCTYPE html>
14
+ <html>
15
+ <head>
16
+ <title>Title</title>
17
+ </head>
18
+ <body>
19
+ <h1>#{env['PATH_INFO']}</h1>
20
+
21
+ <h2>Local links</h2>
22
+ <a href="/">Localhost</a>
23
+ <a href="/localhost">/localhost</a>
24
+ <a href="/217-0-0-1">/127-0-0-1</a>
25
+
26
+ <h2>localhost links</h2>
27
+ <a href="http://localhost:#{port}/">Localhost</a>
28
+ <a href="http://localhost:#{port}/localhost">/localhost</a>
29
+ <a href="http://localhost:#{port}/217-0-0-1">/127-0-0-1</a>
30
+
31
+ <h2>127.0.0.1 links</h2>
32
+ <a href="http://127.0.0.1:#{port}/">Localhost</a>
33
+ <a href="http://127.0.0.1:#{port}/localhost">/localhost</a>
34
+ <a href="http://127.0.0.1:#{port}/217-0-0-1">/127-0-0-1</a>
35
+ ]
36
+ ]
37
+ ]
38
+ end
39
+
40
+ # When the user goes to http://localhost/ from the URL bar or from another site, they get /localhost?magic-redirect
41
+ # but when they follow a link from http://localhost/ it all works normally.
42
+ #
43
+ # The same happens when they access using 127.0.0.1, except they are directed to a different incoming URL.
44
+
45
+ use Rack::MagicIncomingUrl, {
46
+ 'localhost' => { '/' => '/localhost?magic-redirect' },
47
+ '127.0.0.1' => { '/' => '/127-0-0-1?magic-redirect' }
48
+ }
49
+ run app
50
+
@@ -0,0 +1,58 @@
1
+ =begin
2
+ Magic Incoming URL is a piece of rack middleware that redirects a URL to another one - but only when it's not from a local link.
3
+
4
+ It's designed for sites that respond to multiple domains, where different domains should lead to different landing pages.
5
+
6
+ e.g. You run Simon's Shoes and have two domains: simons-shoes.net and simons-boots.net.
7
+ They both point to the same site, but you want customers who go to simons-boots.net to end up
8
+ start on the boots page.
9
+
10
+ http://www.simons-shoes.net -> http://www.simons-shoes.net/
11
+ http://www.simons-boots.net -> http://www.simons-boots.net/boots
12
+
13
+ You can achieve this with the following config:
14
+
15
+ map '/' do
16
+ use Rack::MagicIncomingUrl, { 'www.simons-boots.net' => { '/' => '/boots' } }
17
+ run MyWebApp
18
+ end
19
+
20
+ =end
21
+ module Rack
22
+ class MagicIncomingUrl
23
+ def initialize(app, map)
24
+ @app, @map = app, map
25
+ end
26
+
27
+ def redirect_for_env(env)
28
+ return nil unless @map
29
+
30
+ host, path, server = env['HTTP_HOST'], env['PATH_INFO'], env['SERVER_NAME']
31
+
32
+ settings = @map[host] || @map[server]
33
+
34
+ return unless settings
35
+
36
+ settings[path]
37
+ end
38
+
39
+ def call env
40
+ redirect = redirect_for_env(env)
41
+
42
+ if redirect
43
+ # Only continue if no referer or non-local refererer
44
+ if env['HTTP_REFERER'].nil? or env['HTTP_REFERER'].index(env['HTTP_HOST']).nil?
45
+ if redirect[0..0] == '/'
46
+ redirect = "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{redirect}"
47
+ end
48
+ res = Rack::Response.new
49
+ res.redirect(redirect)
50
+
51
+ return res.finish
52
+ end
53
+ end
54
+
55
+ @app.call(env)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["Geoff Youngs"]
5
+ gem.email = ["git@intersect-uk.co.uk"]
6
+ gem.description = <<-EOD
7
+ A simple piece of rack middleware to redirect certain URLs when they are
8
+ navigated to directly.
9
+
10
+ Designed for use with sites where the same site is served across several domain names
11
+ that each highlight different specialities.
12
+ EOD
13
+ gem.summary = %q{Redirect incoming visitors based on domain / url}
14
+ gem.homepage = "http://github.com/geoffyoungs/rack-magic-incoming-url"
15
+
16
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ gem.files = `git ls-files`.split("\n")
18
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ gem.name = "rack-magic-incoming-url"
20
+ gem.require_paths = ["lib"]
21
+ gem.version = '0.0.1'
22
+ gem.add_dependency("rack")
23
+ gem.add_development_dependency("rack-test")
24
+ end
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rack/test'
3
+ require 'rack/mock'
4
+ require 'rack/magic-incoming-url'
5
+ require 'test/unit'
6
+
7
+ class TestIncoming < Test::Unit::TestCase
8
+ include Rack::Test::Methods
9
+
10
+ attr_reader :app
11
+ def setup
12
+ orig = lambda { |env| [200, {'Content-Type' => 'text/html'}, 'OK'] }
13
+ @app = Rack::MagicIncomingUrl.new orig, {
14
+ 'www.simons-boots.net' => {
15
+ '/' => 'http://www.simons-boots.net/boots',
16
+ '/offers' => '/boots-offers'
17
+ }
18
+ }
19
+ end
20
+
21
+ def test_redirect_no_referer
22
+ get "http://www.simons-boots.net/"
23
+ assert last_response.redirect?
24
+ assert_equal "http://www.simons-boots.net/boots", last_response.location
25
+
26
+ get "http://www.simons-boots.net/offers"
27
+ assert last_response.redirect?
28
+ assert_equal "http://www.simons-boots.net/boots-offers", last_response.location
29
+ end
30
+
31
+ def test_redirect_external_referer
32
+ get "http://www.simons-boots.net/", {}, { 'HTTP_REFERER' => 'http://www.google.com/' }
33
+ assert last_response.redirect?
34
+ assert_equal "http://www.simons-boots.net/boots", last_response.location
35
+ end
36
+
37
+ def test_noredirect_same_referer
38
+ get "http://www.simons-boots.net/", {}, { 'HTTP_REFERER' => 'http://www.simons-boots.net/' }
39
+ assert ! last_response.redirect?
40
+
41
+ get "http://www.simons-boots.net/offers", {}, { 'HTTP_REFERER' => 'http://www.simons-boots.net/' }
42
+ assert ! last_response.redirect?
43
+ end
44
+
45
+ def test_noredirect_different_url
46
+ get "http://www.simons-boots.net/foo", {}, { 'HTTP_REFERER' => 'http://www.simons-shoes.net/' }
47
+ assert ! last_response.redirect?
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-magic-incoming-url
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Geoff Youngs
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rack-test
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: ! 'A simple piece of rack middleware to redirect certain URLs when they
47
+ are
48
+
49
+ navigated to directly.
50
+
51
+
52
+ Designed for use with sites where the same site is served across several domain
53
+ names
54
+
55
+ that each highlight different specialities.
56
+
57
+ '
58
+ email:
59
+ - git@intersect-uk.co.uk
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - Rakefile
68
+ - example/config.ru
69
+ - lib/rack/magic-incoming-url.rb
70
+ - magic-incoming-url.gemspec
71
+ - test/magic_redirect_test.rb
72
+ homepage: http://github.com/geoffyoungs/rack-magic-incoming-url
73
+ licenses: []
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 1.8.25
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: Redirect incoming visitors based on domain / url
96
+ test_files: []