rack-domain 0.1.1 → 1.0.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 +4 -4
- data/Gemfile +0 -6
- data/README.md +56 -2
- data/lib/rack/domain.rb +37 -11
- data/lib/rack/domain/version.rb +1 -1
- data/rack-domain.gemspec +2 -1
- data/test/{subdomainer_test.rb → domain_test.rb} +47 -34
- metadata +18 -5
- data/lib/rack/domain/dsl.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41d7ce04c47ae1bf25c2c8f2003de1da76ffaa85
|
4
|
+
data.tar.gz: 72db72f8e0140df322026d53236b0212f35c2ffd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a036dc1bd6474e768f1aa9be61b243db19d830c9b91214e96ae6145cc0fb76fcd4eb785ae4f4cc21e7bbd13d86d04b32270e72e5239610b8f1e35f9fd83090fd
|
7
|
+
data.tar.gz: 8d4320d153059937d0fc81b1d8aa2f50be82d077e2c77168d8773f4534bbc7bb7d9efa5a2dbe225fbcedf43a350708657c3c6c5e47efd98dfb046c2b2b6c0cf1
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -5,6 +5,11 @@
|
|
5
5
|
[](https://coveralls.io/r/whatyouhide/rack-domain)
|
6
6
|
[](http://inch-ci.org/github/whatyouhide/rack-domain)
|
7
7
|
|
8
|
+
`Rack::Domain` is a Rack middleware that enables you to intercept a request with
|
9
|
+
a specific domain or subdomain (or regexp that matches a domain, actually) and
|
10
|
+
route it to a specific application.
|
11
|
+
|
12
|
+
|
8
13
|
## Installation
|
9
14
|
|
10
15
|
Add this line to your application's Gemfile:
|
@@ -22,10 +27,59 @@ Or install it yourself as:
|
|
22
27
|
$ gem install rack-domain
|
23
28
|
|
24
29
|
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
`Rack::Domain` supports three kinds of filters in order to match a domain.
|
33
|
+
|
34
|
+
- A string: it will match only if the string is exactly the same as the domain.
|
35
|
+
- A regexp: it will match if the domain matches the regexp.
|
36
|
+
- An array of strings and regexps: it will match if at least one of the elements
|
37
|
+
of the array matches (as described above) the domain.
|
38
|
+
|
39
|
+
To decide where to dispatch the request if there's a match, you can use an
|
40
|
+
existing Rack app through the `:run` option, or you can pass a block in which
|
41
|
+
you can use the classic `use|run|map...` syntax. This works because the block is
|
42
|
+
directly passed to a new instance of `Rack::Builder`.
|
43
|
+
|
44
|
+
### Examples
|
45
|
+
|
46
|
+
Using a regexp:
|
47
|
+
|
48
|
+
``` ruby
|
49
|
+
# Match the 'lobster' subdomain.
|
50
|
+
use Rack::Domain, /^lobster\./, run: Rack::Lobster.new
|
51
|
+
```
|
52
|
+
|
53
|
+
Using a string:
|
54
|
+
|
55
|
+
``` ruby
|
56
|
+
# Match only if the current domain is github.com:
|
57
|
+
use Rack::Domain, 'github.com', run: MyGitHubClone
|
58
|
+
```
|
59
|
+
|
60
|
+
Using an array of strings and regexps:
|
61
|
+
|
62
|
+
``` ruby
|
63
|
+
use Rack::Domain, ['lobst.er', /^lobster\./], run: Rack::Lobster.new
|
64
|
+
```
|
65
|
+
|
66
|
+
Using an on-the-fly app build with a `Rack::Builder`-style block:
|
67
|
+
|
68
|
+
``` ruby
|
69
|
+
use Rack::Domain, /^api/ do
|
70
|
+
use Rack::Logger
|
71
|
+
run MyApi
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
|
25
76
|
## Contributing
|
26
77
|
|
27
|
-
Fork, make changes, commit, open Pull Request! Read the [GitHub
|
28
|
-
forking][forking] if you don't know how to.
|
78
|
+
Fork, make changes, commit, open Pull Request, be awesome! Read the [GitHub
|
79
|
+
guide to forking][forking] if you don't know how to.
|
80
|
+
|
81
|
+
Also, issues are more than welcome! Open one if you find a bug, you have a
|
82
|
+
suggestion or simply to ask a question.
|
29
83
|
|
30
84
|
|
31
85
|
|
data/lib/rack/domain.rb
CHANGED
@@ -4,20 +4,38 @@ require 'rack/domain/version'
|
|
4
4
|
|
5
5
|
# This Rack middleware allows to intercept requests and route them to different
|
6
6
|
# apps based on the domain (full, with subdomains and the TLD).
|
7
|
+
#
|
8
|
+
# @example Using a regexp
|
9
|
+
# # Match the 'lobster' subdomain.
|
10
|
+
# use Rack::Domain, /^lobster\./, run: Rack::Lobster.new
|
11
|
+
# @example Using a string
|
12
|
+
# # Match only if the current domain is github.com:
|
13
|
+
# use Rack::Domain, 'github.com', run: MyGitHubClone
|
14
|
+
# @example Using an array of strings and regexps
|
15
|
+
# use Rack::Domain, ['lobst.er', /^lobster\./], run: Rack::Lobster.new
|
16
|
+
# @example Using an on-the-fly app build with a `Rack::Builder` block:
|
17
|
+
# use Rack::Domain, /^api/ do
|
18
|
+
# use Rack::Logger
|
19
|
+
# run MyApi
|
20
|
+
# end
|
7
21
|
class Rack::Domain
|
8
22
|
# Create a new instance of this middleware.
|
9
23
|
# **Note** that this method is the method called by `Rack::Builder#use`.
|
10
24
|
#
|
11
25
|
# @param [#call] next_app The next app on the stack, filled automatically by
|
12
26
|
# Rack when building the middlware chain.
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# domain
|
16
|
-
#
|
27
|
+
#
|
28
|
+
# @param [String, Regexp, Array<String, Regexp>] filter The filter used to,
|
29
|
+
# well, filter the domain. If `filter` is a `String`, it will be matched as the
|
30
|
+
# entire domain; if it's a regexp, it will be matched as a regexp. If it's
|
31
|
+
# an array of strings and regexps, it will match if any of the elements of
|
32
|
+
# the array matches the domain as specified above.
|
33
|
+
#
|
17
34
|
# @param [Hash] opts An hash of options.
|
18
35
|
# @option opts [#call, nil] :run The Rack app to run if the domain matches the
|
19
36
|
# filter. If you don't want to pass a ready application, you can pass a
|
20
37
|
# block with `Rack::Builder` syntax which will create a Rack app on-the-fly.
|
38
|
+
#
|
21
39
|
# @raise [ArgumentError] if both a building block and an app to run were
|
22
40
|
# passed to this function.
|
23
41
|
def initialize(next_app, filter, opts = {}, &block)
|
@@ -51,15 +69,23 @@ class Rack::Domain
|
|
51
69
|
|
52
70
|
# Return `true` if the domain of the current request matches the given
|
53
71
|
# `@filter`, `false` otherwise.
|
72
|
+
# @raise [ArgumentError] if the filter or array of filters aren't regexps or
|
73
|
+
# strings.
|
54
74
|
# @return [Boolean]
|
55
75
|
def domain_matches?
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
76
|
+
# Force the filter to be an array.
|
77
|
+
@filter = [@filter] unless @filter.is_a?(Array)
|
78
|
+
|
79
|
+
# Check if any of the elements of the `@filter` array matches the domain.
|
80
|
+
# The matching test is done based on the element's type.
|
81
|
+
@filter.any? do |flt|
|
82
|
+
if flt.is_a?(Regexp)
|
83
|
+
flt =~ @domain
|
84
|
+
elsif flt.is_a?(String)
|
85
|
+
flt == @domain
|
86
|
+
else
|
87
|
+
fail ArgumentError, 'The filters must be strings or regexps'
|
88
|
+
end
|
63
89
|
end
|
64
90
|
end
|
65
91
|
end
|
data/lib/rack/domain/version.rb
CHANGED
data/rack-domain.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.homepage = 'https://github.com/whatyouhide/rack-domain'
|
12
12
|
spec.license = 'MIT'
|
13
13
|
spec.summary = <<-SUMMARY
|
14
|
-
Rack middleware for dispatching Rack apps based on the domain
|
14
|
+
Rack middleware for dispatching Rack apps based on the domain.
|
15
15
|
SUMMARY
|
16
16
|
spec.description = <<-DESCRIPTION
|
17
17
|
This Rack middleware allows you to run specific apps when the request
|
@@ -31,4 +31,5 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency 'minitest', '~> 5'
|
32
32
|
spec.add_development_dependency 'minitest-reporters', '~> 1'
|
33
33
|
spec.add_development_dependency 'coveralls', '~> 0.7'
|
34
|
+
spec.add_development_dependency 'rack-test', '>= 0.4'
|
34
35
|
end
|
@@ -2,11 +2,8 @@
|
|
2
2
|
|
3
3
|
require_relative 'test_helper'
|
4
4
|
|
5
|
+
LOBSTER = lambda { |env| [200, {}, ['Lobstericious']] }
|
5
6
|
NOT_FOUNDER = lambda { |env| [404, {}, ['Error']] }
|
6
|
-
LOBSTER = Rack::Builder.new do
|
7
|
-
map('/lobster') { run Rack::Lobster.new }
|
8
|
-
map('/') { run NOT_FOUNDER }
|
9
|
-
end
|
10
7
|
|
11
8
|
class DomainTest < Minitest::Test
|
12
9
|
include Rack::Test::Methods
|
@@ -14,21 +11,28 @@ class DomainTest < Minitest::Test
|
|
14
11
|
BASE_URL = 'http://example.com'
|
15
12
|
BASE_URL_WITH_SUBDOMAIN = 'http://api.example.com'
|
16
13
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
14
|
+
def test_with_a_single_specific_domain
|
15
|
+
set_app_to do
|
16
|
+
use Rack::Domain, 'api.example.com', run: LOBSTER
|
17
|
+
run NOT_FOUNDER
|
18
|
+
end
|
23
19
|
|
24
|
-
|
20
|
+
assert_dispatches_to_the_right_app
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_with_an_array_of_domains
|
24
|
+
set_app_to do
|
25
|
+
use Rack::Domain, %w(api.a.b api.example.com), run: LOBSTER
|
26
|
+
run NOT_FOUNDER
|
25
27
|
end
|
28
|
+
|
29
|
+
assert_dispatches_to_the_right_app
|
26
30
|
end
|
27
31
|
|
28
|
-
def
|
32
|
+
def test_with_single_regexps
|
29
33
|
[/^api\./, /.+/, /example/, /\.com$/].each do |regexp|
|
30
34
|
set_app_to do
|
31
|
-
use Rack::Domain, regexp, run:
|
35
|
+
use Rack::Domain, regexp, run: LOBSTER
|
32
36
|
run NOT_FOUNDER
|
33
37
|
end
|
34
38
|
|
@@ -36,13 +40,26 @@ class DomainTest < Minitest::Test
|
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
43
|
+
def test_with_an_array_of_regexps
|
44
|
+
set_app_to do
|
45
|
+
use Rack::Domain, [/api/, /test/], run: LOBSTER
|
46
|
+
run NOT_FOUNDER
|
47
|
+
end
|
48
|
+
|
49
|
+
assert_dispatches_to_the_right_app
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_matching_with_a_mixed_array
|
53
|
+
set_app_to do
|
54
|
+
use Rack::Domain, [/api/, 'api.example.com'], run: LOBSTER
|
55
|
+
run NOT_FOUNDER
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
39
59
|
def test_with_a_block
|
40
|
-
['api
|
60
|
+
['api.example.com', /example/, /\.com$/].each do |filter|
|
41
61
|
set_app_to do
|
42
|
-
use
|
43
|
-
run Rack::Lobster.new
|
44
|
-
end
|
45
|
-
|
62
|
+
use(Rack::Domain, filter) { run LOBSTER }
|
46
63
|
run NOT_FOUNDER
|
47
64
|
end
|
48
65
|
|
@@ -50,27 +67,23 @@ class DomainTest < Minitest::Test
|
|
50
67
|
end
|
51
68
|
end
|
52
69
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
run NOT_FOUNDER
|
70
|
+
def test_argument_errors
|
71
|
+
# Both a block and a :run option.
|
72
|
+
assert_app_raises ArgumentError do
|
73
|
+
use(Rack::Domain, 'api', run: LOBSTER) { lob }
|
74
|
+
run LOBSTER
|
59
75
|
end
|
60
|
-
assert_dispatches_to_the_right_app
|
61
76
|
|
62
|
-
|
63
|
-
|
64
|
-
run
|
77
|
+
# No filter specified.
|
78
|
+
assert_app_raises ArgumentError do
|
79
|
+
use(Rack::Domain, {}) { run LOBSTER }
|
80
|
+
run LOBSTER
|
65
81
|
end
|
66
|
-
assert_dispatches_to_the_right_app
|
67
|
-
end
|
68
82
|
|
69
|
-
|
83
|
+
# No arguments passed.
|
70
84
|
assert_app_raises ArgumentError do
|
71
|
-
|
72
|
-
|
73
|
-
run lob
|
85
|
+
use(Rack::Domain)
|
86
|
+
run LOBSTER
|
74
87
|
end
|
75
88
|
end
|
76
89
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-domain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrea Leopardi
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.7'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rack-test
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.4'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.4'
|
97
111
|
description: |2
|
98
112
|
This Rack middleware allows you to run specific apps when the request
|
99
113
|
domain matches a given filter. The filter can be provided in a number of
|
@@ -112,10 +126,9 @@ files:
|
|
112
126
|
- README.md
|
113
127
|
- Rakefile
|
114
128
|
- lib/rack/domain.rb
|
115
|
-
- lib/rack/domain/dsl.rb
|
116
129
|
- lib/rack/domain/version.rb
|
117
130
|
- rack-domain.gemspec
|
118
|
-
- test/
|
131
|
+
- test/domain_test.rb
|
119
132
|
- test/test_helper.rb
|
120
133
|
homepage: https://github.com/whatyouhide/rack-domain
|
121
134
|
licenses:
|
@@ -140,8 +153,8 @@ rubyforge_project:
|
|
140
153
|
rubygems_version: 2.2.2
|
141
154
|
signing_key:
|
142
155
|
specification_version: 4
|
143
|
-
summary: Rack middleware for dispatching Rack apps based on the domain
|
156
|
+
summary: Rack middleware for dispatching Rack apps based on the domain.
|
144
157
|
test_files:
|
145
|
-
- test/
|
158
|
+
- test/domain_test.rb
|
146
159
|
- test/test_helper.rb
|
147
160
|
has_rdoc:
|
data/lib/rack/domain/dsl.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'rack/domain'
|
4
|
-
|
5
|
-
# This class is monkeypatched with the `#domain` method.
|
6
|
-
class Rack::Builder
|
7
|
-
# Behaves just like `use Rack::Domain`, but with a simpler and clearer syntax.
|
8
|
-
#
|
9
|
-
# @param [String, Regexp] filter The filter used to match the domain.
|
10
|
-
# @param [Hash] opts An hash of options.
|
11
|
-
# @option opts [#call, nil] :run The app to run if the domain matches.
|
12
|
-
#
|
13
|
-
# @raise [ArgumentError] if no app to run or block were passed, or if both
|
14
|
-
# were passed.
|
15
|
-
def domain(filter, opts = {}, &block)
|
16
|
-
use(Rack::Domain, filter, opts, &block)
|
17
|
-
end
|
18
|
-
end
|