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