pact-provider-proxy 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.gitignore +1 -0
- data/CHANGELOG.md +4 -0
- data/lib/pact/provider/proxy/version.rb +1 -1
- data/pact-provider-proxy.gemspec +5 -2
- data/script/update-rack-reverse-proxy.sh +6 -0
- data/spec/support/pact-with-no-provider-states.json +4 -1
- data/vendor/rack-reverse-proxy/.document +5 -0
- data/vendor/rack-reverse-proxy/.gitignore +21 -0
- data/vendor/rack-reverse-proxy/.rspec +1 -0
- data/vendor/rack-reverse-proxy/Gemfile +2 -0
- data/vendor/rack-reverse-proxy/Guardfile +8 -0
- data/vendor/rack-reverse-proxy/LICENSE +20 -0
- data/vendor/rack-reverse-proxy/README.md +64 -0
- data/vendor/rack-reverse-proxy/Rakefile +10 -0
- data/vendor/rack-reverse-proxy/VERSION +1 -0
- data/vendor/rack-reverse-proxy/lib/rack/exception.rb +31 -0
- data/vendor/rack-reverse-proxy/lib/rack/reverse_proxy.rb +133 -0
- data/vendor/rack-reverse-proxy/lib/rack/reverse_proxy_matcher.rb +53 -0
- data/vendor/rack-reverse-proxy/rack-reverse-proxy.gemspec +21 -0
- data/vendor/rack-reverse-proxy/spec/rack/reverse_proxy_spec.rb +365 -0
- data/vendor/rack-reverse-proxy/spec/spec_helper.rb +29 -0
- data/vendor/rack-reverse-proxy/spec/support/http_streaming_response_patch.rb +32 -0
- metadata +63 -32
- data/spec/support/pact_helper.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Y2Y4Mjk3NGJjNDA0YTRhNGI3ZjgwODYxYTExOTcyMGE0Y2ZhYjYyNQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Y2E4OGQ2YzhkOTZlMjBkOTg1YThiNWUzOTU2ZmFiMzc2NjU4ZTg2MA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZWJiOWYxYjNiZmQxNmRlMTNiMmU2ZGIyZTEyZjczZGUyNWFhNDI1ZWM5Mjcw
|
10
|
+
MzMyYjlhMGQ0ZDJiOTM3MDI3MzU2NjI1MzNlNTUxMzk5ZTFjMzRhZmEwMjgy
|
11
|
+
MDg3ODRjNmRhYTdmMWJlMmU2MTMwNmIxYzAzNmY2NWMxNTZjNWQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzI3N2M4Y2ZiODI4ODQ2OTExZWRlZjU5M2Q5YzI1ZWE4MmM0OGM2ZDU1OTJj
|
14
|
+
NzdlYmRkNTU2NmZiMDQ1MTZlNjViNDBhMDFkNWI3NjJkMGQ4NjJmZjBlZDNl
|
15
|
+
ZGUyNGU4YjA2YjAwOWFjZjhjYzhlMjAzZjk2MGU3NTNmZjJjOGM=
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
git log --pretty=format:' * %h - %s (%an, %ad)'
|
2
2
|
|
3
|
+
### 1.2.0 (14 October 2014)
|
4
|
+
|
5
|
+
* 6a6695c - Forked and vendored rack-reverse-proxy because no one is maintaining or releasing the gem (bethesque, Tue Oct 14 11:41:37 2014 +1100)
|
6
|
+
|
3
7
|
### 1.1.0 (18 September 2014)
|
4
8
|
|
5
9
|
* dd1117e - Updated pact version (bethesque, Thu Sep 18 16:16:12 2014 +1000)
|
data/pact-provider-proxy.gemspec
CHANGED
@@ -17,11 +17,14 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.files = `git ls-files`.split($/)
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
-
spec.require_paths = ["lib"]
|
20
|
+
spec.require_paths = ["lib", "vendor/rack-reverse-proxy/lib"]
|
21
21
|
|
22
|
-
spec.add_dependency "rack-reverse-proxy"
|
23
22
|
spec.add_dependency "pact", ">=1.1.1", "~>1.0"
|
24
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
25
24
|
spec.add_development_dependency "rake"
|
26
25
|
spec.add_development_dependency "pry"
|
26
|
+
|
27
|
+
# For rack-reverse-proxy
|
28
|
+
spec.add_dependency "rack", ">= 1.0.0"
|
29
|
+
spec.add_dependency "rack-proxy", "~> 0.5"
|
27
30
|
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
set -e
|
3
|
+
|
4
|
+
echo "Updating rack-reverse-proxy from master at 'git@github.com:bethesque/rack-reverse-proxy.git'..."
|
5
|
+
git subtree pull --prefix vendor/rack-reverse-proxy git@github.com:bethesque/rack-reverse-proxy.git master --squash
|
6
|
+
echo "\033[32mDone!\033[0m"
|
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Jon Swope
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# A Reverse Proxy for Rack
|
2
|
+
[![TravisCI](https://secure.travis-ci.org/pex/rack-reverse-proxy.png "Build Status")](http://travis-ci.org/pex/rack-reverse-proxy "Build Status")
|
3
|
+
|
4
|
+
This is a simple reverse proxy for Rack that pretty heavily rips off Rack Forwarder. It is not meant for production systems (although it may work), as the webserver fronting your app is generally much better at this sort of thing.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
The gem is available on gemcutter. Assuming you have a recent version of Rubygems you should just be able to install it via:
|
8
|
+
|
9
|
+
```
|
10
|
+
gem install rack-reverse-proxy
|
11
|
+
```
|
12
|
+
|
13
|
+
For your Gemfile use:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem "rack-reverse-proxy", require: "rack/reverse_proxy"
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
Matchers can be a regex or a string. If a regex is used, you can use the subcaptures in your forwarding url by denoting them with a `$`.
|
21
|
+
|
22
|
+
Right now if more than one matcher matches any given route, it throws an exception for an ambiguous match. This will probably change later. If no match is found, the call is forwarded to your application.
|
23
|
+
|
24
|
+
Below is an example for configuring the middleware:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
require 'rack/reverse_proxy'
|
28
|
+
|
29
|
+
use Rack::ReverseProxy do
|
30
|
+
# Set :preserve_host to true globally (default is true already)
|
31
|
+
reverse_proxy_options preserve_host: true
|
32
|
+
|
33
|
+
# Forward the path /test* to http://example.com/test*
|
34
|
+
reverse_proxy '/test', 'http://example.com/'
|
35
|
+
|
36
|
+
# Forward the path /foo/* to http://example.com/bar/*
|
37
|
+
reverse_proxy /^\/foo(\/.*)$/, 'http://example.com/bar$1', username: 'name', password: 'basic_auth_secret'
|
38
|
+
end
|
39
|
+
|
40
|
+
app = proc do |env|
|
41
|
+
[ 200, {'Content-Type' => 'text/plain'}, "b" ]
|
42
|
+
end
|
43
|
+
run app
|
44
|
+
```
|
45
|
+
|
46
|
+
reverse_proxy_options sets global options for all reverse proxies. Available options are:
|
47
|
+
* `:preserve_host` Set to false to omit Host headers
|
48
|
+
* `:username` username for basic auth
|
49
|
+
* `:password` password for basic auth
|
50
|
+
* `:matching` is a global only option, if set to :first the first matched url will be requested (no ambigous error). Default: :all.
|
51
|
+
* `:timeout` seconds to timout the requests
|
52
|
+
|
53
|
+
## Note on Patches/Pull Requests
|
54
|
+
* Fork the project.
|
55
|
+
* Make your feature addition or bug fix.
|
56
|
+
* Add tests for it. This is important so I don't break it in a
|
57
|
+
future version unintentionally.
|
58
|
+
* Commit, do not mess with rakefile, version, or history.
|
59
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
60
|
+
* Send me a pull request. Bonus points for topic branches.
|
61
|
+
|
62
|
+
## Copyright
|
63
|
+
|
64
|
+
Copyright (c) 2010 Jon Swope. See LICENSE for details.
|
@@ -0,0 +1 @@
|
|
1
|
+
0.8.1
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rack
|
2
|
+
class GenericProxyURI < Exception
|
3
|
+
attr_reader :url
|
4
|
+
|
5
|
+
def intialize(url)
|
6
|
+
@url = url
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
%Q(Your URL "#{@url}" is too generic. Did you mean "http://#{@url}"?)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class AmbiguousProxyMatch < Exception
|
15
|
+
attr_reader :path, :matches
|
16
|
+
def initialize(path, matches)
|
17
|
+
@path = path
|
18
|
+
@matches = matches
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
%Q(Path "#{path}" matched multiple endpoints: #{formatted_matches})
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def formatted_matches
|
28
|
+
matches.map {|matcher| matcher.to_s}.join(', ')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require "rack-proxy"
|
4
|
+
require "rack/reverse_proxy_matcher"
|
5
|
+
require "rack/exception"
|
6
|
+
|
7
|
+
module Rack
|
8
|
+
class ReverseProxy
|
9
|
+
include NewRelic::Agent::Instrumentation::ControllerInstrumentation if defined? NewRelic
|
10
|
+
|
11
|
+
def initialize(app = nil, &b)
|
12
|
+
@app = app || lambda {|env| [404, [], []] }
|
13
|
+
@matchers = []
|
14
|
+
@global_options = {:preserve_host => true, :x_forwarded_host => true, :matching => :all, :replace_response_host => false}
|
15
|
+
instance_eval &b if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env)
|
19
|
+
rackreq = Rack::Request.new(env)
|
20
|
+
matcher = get_matcher(rackreq.fullpath, extract_http_request_headers(rackreq.env), rackreq)
|
21
|
+
return @app.call(env) if matcher.nil?
|
22
|
+
|
23
|
+
if @global_options[:newrelic_instrumentation]
|
24
|
+
action_name = "#{rackreq.path.gsub(/\/\d+/,'/:id').gsub(/^\//,'')}/#{rackreq.request_method}" # Rack::ReverseProxy/foo/bar#GET
|
25
|
+
perform_action_with_newrelic_trace(:name => action_name, :request => rackreq) do
|
26
|
+
proxy(env, rackreq, matcher)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
proxy(env, rackreq, matcher)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def proxy(env, source_request, matcher)
|
36
|
+
uri = matcher.get_uri(source_request.fullpath,env)
|
37
|
+
if uri.nil?
|
38
|
+
return @app.call(env)
|
39
|
+
end
|
40
|
+
options = @global_options.dup.merge(matcher.options)
|
41
|
+
|
42
|
+
# Initialize request
|
43
|
+
target_request = Net::HTTP.const_get(source_request.request_method.capitalize).new(uri.request_uri)
|
44
|
+
|
45
|
+
# Setup headers
|
46
|
+
target_request_headers = extract_http_request_headers(source_request.env)
|
47
|
+
|
48
|
+
if options[:preserve_host]
|
49
|
+
target_request_headers['HOST'] = "#{uri.host}:#{uri.port}"
|
50
|
+
end
|
51
|
+
|
52
|
+
if options[:x_forwarded_host]
|
53
|
+
target_request_headers['X-Forwarded-Host'] = source_request.host
|
54
|
+
target_request_headers['X-Forwarded-Port'] = "#{source_request.port}"
|
55
|
+
end
|
56
|
+
|
57
|
+
target_request.initialize_http_header(target_request_headers)
|
58
|
+
|
59
|
+
# Basic auth
|
60
|
+
target_request.basic_auth options[:username], options[:password] if options[:username] and options[:password]
|
61
|
+
|
62
|
+
# Setup body
|
63
|
+
if target_request.request_body_permitted? && source_request.body
|
64
|
+
source_request.body.rewind
|
65
|
+
target_request.body_stream = source_request.body
|
66
|
+
end
|
67
|
+
|
68
|
+
target_request.content_length = source_request.content_length || 0
|
69
|
+
target_request.content_type = source_request.content_type if source_request.content_type
|
70
|
+
|
71
|
+
# Create a streaming response (the actual network communication is deferred, a.k.a. streamed)
|
72
|
+
target_response = HttpStreamingResponse.new(target_request, uri.host, uri.port)
|
73
|
+
|
74
|
+
target_response.use_ssl = "https" == uri.scheme
|
75
|
+
|
76
|
+
# Let rack set the transfer-encoding header
|
77
|
+
response_headers = target_response.headers
|
78
|
+
response_headers.delete('transfer-encoding')
|
79
|
+
|
80
|
+
# Replace the location header with the proxy domain
|
81
|
+
if response_headers['location'] && options[:replace_response_host]
|
82
|
+
response_location = URI(response_headers['location'][0])
|
83
|
+
response_location.host = source_request.host
|
84
|
+
response_headers['location'] = response_location.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
[target_response.status, response_headers, target_response.body]
|
88
|
+
end
|
89
|
+
|
90
|
+
def extract_http_request_headers(env)
|
91
|
+
headers = env.reject do |k, v|
|
92
|
+
!(/^HTTP_[A-Z_]+$/ === k) || v.nil?
|
93
|
+
end.map do |k, v|
|
94
|
+
[reconstruct_header_name(k), v]
|
95
|
+
end.inject(Utils::HeaderHash.new) do |hash, k_v|
|
96
|
+
k, v = k_v
|
97
|
+
hash[k] = v
|
98
|
+
hash
|
99
|
+
end
|
100
|
+
|
101
|
+
x_forwarded_for = (headers["X-Forwarded-For"].to_s.split(/, +/) << env["REMOTE_ADDR"]).join(", ")
|
102
|
+
|
103
|
+
headers.merge!("X-Forwarded-For" => x_forwarded_for)
|
104
|
+
end
|
105
|
+
|
106
|
+
def reconstruct_header_name(name)
|
107
|
+
name.sub(/^HTTP_/, "").split("_").collect(&:capitalize).join("-")
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_matcher(path, headers, rackreq)
|
111
|
+
matches = @matchers.select do |matcher|
|
112
|
+
matcher.match?(path, headers, rackreq)
|
113
|
+
end
|
114
|
+
|
115
|
+
if matches.length < 1
|
116
|
+
nil
|
117
|
+
elsif matches.length > 1 && @global_options[:matching] != :first
|
118
|
+
raise AmbiguousProxyMatch.new(path, matches)
|
119
|
+
else
|
120
|
+
matches.first
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def reverse_proxy_options(options)
|
125
|
+
@global_options=options
|
126
|
+
end
|
127
|
+
|
128
|
+
def reverse_proxy(matcher, url=nil, opts={})
|
129
|
+
raise GenericProxyURI.new(url) if matcher.is_a?(String) && url.is_a?(String) && URI(url).class == URI::Generic
|
130
|
+
@matchers << ReverseProxyMatcher.new(matcher,url,opts)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Rack
|
2
|
+
class ReverseProxyMatcher
|
3
|
+
def initialize(matcher,url=nil,options)
|
4
|
+
@default_url=url
|
5
|
+
@url=url
|
6
|
+
@options=options
|
7
|
+
|
8
|
+
if matcher.kind_of?(String)
|
9
|
+
@matcher = /^#{matcher.to_s}/
|
10
|
+
elsif matcher.respond_to?(:match)
|
11
|
+
@matcher = matcher
|
12
|
+
else
|
13
|
+
raise "Invalid Matcher for reverse_proxy"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :matcher,:url, :default_url,:options
|
18
|
+
|
19
|
+
def match?(path, *args)
|
20
|
+
match_path(path, *args) ? true : false
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_uri(path,env)
|
24
|
+
return nil if url.nil?
|
25
|
+
_url=(url.respond_to?(:call) ? url.call(env) : url.clone)
|
26
|
+
if _url =~/\$\d/
|
27
|
+
match_path(path).to_a.each_with_index { |m, i| _url.gsub!("$#{i.to_s}", m) }
|
28
|
+
URI(_url)
|
29
|
+
else
|
30
|
+
default_url.nil? ? URI.parse(_url) : URI.join(_url, path)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
%Q("#{matcher.to_s}" => "#{url}")
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def match_path(path, *args)
|
40
|
+
headers = args[0]
|
41
|
+
rackreq = args[1]
|
42
|
+
arity = matcher.method(:match).arity
|
43
|
+
if arity == -1
|
44
|
+
match = matcher.match(path)
|
45
|
+
else
|
46
|
+
params = [path, (@options[:accept_headers] ? headers : nil), rackreq]
|
47
|
+
match = matcher.match(*params[0..(arity - 1)])
|
48
|
+
end
|
49
|
+
@url = match.url(path) if match && default_url.nil?
|
50
|
+
match
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'rack-reverse-proxy'
|
3
|
+
s.version = "0.8.1"
|
4
|
+
s.authors = ["Jon Swope", "Ian Ehlert", "Roman Ernst"]
|
5
|
+
s.description = 'A Rack based reverse proxy for basic needs. Useful for testing or in cases where webserver configuration is unavailable.'
|
6
|
+
s.email = ["jaswope@gmail.com", "ehlertij@gmail.com", "rernst@farbenmeer.net"]
|
7
|
+
s.files = Dir['README.md', 'LICENSE', 'lib/**/*']
|
8
|
+
s.homepage = 'http://github.com/pex/rack-reverse-proxy'
|
9
|
+
s.require_paths = ["lib"]
|
10
|
+
s.summary = 'A Simple Reverse Proxy for Rack'
|
11
|
+
|
12
|
+
s.add_development_dependency "rspec", "~> 3.1"
|
13
|
+
s.add_development_dependency "rake", "~> 10.3"
|
14
|
+
s.add_development_dependency "rack-test", "~> 0.6"
|
15
|
+
s.add_development_dependency "webmock", "~> 1.18"
|
16
|
+
s.add_development_dependency "guard-rspec"
|
17
|
+
s.add_development_dependency "guard-bundler"
|
18
|
+
|
19
|
+
s.add_dependency "rack", ">= 1.0.0"
|
20
|
+
s.add_dependency "rack-proxy", "~> 0.5"
|
21
|
+
end
|
@@ -0,0 +1,365 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Rack::ReverseProxy do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
Rack::ReverseProxy.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def dummy_app
|
11
|
+
lambda { |env| [200, {}, ['Dummy App']] }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "as middleware" do
|
15
|
+
def app
|
16
|
+
Rack::ReverseProxy.new(dummy_app) do
|
17
|
+
reverse_proxy '/test', 'http://example.com/', {:preserve_host => true}
|
18
|
+
reverse_proxy '/2test', lambda{ |env| 'http://example.com/'}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should forward requests to the calling app when the path is not matched" do
|
23
|
+
get '/'
|
24
|
+
last_response.body.should == "Dummy App"
|
25
|
+
last_response.should be_ok
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should proxy requests when a pattern is matched" do
|
29
|
+
stub_request(:get, 'http://example.com/test').to_return({:body => "Proxied App"})
|
30
|
+
get '/test'
|
31
|
+
last_response.body.should == "Proxied App"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should proxy requests to a lambda url when a pattern is matched" do
|
35
|
+
stub_request(:get, 'http://example.com/2test').to_return({:body => "Proxied App2"})
|
36
|
+
get '/2test'
|
37
|
+
last_response.body.should == "Proxied App2"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should set the Host header" do
|
41
|
+
stub_request(:any, 'example.com/test/stuff')
|
42
|
+
get '/test/stuff'
|
43
|
+
a_request(:get, 'http://example.com/test/stuff').with(:headers => {"Host" => "example.com:80"}).should have_been_made
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should set the X-Forwarded-Host header to the proxying host by default" do
|
47
|
+
stub_request(:any, 'example.com/test/stuff')
|
48
|
+
get '/test/stuff'
|
49
|
+
a_request(:get, 'http://example.com/test/stuff').with(:headers => {'X-Forwarded-Host' => 'example.org'}).should have_been_made
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should convert the RACK HTTP headers to standard HTTP headers" do
|
53
|
+
stub_request(:any, 'example.com/test/stuff')
|
54
|
+
get '/test/stuff', nil, {'HTTP_X_CUSTOM_HEADER' => 'foo'}
|
55
|
+
a_request(:get, 'http://example.com/test/stuff').with(:headers => {'X-Custom-Header' => 'foo'}).should have_been_made
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should maintain the Content-Type header" do
|
59
|
+
stub_request(:any, 'example.com/test/stuff')
|
60
|
+
get '/test/stuff', nil, {'CONTENT_TYPE' => 'foo'}
|
61
|
+
a_request(:get, 'http://example.com/test/stuff').with(:headers => {'Content-Type' => 'foo'}).should have_been_made
|
62
|
+
end
|
63
|
+
|
64
|
+
it "supports PATCH requests" do
|
65
|
+
stub_request(:any, 'example.com/test/stuff')
|
66
|
+
patch '/test/stuff'
|
67
|
+
a_request(:patch, 'http://example.com/test/stuff').should have_been_made
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "with preserve host turned off" do
|
71
|
+
def app
|
72
|
+
Rack::ReverseProxy.new(dummy_app) do
|
73
|
+
reverse_proxy '/test', 'http://example.com/', {:preserve_host => false}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not set the Host header" do
|
78
|
+
stub_request(:any, 'example.com/test/stuff')
|
79
|
+
get '/test/stuff'
|
80
|
+
a_request(:get, 'http://example.com/test/stuff').with(:headers => {"Host" => "example.com"}).should_not have_been_made
|
81
|
+
a_request(:get, 'http://example.com/test/stuff').should have_been_made
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "with x_forwarded_host turned off" do
|
86
|
+
def app
|
87
|
+
Rack::ReverseProxy.new(dummy_app) do
|
88
|
+
reverse_proxy_options :x_forwarded_host => false
|
89
|
+
reverse_proxy '/test', 'http://example.com/'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should not set the X-Forwarded-Host header to the proxying host" do
|
94
|
+
stub_request(:any, 'example.com/test/stuff')
|
95
|
+
get '/test/stuff'
|
96
|
+
a_request(:get, 'http://example.com/test/stuff').with(:headers => {'X-Forwarded-Host' => 'example.org'}).should_not have_been_made
|
97
|
+
a_request(:get, 'http://example.com/test/stuff').should have_been_made
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "with basic auth turned on" do
|
102
|
+
def app
|
103
|
+
Rack::ReverseProxy.new(dummy_app) do
|
104
|
+
reverse_proxy '/test', 'http://example.com/', {:username => "joe", :password => "shmoe"}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should make request with basic auth" do
|
109
|
+
stub_request(:get, "http://joe:shmoe@example.com/test/stuff").to_return(:body => "secured content")
|
110
|
+
get '/test/stuff'
|
111
|
+
last_response.body.should == "secured content"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "with preserve response host turned on" do
|
116
|
+
def app
|
117
|
+
Rack::ReverseProxy.new(dummy_app) do
|
118
|
+
reverse_proxy '/test', 'http://example.com/', {:replace_response_host => true}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should replace the location response header" do
|
123
|
+
stub_request(:get, "http://example.com/test/stuff").to_return(:headers => {"location" => "http://test.com/bar"})
|
124
|
+
get 'http://example.com/test/stuff'
|
125
|
+
# puts last_response.headers.inspect
|
126
|
+
last_response.headers['location'].should == "http://example.com/bar"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "with ambiguous routes and all matching" do
|
131
|
+
def app
|
132
|
+
Rack::ReverseProxy.new(dummy_app) do
|
133
|
+
reverse_proxy_options :matching => :all
|
134
|
+
reverse_proxy '/test', 'http://example.com/'
|
135
|
+
reverse_proxy /^\/test/, 'http://example.com/'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should throw an exception" do
|
140
|
+
lambda { get '/test' }.should raise_error(Rack::AmbiguousProxyMatch)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "with ambiguous routes and first matching" do
|
145
|
+
def app
|
146
|
+
Rack::ReverseProxy.new(dummy_app) do
|
147
|
+
reverse_proxy_options :matching => :first
|
148
|
+
reverse_proxy '/test', 'http://example1.com/'
|
149
|
+
reverse_proxy /^\/test/, 'http://example2.com/'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should throw an exception" do
|
154
|
+
stub_request(:get, 'http://example1.com/test').to_return({:body => "Proxied App"})
|
155
|
+
get '/test'
|
156
|
+
last_response.body.should == "Proxied App"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "with a route as a regular expression" do
|
161
|
+
def app
|
162
|
+
Rack::ReverseProxy.new(dummy_app) do
|
163
|
+
reverse_proxy %r|^/test(/.*)$|, 'http://example.com$1'
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should support subcaptures" do
|
168
|
+
stub_request(:get, 'http://example.com/path').to_return({:body => "Proxied App"})
|
169
|
+
get '/test/path'
|
170
|
+
last_response.body.should == "Proxied App"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "with a https route" do
|
175
|
+
def app
|
176
|
+
Rack::ReverseProxy.new(dummy_app) do
|
177
|
+
reverse_proxy '/test', 'https://example.com'
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should make a secure request" do
|
182
|
+
stub_request(:get, 'https://example.com/test/stuff').to_return({:body => "Proxied Secure App"})
|
183
|
+
get '/test/stuff'
|
184
|
+
last_response.body.should == "Proxied Secure App"
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "with a route as a string" do
|
190
|
+
def app
|
191
|
+
Rack::ReverseProxy.new(dummy_app) do
|
192
|
+
reverse_proxy '/test', 'http://example.com'
|
193
|
+
reverse_proxy '/path', 'http://example.com/foo$0'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should append the full path to the uri" do
|
198
|
+
stub_request(:get, 'http://example.com/test/stuff').to_return({:body => "Proxied App"})
|
199
|
+
get '/test/stuff'
|
200
|
+
last_response.body.should == "Proxied App"
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "with a generic url" do
|
206
|
+
def app
|
207
|
+
Rack::ReverseProxy.new(dummy_app) do
|
208
|
+
reverse_proxy '/test', 'example.com'
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should throw an exception" do
|
213
|
+
lambda{ app }.should raise_error(Rack::GenericProxyURI)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
describe "with a matching route" do
|
218
|
+
def app
|
219
|
+
Rack::ReverseProxy.new(dummy_app) do
|
220
|
+
reverse_proxy '/test', 'http://example.com/'
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
%w|get head delete put post|.each do |method|
|
225
|
+
describe "and using method #{method}" do
|
226
|
+
it "should forward the correct request" do
|
227
|
+
stub_request(method.to_sym, 'http://example.com/test').to_return({:body => "Proxied App for #{method}"})
|
228
|
+
eval "#{method} '/test'"
|
229
|
+
last_response.body.should == "Proxied App for #{method}"
|
230
|
+
end
|
231
|
+
|
232
|
+
if %w|put post|.include?(method)
|
233
|
+
it "should forward the request payload" do
|
234
|
+
stub_request(method.to_sym, 'http://example.com/test').to_return { |req| {:body => req.body} }
|
235
|
+
eval "#{method} '/test', {:test => 'test'}"
|
236
|
+
last_response.body.should == "test=test"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe "with a matching class" do
|
244
|
+
class Matcher
|
245
|
+
def self.match(path)
|
246
|
+
if path.match(/^\/(test|users)/)
|
247
|
+
Matcher.new
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def url(path)
|
252
|
+
if path.include?("user")
|
253
|
+
'http://users-example.com' + path
|
254
|
+
else
|
255
|
+
'http://example.com' + path
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def app
|
261
|
+
Rack::ReverseProxy.new(dummy_app) do
|
262
|
+
reverse_proxy Matcher
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should forward requests to the calling app when the path is not matched" do
|
267
|
+
get '/'
|
268
|
+
last_response.body.should == "Dummy App"
|
269
|
+
last_response.should be_ok
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should proxy requests when a pattern is matched" do
|
273
|
+
stub_request(:get, 'http://example.com/test').to_return({:body => "Proxied App"})
|
274
|
+
stub_request(:get, 'http://users-example.com/users').to_return({:body => "User App"})
|
275
|
+
get '/test'
|
276
|
+
last_response.body.should == "Proxied App"
|
277
|
+
get '/users'
|
278
|
+
last_response.body.should == "User App"
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "with a matching class" do
|
283
|
+
class RequestMatcher
|
284
|
+
attr_accessor :rackreq
|
285
|
+
|
286
|
+
def initialize(rackreq)
|
287
|
+
self.rackreq = rackreq
|
288
|
+
end
|
289
|
+
|
290
|
+
def self.match(path, headers, rackreq)
|
291
|
+
if path.match(/^\/(test|users)/)
|
292
|
+
RequestMatcher.new(rackreq)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def url(path)
|
297
|
+
if rackreq.params["user"] == 'omer'
|
298
|
+
'http://users-example.com' + path
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def app
|
304
|
+
Rack::ReverseProxy.new(dummy_app) do
|
305
|
+
reverse_proxy RequestMatcher
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should forward requests to the calling app when the path is not matched" do
|
310
|
+
get '/'
|
311
|
+
last_response.body.should == "Dummy App"
|
312
|
+
last_response.should be_ok
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should proxy requests when a pattern is matched" do
|
316
|
+
stub_request(:get, 'http://users-example.com/users?user=omer').to_return({:body => "User App"})
|
317
|
+
get '/test', user: "mark"
|
318
|
+
last_response.body.should == "Dummy App"
|
319
|
+
get '/users', user: 'omer'
|
320
|
+
last_response.body.should == "User App"
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
describe "with a matching class that accepts headers" do
|
326
|
+
class MatcherHeaders
|
327
|
+
def self.match(path, headers)
|
328
|
+
if path.match(/^\/test/) && headers['ACCEPT'] && headers['ACCEPT'] == 'foo.bar'
|
329
|
+
MatcherHeaders.new
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def url(path)
|
334
|
+
'http://example.com' + path
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def app
|
339
|
+
Rack::ReverseProxy.new(dummy_app) do
|
340
|
+
reverse_proxy MatcherHeaders, nil, {:accept_headers => true}
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should proxy requests when a pattern is matched and correct headers are passed" do
|
345
|
+
stub_request(:get, 'http://example.com/test').to_return({:body => "Proxied App with Headers"})
|
346
|
+
get '/test', {}, {'HTTP_ACCEPT' => 'foo.bar'}
|
347
|
+
last_response.body.should == "Proxied App with Headers"
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should not proxy requests when a pattern is matched and incorrect headers are passed" do
|
351
|
+
stub_request(:get, 'http://example.com/test').to_return({:body => "Proxied App with Headers"})
|
352
|
+
get '/test', {}, {'HTTP_ACCEPT' => 'bar.foo'}
|
353
|
+
last_response.body.should_not == "Proxied App with Headers"
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
describe "as a rack app" do
|
359
|
+
it "should respond with 404 when the path is not matched" do
|
360
|
+
get '/'
|
361
|
+
last_response.should be_not_found
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rack/reverse_proxy'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'webmock/rspec'
|
6
|
+
# Patch HttpStreamingResponse to make rack-proxy compatible with webmocks
|
7
|
+
require 'support/http_streaming_response_patch'
|
8
|
+
|
9
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
10
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__))
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.expect_with :rspec do |expectations|
|
14
|
+
# This option will default to `true` in RSpec 4.
|
15
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
16
|
+
expectations.syntax = [:should]
|
17
|
+
end
|
18
|
+
config.mock_with :rspec do |mocks|
|
19
|
+
mocks.verify_doubled_constant_names = true
|
20
|
+
mocks.verify_partial_doubles = true
|
21
|
+
mocks.syntax = [:should]
|
22
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
23
|
+
# a real object. This is generally recommended, and will default to
|
24
|
+
# `true` in RSpec 4.
|
25
|
+
mocks.verify_partial_doubles = true
|
26
|
+
end
|
27
|
+
|
28
|
+
WebMock.disable_net_connect!
|
29
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
##
|
2
|
+
# Patch HttpStreamingResponse
|
3
|
+
# in order to support webmocks and still use rack-proxy
|
4
|
+
#
|
5
|
+
# Inspired by @ehlertij commits on sportngin/rack-proxy:
|
6
|
+
# 616574e452fa731f5427d2ff2aff6823fcf28bde
|
7
|
+
# d8c377f7485997b229ced23c33cfef87d3fb8693
|
8
|
+
# 75b446a26ceb519ddc28f38b33309e9a2799074c
|
9
|
+
#
|
10
|
+
module Rack
|
11
|
+
class HttpStreamingResponse
|
12
|
+
def each(&block)
|
13
|
+
response.read_body(&block)
|
14
|
+
ensure
|
15
|
+
session.end_request_hacked unless mocking?
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def response
|
21
|
+
if mocking?
|
22
|
+
@response ||= session.request(@request)
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def mocking?
|
29
|
+
defined?(WebMock) || defined?(FakeWeb)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,91 +1,105 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact-provider-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Beth
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rack-reverse-proxy
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: pact
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
|
-
- -
|
17
|
+
- - ! '>='
|
32
18
|
- !ruby/object:Gem::Version
|
33
19
|
version: 1.1.1
|
34
|
-
- -
|
20
|
+
- - ~>
|
35
21
|
- !ruby/object:Gem::Version
|
36
22
|
version: '1.0'
|
37
23
|
type: :runtime
|
38
24
|
prerelease: false
|
39
25
|
version_requirements: !ruby/object:Gem::Requirement
|
40
26
|
requirements:
|
41
|
-
- -
|
27
|
+
- - ! '>='
|
42
28
|
- !ruby/object:Gem::Version
|
43
29
|
version: 1.1.1
|
44
|
-
- -
|
30
|
+
- - ~>
|
45
31
|
- !ruby/object:Gem::Version
|
46
32
|
version: '1.0'
|
47
33
|
- !ruby/object:Gem::Dependency
|
48
34
|
name: bundler
|
49
35
|
requirement: !ruby/object:Gem::Requirement
|
50
36
|
requirements:
|
51
|
-
- -
|
37
|
+
- - ~>
|
52
38
|
- !ruby/object:Gem::Version
|
53
39
|
version: '1.3'
|
54
40
|
type: :development
|
55
41
|
prerelease: false
|
56
42
|
version_requirements: !ruby/object:Gem::Requirement
|
57
43
|
requirements:
|
58
|
-
- -
|
44
|
+
- - ~>
|
59
45
|
- !ruby/object:Gem::Version
|
60
46
|
version: '1.3'
|
61
47
|
- !ruby/object:Gem::Dependency
|
62
48
|
name: rake
|
63
49
|
requirement: !ruby/object:Gem::Requirement
|
64
50
|
requirements:
|
65
|
-
- -
|
51
|
+
- - ! '>='
|
66
52
|
- !ruby/object:Gem::Version
|
67
53
|
version: '0'
|
68
54
|
type: :development
|
69
55
|
prerelease: false
|
70
56
|
version_requirements: !ruby/object:Gem::Requirement
|
71
57
|
requirements:
|
72
|
-
- -
|
58
|
+
- - ! '>='
|
73
59
|
- !ruby/object:Gem::Version
|
74
60
|
version: '0'
|
75
61
|
- !ruby/object:Gem::Dependency
|
76
62
|
name: pry
|
77
63
|
requirement: !ruby/object:Gem::Requirement
|
78
64
|
requirements:
|
79
|
-
- -
|
65
|
+
- - ! '>='
|
80
66
|
- !ruby/object:Gem::Version
|
81
67
|
version: '0'
|
82
68
|
type: :development
|
83
69
|
prerelease: false
|
84
70
|
version_requirements: !ruby/object:Gem::Requirement
|
85
71
|
requirements:
|
86
|
-
- -
|
72
|
+
- - ! '>='
|
87
73
|
- !ruby/object:Gem::Version
|
88
74
|
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rack
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.0.0
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.0.0
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rack-proxy
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ~>
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0.5'
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0.5'
|
89
103
|
description: See summary
|
90
104
|
email:
|
91
105
|
- beth@bethesque.com
|
@@ -93,7 +107,7 @@ executables: []
|
|
93
107
|
extensions: []
|
94
108
|
extra_rdoc_files: []
|
95
109
|
files:
|
96
|
-
-
|
110
|
+
- .gitignore
|
97
111
|
- CHANGELOG.md
|
98
112
|
- Gemfile
|
99
113
|
- LICENSE.txt
|
@@ -106,12 +120,29 @@ files:
|
|
106
120
|
- lib/pact/provider/proxy/tasks/proxy_verification_task.rb
|
107
121
|
- lib/pact/provider/proxy/version.rb
|
108
122
|
- pact-provider-proxy.gemspec
|
123
|
+
- script/update-rack-reverse-proxy.sh
|
109
124
|
- spec/fixtures/template_pact_helper.rb
|
110
125
|
- spec/support/custom_pact_helper.rb
|
111
126
|
- spec/support/pact-with-no-provider-states.json
|
112
127
|
- spec/support/pact.json
|
113
|
-
- spec/support/pact_helper.rb
|
114
128
|
- spec/tasks.rake
|
129
|
+
- vendor/rack-reverse-proxy/.document
|
130
|
+
- vendor/rack-reverse-proxy/.gitignore
|
131
|
+
- vendor/rack-reverse-proxy/.rspec
|
132
|
+
- vendor/rack-reverse-proxy/Gemfile
|
133
|
+
- vendor/rack-reverse-proxy/Gemfile.lock
|
134
|
+
- vendor/rack-reverse-proxy/Guardfile
|
135
|
+
- vendor/rack-reverse-proxy/LICENSE
|
136
|
+
- vendor/rack-reverse-proxy/README.md
|
137
|
+
- vendor/rack-reverse-proxy/Rakefile
|
138
|
+
- vendor/rack-reverse-proxy/VERSION
|
139
|
+
- vendor/rack-reverse-proxy/lib/rack/exception.rb
|
140
|
+
- vendor/rack-reverse-proxy/lib/rack/reverse_proxy.rb
|
141
|
+
- vendor/rack-reverse-proxy/lib/rack/reverse_proxy_matcher.rb
|
142
|
+
- vendor/rack-reverse-proxy/rack-reverse-proxy.gemspec
|
143
|
+
- vendor/rack-reverse-proxy/spec/rack/reverse_proxy_spec.rb
|
144
|
+
- vendor/rack-reverse-proxy/spec/spec_helper.rb
|
145
|
+
- vendor/rack-reverse-proxy/spec/support/http_streaming_response_patch.rb
|
115
146
|
homepage: https://github.com/bethesque/pact-provider-proxy
|
116
147
|
licenses:
|
117
148
|
- MIT
|
@@ -120,19 +151,20 @@ post_install_message:
|
|
120
151
|
rdoc_options: []
|
121
152
|
require_paths:
|
122
153
|
- lib
|
154
|
+
- vendor/rack-reverse-proxy/lib
|
123
155
|
required_ruby_version: !ruby/object:Gem::Requirement
|
124
156
|
requirements:
|
125
|
-
- -
|
157
|
+
- - ! '>='
|
126
158
|
- !ruby/object:Gem::Version
|
127
159
|
version: '0'
|
128
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
161
|
requirements:
|
130
|
-
- -
|
162
|
+
- - ! '>='
|
131
163
|
- !ruby/object:Gem::Version
|
132
164
|
version: '0'
|
133
165
|
requirements: []
|
134
166
|
rubyforge_project:
|
135
|
-
rubygems_version: 2.
|
167
|
+
rubygems_version: 2.1.11
|
136
168
|
signing_key:
|
137
169
|
specification_version: 4
|
138
170
|
summary: Allows verification of a pact against a running provider
|
@@ -141,5 +173,4 @@ test_files:
|
|
141
173
|
- spec/support/custom_pact_helper.rb
|
142
174
|
- spec/support/pact-with-no-provider-states.json
|
143
175
|
- spec/support/pact.json
|
144
|
-
- spec/support/pact_helper.rb
|
145
176
|
- spec/tasks.rake
|