rack-canonical-host 1.1.0 → 1.2.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/CHANGELOG.md +21 -14
- data/README.md +1 -1
- data/lib/rack/canonical_host/redirect.rb +3 -3
- data/lib/rack/canonical_host/version.rb +1 -1
- metadata +19 -38
- data/.github/workflows/ci.yml +0 -30
- data/.gitignore +0 -19
- data/.rspec +0 -3
- data/Appraisals +0 -19
- data/Gemfile +0 -3
- data/Rakefile +0 -8
- data/gemfiles/rack_1.5.gemfile +0 -7
- data/gemfiles/rack_1.6.gemfile +0 -7
- data/gemfiles/rack_2.0.gemfile +0 -7
- data/gemfiles/rack_2.1.gemfile +0 -7
- data/gemfiles/rack_2.2.gemfile +0 -7
- data/rack-canonical-host.gemspec +0 -20
- data/spec/rack/canonical_host_spec.rb +0 -275
- data/spec/spec_helper.rb +0 -26
- data/spec/support/matchers/have_header.rb +0 -56
- data/spec/support/matchers/redirect_to.rb +0 -81
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8d04ccdf68037f3995ea1a93a9f7858d5363fa9e4eae2797d6b35eb14b00e0f2
|
|
4
|
+
data.tar.gz: 30f80af7f437c52e4bdbe61b3a95ee560bba6250546a4b02153d11565e0a9bc6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 78b807b256f6683f3a8864e0f422208475cb03e4baa4bbce50a998000958f98b43f41deead8f400cb0ae78b9ee6b57b0bbb6d3d0504e9faf6b31db3ad13faccc
|
|
7
|
+
data.tar.gz: 3a7186d72cea3a465fece9c11d2e178f1e6f09fa29e39463b58b92440fba32ecc56f2ff42742f5ad1a9359f17a4bff8a2ad3344c47308fd16a71bc2abb540230
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.0 (2023-04-14)
|
|
4
|
+
|
|
5
|
+
* Add support for Rack 3.0 ([Vinny Diehl][vinnydiehl])
|
|
6
|
+
* Remove unneeded gem directives ([Olle Jonsson][olleolleolle])
|
|
7
|
+
|
|
3
8
|
## 1.1.0 (2021-11-10)
|
|
4
9
|
|
|
5
10
|
* Support lambda/proc on `:if` and `:ignore` options ([Sean Huber][shuber])
|
|
@@ -27,7 +32,7 @@
|
|
|
27
32
|
* Remove `:force_ssl` option in favor of using [rack-ssl][rack-ssl]
|
|
28
33
|
([Nathaniel Bibler][nbibler])
|
|
29
34
|
|
|
30
|
-
[rack-ssl]:
|
|
35
|
+
[rack-ssl]: https://rubygems.org/gems/rack-ssl
|
|
31
36
|
|
|
32
37
|
## 0.1.0 (2014-04-16)
|
|
33
38
|
|
|
@@ -74,16 +79,18 @@
|
|
|
74
79
|
|
|
75
80
|
* Initial release ([Tyler Hunt][tylerhunt])
|
|
76
81
|
|
|
77
|
-
[Aupajo]:
|
|
78
|
-
[finack]:
|
|
79
|
-
[firedev]:
|
|
80
|
-
[jcarbo]:
|
|
81
|
-
[jellybob]:
|
|
82
|
-
[jschuur]:
|
|
83
|
-
[nbibler]:
|
|
84
|
-
[rubymaverick]:
|
|
85
|
-
[shuber]:
|
|
86
|
-
[squaresurf]:
|
|
87
|
-
[tma]:
|
|
88
|
-
[tylerhunt]:
|
|
89
|
-
[zoso10]:
|
|
82
|
+
[Aupajo]: https://github.com/Aupajo
|
|
83
|
+
[finack]: https://github.com/finack
|
|
84
|
+
[firedev]: https://github.com/firedev
|
|
85
|
+
[jcarbo]: https://github.com/jcarbo
|
|
86
|
+
[jellybob]: https://github.com/jellybob
|
|
87
|
+
[jschuur]: https://github.com/jschuur
|
|
88
|
+
[nbibler]: https://github.com/nbibler
|
|
89
|
+
[rubymaverick]: https://github.com/ericallam
|
|
90
|
+
[shuber]: https://github.com/shuber
|
|
91
|
+
[squaresurf]: httpss://github.com/squaresurf
|
|
92
|
+
[tma]: https://github.com/tma
|
|
93
|
+
[tylerhunt]: https://github.com/tylerhunt
|
|
94
|
+
[zoso10]: https://github.com/zoso10
|
|
95
|
+
[olleolleolle]: https://github.com/olleolleolle
|
|
96
|
+
[vinnydiehl]: https://github.com/vinnydiehl
|
data/README.md
CHANGED
|
@@ -55,9 +55,9 @@ module Rack
|
|
|
55
55
|
|
|
56
56
|
def headers
|
|
57
57
|
{
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
'
|
|
58
|
+
'cache-control' => cache_control,
|
|
59
|
+
'content-type' => 'text/html',
|
|
60
|
+
'location' => new_url,
|
|
61
61
|
}.reject { |_, value| !value }
|
|
62
62
|
end
|
|
63
63
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-canonical-host
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tyler Hunt
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-04-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: addressable
|
|
@@ -36,20 +36,20 @@ dependencies:
|
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 1
|
|
39
|
+
version: '1'
|
|
40
40
|
- - "<"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: '
|
|
42
|
+
version: '4'
|
|
43
43
|
type: :runtime
|
|
44
44
|
prerelease: false
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
46
46
|
requirements:
|
|
47
47
|
- - ">="
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: 1
|
|
49
|
+
version: '1'
|
|
50
50
|
- - "<"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: '
|
|
52
|
+
version: '4'
|
|
53
53
|
- !ruby/object:Gem::Dependency
|
|
54
54
|
name: appraisal
|
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -68,16 +68,16 @@ dependencies:
|
|
|
68
68
|
name: rake
|
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
|
70
70
|
requirements:
|
|
71
|
-
- - "
|
|
71
|
+
- - "~>"
|
|
72
72
|
- !ruby/object:Gem::Version
|
|
73
|
-
version: '0'
|
|
73
|
+
version: '13.0'
|
|
74
74
|
type: :development
|
|
75
75
|
prerelease: false
|
|
76
76
|
version_requirements: !ruby/object:Gem::Requirement
|
|
77
77
|
requirements:
|
|
78
|
-
- - "
|
|
78
|
+
- - "~>"
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
|
-
version: '0'
|
|
80
|
+
version: '13.0'
|
|
81
81
|
- !ruby/object:Gem::Dependency
|
|
82
82
|
name: rspec
|
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -92,39 +92,24 @@ dependencies:
|
|
|
92
92
|
- - "~>"
|
|
93
93
|
- !ruby/object:Gem::Version
|
|
94
94
|
version: '3.0'
|
|
95
|
-
description:
|
|
96
|
-
email:
|
|
95
|
+
description:
|
|
96
|
+
email:
|
|
97
97
|
executables: []
|
|
98
98
|
extensions: []
|
|
99
99
|
extra_rdoc_files: []
|
|
100
100
|
files:
|
|
101
|
-
- ".github/workflows/ci.yml"
|
|
102
|
-
- ".gitignore"
|
|
103
|
-
- ".rspec"
|
|
104
|
-
- Appraisals
|
|
105
101
|
- CHANGELOG.md
|
|
106
|
-
- Gemfile
|
|
107
102
|
- LICENSE
|
|
108
103
|
- README.md
|
|
109
|
-
- Rakefile
|
|
110
|
-
- gemfiles/rack_1.5.gemfile
|
|
111
|
-
- gemfiles/rack_1.6.gemfile
|
|
112
|
-
- gemfiles/rack_2.0.gemfile
|
|
113
|
-
- gemfiles/rack_2.1.gemfile
|
|
114
|
-
- gemfiles/rack_2.2.gemfile
|
|
115
104
|
- lib/rack-canonical-host.rb
|
|
116
105
|
- lib/rack/canonical_host.rb
|
|
117
106
|
- lib/rack/canonical_host/redirect.rb
|
|
118
107
|
- lib/rack/canonical_host/version.rb
|
|
119
|
-
- rack-canonical-host.gemspec
|
|
120
|
-
- spec/rack/canonical_host_spec.rb
|
|
121
|
-
- spec/spec_helper.rb
|
|
122
|
-
- spec/support/matchers/have_header.rb
|
|
123
|
-
- spec/support/matchers/redirect_to.rb
|
|
124
108
|
homepage: https://github.com/tylerhunt/rack-canonical-host
|
|
125
|
-
licenses:
|
|
109
|
+
licenses:
|
|
110
|
+
- MIT
|
|
126
111
|
metadata: {}
|
|
127
|
-
post_install_message:
|
|
112
|
+
post_install_message:
|
|
128
113
|
rdoc_options: []
|
|
129
114
|
require_paths:
|
|
130
115
|
- lib
|
|
@@ -139,12 +124,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
139
124
|
- !ruby/object:Gem::Version
|
|
140
125
|
version: '0'
|
|
141
126
|
requirements: []
|
|
142
|
-
rubygems_version: 3.
|
|
143
|
-
signing_key:
|
|
127
|
+
rubygems_version: 3.3.26
|
|
128
|
+
signing_key:
|
|
144
129
|
specification_version: 4
|
|
145
130
|
summary: Rack middleware for defining a canonical host name.
|
|
146
|
-
test_files:
|
|
147
|
-
- spec/rack/canonical_host_spec.rb
|
|
148
|
-
- spec/spec_helper.rb
|
|
149
|
-
- spec/support/matchers/have_header.rb
|
|
150
|
-
- spec/support/matchers/redirect_to.rb
|
|
131
|
+
test_files: []
|
data/.github/workflows/ci.yml
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
on:
|
|
3
|
-
- push
|
|
4
|
-
- pull_request
|
|
5
|
-
jobs:
|
|
6
|
-
test:
|
|
7
|
-
name: Ruby ${{ matrix.ruby }} & Rack ${{ matrix.rack }}
|
|
8
|
-
runs-on: 'ubuntu-latest'
|
|
9
|
-
strategy:
|
|
10
|
-
matrix:
|
|
11
|
-
ruby:
|
|
12
|
-
- '3.0'
|
|
13
|
-
- '2.7'
|
|
14
|
-
- '2.6'
|
|
15
|
-
rack:
|
|
16
|
-
- '1.5'
|
|
17
|
-
- '1.6'
|
|
18
|
-
- '2.0'
|
|
19
|
-
- '2.1'
|
|
20
|
-
- '2.2'
|
|
21
|
-
fail-fast: false
|
|
22
|
-
env:
|
|
23
|
-
BUNDLE_GEMFILE: "gemfiles/rack_${{ matrix.rack }}.gemfile"
|
|
24
|
-
steps:
|
|
25
|
-
- uses: actions/checkout@v2
|
|
26
|
-
- uses: ruby/setup-ruby@v1
|
|
27
|
-
with:
|
|
28
|
-
ruby-version: ${{ matrix.ruby }}
|
|
29
|
-
- run: bundle install
|
|
30
|
-
- run: bundle exec rake
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/Appraisals
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
appraise 'rack-1.5' do
|
|
2
|
-
gem 'rack', '~> 1.5.0'
|
|
3
|
-
end
|
|
4
|
-
|
|
5
|
-
appraise 'rack-1.6' do
|
|
6
|
-
gem 'rack', '~> 1.6.0'
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
appraise 'rack-2.0' do
|
|
10
|
-
gem 'rack', '~> 2.0.0'
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
appraise 'rack-2.1' do
|
|
14
|
-
gem 'rack', '~> 2.1.0'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
appraise 'rack-2.2' do
|
|
18
|
-
gem 'rack', '~> 2.2.0'
|
|
19
|
-
end
|
data/Gemfile
DELETED
data/Rakefile
DELETED
data/gemfiles/rack_1.5.gemfile
DELETED
data/gemfiles/rack_1.6.gemfile
DELETED
data/gemfiles/rack_2.0.gemfile
DELETED
data/gemfiles/rack_2.1.gemfile
DELETED
data/gemfiles/rack_2.2.gemfile
DELETED
data/rack-canonical-host.gemspec
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require './lib/rack/canonical_host/version'
|
|
2
|
-
|
|
3
|
-
Gem::Specification.new do |gem|
|
|
4
|
-
gem.name = 'rack-canonical-host'
|
|
5
|
-
gem.version = Rack::CanonicalHost::VERSION
|
|
6
|
-
gem.summary = 'Rack middleware for defining a canonical host name.'
|
|
7
|
-
gem.homepage = 'https://github.com/tylerhunt/rack-canonical-host'
|
|
8
|
-
gem.author = 'Tyler Hunt'
|
|
9
|
-
|
|
10
|
-
gem.add_dependency 'addressable', '> 0', '< 3'
|
|
11
|
-
gem.add_dependency 'rack', ['>= 1.0.0', '< 3']
|
|
12
|
-
gem.add_development_dependency 'appraisal', '~> 2.2'
|
|
13
|
-
gem.add_development_dependency 'rake'
|
|
14
|
-
gem.add_development_dependency 'rspec', '~> 3.0'
|
|
15
|
-
|
|
16
|
-
gem.files = `git ls-files`.split($\)
|
|
17
|
-
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
18
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
19
|
-
gem.require_paths = ['lib']
|
|
20
|
-
end
|
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
RSpec.describe Rack::CanonicalHost do
|
|
2
|
-
let(:app_response) { [200, { 'Content-Type' => 'text/plain' }, %w(OK)] }
|
|
3
|
-
let(:inner_app) { ->(env) { response } }
|
|
4
|
-
|
|
5
|
-
before do
|
|
6
|
-
allow(inner_app)
|
|
7
|
-
.to receive(:call)
|
|
8
|
-
.with(env)
|
|
9
|
-
.and_return(app_response)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def build_app(host=nil, options={}, inner_app=inner_app(), &block)
|
|
13
|
-
Rack::Builder.new do
|
|
14
|
-
use Rack::Lint
|
|
15
|
-
use Rack::CanonicalHost, host, options, &block
|
|
16
|
-
run inner_app
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
shared_context 'a matching request' do
|
|
21
|
-
context 'with a request to a matching host' do
|
|
22
|
-
let(:url) { 'http://example.com/full/path' }
|
|
23
|
-
|
|
24
|
-
it { should_not be_redirect }
|
|
25
|
-
|
|
26
|
-
it 'calls the inner app' do
|
|
27
|
-
expect(inner_app).to receive(:call).with(env)
|
|
28
|
-
call_app
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
shared_context 'a non-matching request' do
|
|
34
|
-
context 'with a request to a non-matching host' do
|
|
35
|
-
let(:url) { 'http://www.example.com/full/path' }
|
|
36
|
-
|
|
37
|
-
it { should redirect_to('http://example.com/full/path') }
|
|
38
|
-
|
|
39
|
-
it 'does not call the inner app' do
|
|
40
|
-
expect(inner_app).to_not receive(:call)
|
|
41
|
-
call_app
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it { expect(response).to_not have_header('Cache-Control') }
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
shared_context 'matching and non-matching requests' do
|
|
49
|
-
include_context 'a matching request'
|
|
50
|
-
include_context 'a non-matching request'
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context '#call' do
|
|
54
|
-
let(:headers) { {} }
|
|
55
|
-
|
|
56
|
-
let(:app) { build_app('example.com') }
|
|
57
|
-
let(:env) { Rack::MockRequest.env_for(url, headers) }
|
|
58
|
-
|
|
59
|
-
def call_app
|
|
60
|
-
app.call(env)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
subject(:response) { call_app }
|
|
64
|
-
|
|
65
|
-
include_context 'a matching request'
|
|
66
|
-
include_context 'a non-matching request'
|
|
67
|
-
|
|
68
|
-
context 'when the request has a pipe in the URL' do
|
|
69
|
-
let(:url) { 'https://example.com/full/path?value=withPIPE' }
|
|
70
|
-
|
|
71
|
-
before { env['QUERY_STRING'].sub!('PIPE', '|') }
|
|
72
|
-
|
|
73
|
-
it { expect { call_app }.to_not raise_error }
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
context 'when the request has JavaScript in the URL' do
|
|
77
|
-
let(:url) { 'http://www.example.com/full/path' }
|
|
78
|
-
|
|
79
|
-
let(:headers) {
|
|
80
|
-
{ 'QUERY_STRING' => '"><script>alert(73541);</script>' }
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let(:app) { build_app('example.com') }
|
|
84
|
-
|
|
85
|
-
it 'escapes the JavaScript' do
|
|
86
|
-
expect(response)
|
|
87
|
-
.to redirect_to('http://example.com/full/path?%22%3E%3Cscript%3Ealert(73541)%3B%3C/script%3E')
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
context 'with an X-Forwarded-Host' do
|
|
92
|
-
let(:url) { 'http://proxy.test/full/path' }
|
|
93
|
-
|
|
94
|
-
context 'which matches the canonical host' do
|
|
95
|
-
let(:headers) { { 'HTTP_X_FORWARDED_HOST' => 'example.com:80' } }
|
|
96
|
-
|
|
97
|
-
include_context 'a matching request'
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
context 'which does not match the canonical host' do
|
|
101
|
-
let(:headers) { { 'HTTP_X_FORWARDED_HOST' => 'www.example.com:80' } }
|
|
102
|
-
|
|
103
|
-
include_context 'a non-matching request'
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
context 'without a host' do
|
|
108
|
-
let(:app) { build_app(nil) }
|
|
109
|
-
|
|
110
|
-
include_context 'a matching request'
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
context 'with :ignore option' do
|
|
114
|
-
context 'with lambda/proc' do
|
|
115
|
-
let(:app) {
|
|
116
|
-
build_app(
|
|
117
|
-
'example.com',
|
|
118
|
-
ignore: ->(uri) { uri.host == 'example.net' }
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
include_context 'a matching request'
|
|
123
|
-
include_context 'a non-matching request'
|
|
124
|
-
|
|
125
|
-
context 'with a request to an ignored host' do
|
|
126
|
-
let(:url) { 'http://example.net/full/path' }
|
|
127
|
-
|
|
128
|
-
it { should_not be_redirect }
|
|
129
|
-
|
|
130
|
-
it 'calls the inner app' do
|
|
131
|
-
expect(inner_app).to receive(:call).with(env)
|
|
132
|
-
call_app
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
context 'with string' do
|
|
138
|
-
let(:app) { build_app('example.com', ignore: 'example.net') }
|
|
139
|
-
|
|
140
|
-
include_context 'a matching request'
|
|
141
|
-
include_context 'a non-matching request'
|
|
142
|
-
|
|
143
|
-
context 'with a request to an ignored host' do
|
|
144
|
-
let(:url) { 'http://example.net/full/path' }
|
|
145
|
-
|
|
146
|
-
it { should_not be_redirect }
|
|
147
|
-
|
|
148
|
-
it 'calls the inner app' do
|
|
149
|
-
expect(inner_app).to receive(:call).with(env)
|
|
150
|
-
call_app
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
context 'with regular expression' do
|
|
156
|
-
let(:app) { build_app('example.com', ignore: /ex.*\.net/) }
|
|
157
|
-
|
|
158
|
-
include_context 'a matching request'
|
|
159
|
-
include_context 'a non-matching request'
|
|
160
|
-
|
|
161
|
-
context 'with a request to an ignored host' do
|
|
162
|
-
let(:url) { 'http://example.net/full/path' }
|
|
163
|
-
|
|
164
|
-
it { should_not be_redirect }
|
|
165
|
-
|
|
166
|
-
it 'calls the inner app' do
|
|
167
|
-
expect(inner_app).to receive(:call).with(env)
|
|
168
|
-
call_app
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
context 'with :if option' do
|
|
175
|
-
context 'with a lambda/proc' do
|
|
176
|
-
let(:app) {
|
|
177
|
-
build_app(
|
|
178
|
-
'www.example.com',
|
|
179
|
-
if: ->(uri) { uri.host == 'example.com' }
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
context 'with a request to a matching host' do
|
|
184
|
-
let(:url) { 'http://example.com/full/path' }
|
|
185
|
-
|
|
186
|
-
it { should redirect_to('http://www.example.com/full/path') }
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
context 'with a request to a non-matching host' do
|
|
190
|
-
let(:url) { 'http://api.example.com/full/path' }
|
|
191
|
-
|
|
192
|
-
it { should_not be_redirect }
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
context 'with string' do
|
|
197
|
-
let(:app) { build_app('www.example.com', if: 'example.com') }
|
|
198
|
-
|
|
199
|
-
context 'with a request to a matching host' do
|
|
200
|
-
let(:url) { 'http://example.com/full/path' }
|
|
201
|
-
|
|
202
|
-
it { should redirect_to('http://www.example.com/full/path') }
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
context 'with a request to a non-matching host' do
|
|
206
|
-
let(:url) { 'http://api.example.com/full/path' }
|
|
207
|
-
|
|
208
|
-
it { should_not be_redirect }
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
context 'with a regular expression' do
|
|
213
|
-
let(:app) { build_app('example.com', if: '.*\.example\.com') }
|
|
214
|
-
|
|
215
|
-
context 'with a request to a matching host' do
|
|
216
|
-
let(:url) { 'http://www.example.com/full/path' }
|
|
217
|
-
|
|
218
|
-
it { should_not redirect_to('http://example.com/full/path') }
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
context 'with a request to a non-matching host' do
|
|
222
|
-
let(:url) { 'http://www.example.net/full/path' }
|
|
223
|
-
|
|
224
|
-
it { should_not be_redirect }
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
context 'with a :cache_control option' do
|
|
230
|
-
let(:url) { 'http://subdomain.example.net/full/path' }
|
|
231
|
-
|
|
232
|
-
context 'with a max-age value' do
|
|
233
|
-
let(:app) {
|
|
234
|
-
build_app('example.com', cache_control: 'max-age=3600')
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
it {
|
|
238
|
-
expect(response).to have_header('Cache-Control').with('max-age=3600')
|
|
239
|
-
}
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
context 'with a no-cache value' do
|
|
243
|
-
let(:app) { build_app('example.com', cache_control: 'no-cache') }
|
|
244
|
-
|
|
245
|
-
it { expect(subject).to have_header('Cache-Control').with('no-cache') }
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
context 'with a false value' do
|
|
249
|
-
let(:app) { build_app('example.com', cache_control: false) }
|
|
250
|
-
|
|
251
|
-
it { expect(subject).to_not have_header('Cache-Control') }
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
context 'with a nil value' do
|
|
255
|
-
let(:app) { build_app('example.com', cache_control: false) }
|
|
256
|
-
|
|
257
|
-
it { expect(subject).to_not have_header('Cache-Control') }
|
|
258
|
-
end
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
context 'with a block' do
|
|
262
|
-
let(:app) { build_app { 'example.com' } }
|
|
263
|
-
|
|
264
|
-
include_context 'a matching request'
|
|
265
|
-
include_context 'a non-matching request'
|
|
266
|
-
|
|
267
|
-
context 'that returns nil' do
|
|
268
|
-
let(:app) { build_app('example.com') { nil } }
|
|
269
|
-
|
|
270
|
-
include_context 'a matching request'
|
|
271
|
-
include_context 'a non-matching request'
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
require 'rack/canonical_host'
|
|
2
|
-
|
|
3
|
-
Dir[File.expand_path('../support/**/*.rb', __FILE__)].each do |file|
|
|
4
|
-
require(file)
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
RSpec.configure do |config|
|
|
8
|
-
config.filter_run :focus
|
|
9
|
-
config.run_all_when_everything_filtered = true
|
|
10
|
-
|
|
11
|
-
config.order = :random
|
|
12
|
-
Kernel.srand config.seed
|
|
13
|
-
|
|
14
|
-
if config.files_to_run.one?
|
|
15
|
-
config.default_formatter = 'doc'
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
config.expect_with :rspec do |expectations|
|
|
19
|
-
expectations.syntax = :expect
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
config.mock_with :rspec do |mocks|
|
|
23
|
-
mocks.syntax = :expect
|
|
24
|
-
mocks.verify_partial_doubles = true
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
module HaveHeader
|
|
2
|
-
class Matcher
|
|
3
|
-
def initialize(expected_header)
|
|
4
|
-
self.expected_header = expected_header
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def matches?(response)
|
|
8
|
-
_, self.actual_headers, _ = response
|
|
9
|
-
|
|
10
|
-
if expected_value
|
|
11
|
-
actual_header == expected_value
|
|
12
|
-
else
|
|
13
|
-
actual_header
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def with(expected_value)
|
|
18
|
-
self.expected_value = expected_value
|
|
19
|
-
self
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def description
|
|
23
|
-
sentence = "have header #{expected_header.inspect}"
|
|
24
|
-
sentence << " with #{expected_value.inspect}" if expected_value
|
|
25
|
-
sentence
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def failure_message
|
|
29
|
-
"Expected response to #{description}"
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def failure_message_when_negated
|
|
33
|
-
"Did not expect response to #{description}"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
protected
|
|
37
|
-
|
|
38
|
-
attr_accessor :actual_headers
|
|
39
|
-
attr_accessor :expected_header
|
|
40
|
-
attr_accessor :expected_value
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
def actual_header
|
|
45
|
-
actual_headers[expected_header]
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def have_header(name)
|
|
50
|
-
Matcher.new(name)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
RSpec.configure do |config|
|
|
55
|
-
config.include HaveHeader
|
|
56
|
-
end
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
module RedirectTo
|
|
2
|
-
class Matcher
|
|
3
|
-
def initialize(expected_location)
|
|
4
|
-
self.expected_location = expected_location
|
|
5
|
-
self.expected_status_code = STATUS
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def matches?(response)
|
|
9
|
-
self.actual_status_code, self.actual_headers, _ = response
|
|
10
|
-
|
|
11
|
-
status_code_matches? && location_matches?
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def via(expected_status_code)
|
|
15
|
-
self.expected_status_code = expected_status_code
|
|
16
|
-
self
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def description
|
|
20
|
-
if expected_status_code && expected_location
|
|
21
|
-
"redirect to #{expected_location.inspect} via #{expected_status_code}"
|
|
22
|
-
elsif expected_status_code
|
|
23
|
-
"redirect via #{expected_status_code}"
|
|
24
|
-
elsif expected_location
|
|
25
|
-
"redirect to #{expected_location.inspect}"
|
|
26
|
-
else
|
|
27
|
-
'be a redirect'
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def failure_message
|
|
32
|
-
"Expected response to #{description}"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def failure_message_when_negated
|
|
36
|
-
"Did not expect response to #{description}"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
protected
|
|
40
|
-
|
|
41
|
-
attr_accessor :actual_headers
|
|
42
|
-
attr_accessor :actual_status_code
|
|
43
|
-
attr_accessor :expected_location
|
|
44
|
-
attr_accessor :expected_status_code
|
|
45
|
-
|
|
46
|
-
private
|
|
47
|
-
|
|
48
|
-
LOCATION = 'Location'
|
|
49
|
-
STATUS = 301
|
|
50
|
-
|
|
51
|
-
def actual_location
|
|
52
|
-
actual_headers[LOCATION]
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def status_code_matches?
|
|
56
|
-
if expected_status_code
|
|
57
|
-
actual_status_code == expected_status_code
|
|
58
|
-
else
|
|
59
|
-
actual_status_code.to_s =~ /^30[1237]$/
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def location_matches?
|
|
64
|
-
if expected_location
|
|
65
|
-
expected_location == actual_location
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def redirect_to(location)
|
|
71
|
-
Matcher.new(location)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def be_redirect
|
|
75
|
-
Matcher.new(nil).via(nil)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
RSpec.configure do |config|
|
|
80
|
-
config.include RedirectTo
|
|
81
|
-
end
|