rack-domain 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edff08a269f7b3cb74731b0da8ed93b1d8f05a4d
4
- data.tar.gz: f1131a023969e1c0ff7448d69108a297e26c66ae
3
+ metadata.gz: 41d7ce04c47ae1bf25c2c8f2003de1da76ffaa85
4
+ data.tar.gz: 72db72f8e0140df322026d53236b0212f35c2ffd
5
5
  SHA512:
6
- metadata.gz: 0e04ee83efd5e55eb3d3cf41714af42b8983cdadba0bc106544d8971bae1d511c8ce50cfe66445fb6983fa56a07685e9fc75cd112ff23935ab5e95fa84200f6d
7
- data.tar.gz: ba157cc98443fbc789a90bbd9679e9d9833c9d0883fe97534207ee14f42f4249f4d25c9d74399f1a613223bd8b65beeaf5a49bfc381604959a2f4ca308f7a666
6
+ metadata.gz: a036dc1bd6474e768f1aa9be61b243db19d830c9b91214e96ae6145cc0fb76fcd4eb785ae4f4cc21e7bbd13d86d04b32270e72e5239610b8f1e35f9fd83090fd
7
+ data.tar.gz: 8d4320d153059937d0fc81b1d8aa2f50be82d077e2c77168d8773f4534bbc7bb7d9efa5a2dbe225fbcedf43a350708657c3c6c5e47efd98dfb046c2b2b6c0cf1
data/Gemfile CHANGED
@@ -1,8 +1,2 @@
1
1
  source 'https://rubygems.org'
2
-
3
- gem 'rack-test',
4
- '>= 0.4',
5
- require: 'rack/test',
6
- group: :test
7
-
8
2
  gemspec
data/README.md CHANGED
@@ -5,6 +5,11 @@
5
5
  [![Coverage Status](https://coveralls.io/repos/whatyouhide/rack-domain/badge.png)](https://coveralls.io/r/whatyouhide/rack-domain)
6
6
  [![Inline docs](http://inch-ci.org/github/whatyouhide/rack-domain.svg?branch=master)](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 guide to
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
- # @param [String, Regexp] filter The filter used to, well, filter the domain.
14
- # If `filter` is a `String`, it will be matched *at the beginning* of the
15
- # domain name; this is done so that it's easy to match subdomains and
16
- # domains without TLDs.
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
- case @filter
57
- when Regexp
58
- @filter =~ @domain
59
- when String
60
- @domain.start_with?(@filter)
61
- else
62
- fail 'The filter must be a Regexp or a String'
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
@@ -4,6 +4,6 @@
4
4
  module Rack
5
5
  class Domain
6
6
  # The version of this gem.
7
- VERSION = '0.1.1'
7
+ VERSION = '1.0.0'
8
8
  end
9
9
  end
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 test_with_a_string
18
- %w(api api.example api.example.com).each do |str|
19
- set_app_to do
20
- use Rack::Domain, str, run: Rack::Lobster.new
21
- run NOT_FOUNDER
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
- assert_dispatches_to_the_right_app
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 test_with_regexps
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: Rack::Lobster.new
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', 'api.exam', /example/, /\.com$/].each do |filter|
60
+ ['api.example.com', /example/, /\.com$/].each do |filter|
41
61
  set_app_to do
42
- use Rack::Domain, filter do
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 test_rack_builder_dsl_extension
54
- require 'rack/domain/dsl'
55
-
56
- set_app_to do
57
- domain 'api', run: Rack::Lobster.new
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
- set_app_to do
63
- domain /^api\./, run: Rack::Lobster.new
64
- run NOT_FOUNDER
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
- def test_argument_errors
83
+ # No arguments passed.
70
84
  assert_app_raises ArgumentError do
71
- lob = Rack::Lobster.new
72
- use(Rack::Domain, 'api', { run: Rack::Lobster.new }) { lob }
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.1.1
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/subdomainer_test.rb
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/subdomainer_test.rb
158
+ - test/domain_test.rb
146
159
  - test/test_helper.rb
147
160
  has_rdoc:
@@ -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