pact-net icon indicating copy to clipboard operation
pact-net copied to clipboard

PactVerifier not working behind a Proxy with credentials

Open marcpaulv opened this issue 4 years ago • 3 comments
trafficstars

The PactVerifier cannot be used to communicate with the PACT broker from an environment behind a proxy that needs credentials.

Output from test run (obfuscated app names and Urls)

PactNet.PactFailureException : Pact verification failed. See output for details. 
If the output is empty please provide a custom config.Outputters (IOutput) for your test framework, as we couldn't write to the console.
   at PactNet.Core.PactCoreHost`1.Start()
   at PactNet.PactVerifier.Verify(String description, String providerState)
   at mynamespace.VerifyPactAdherence() in C:\Work\Git\mynamespace\PactTests.cs:line 67

Error reading file from https://mypactDomain/pacts/provider/myProvider/consumer/myConsumer/latest
407 "Proxy Authentication Required" C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http/response.rb:119:in `error!'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http/response.rb:128:in `value'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http.rb:915:in `connect'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http.rb:863:in `do_start'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http.rb:852:in `start'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:114:in `perform_http_request'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:85:in `get_remote'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:62:in `block in get_remote_with_retry'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:60:in `times'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:60:in `get_remote_with_retry'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:41:in `render_pact'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:22:in `read'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_source.rb:17:in `pact_json'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:122:in `collect'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:122:in `pact_jsons'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:79:in `configure_rspec'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:33:in `run'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:69:in `run_with_pact_uri_object'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:50:in `run_specs'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:21:in `call'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:13:in `call'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:171:in `verify_pact'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:43:in `block in call'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:42:in `collect'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:42:in `call'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:34:in `call'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/cli/verify.rb:47:in `verify'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/cli/custom_thor.rb:17:in `start'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1//pact-win32/lib/app/pact-provider-verifier.rb:33:in `<main>'
C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http/response.rb:119:in `error!': 407 "Proxy Authentication Required" (Net::HTTPServerException)
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http/response.rb:128:in `value'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http.rb:915:in `connect'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http.rb:863:in `do_start'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/ruby/lib/ruby/2.2.0/net/http.rb:852:in `start'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:114:in `perform_http_request'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:85:in `get_remote'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:62:in `block in get_remote_with_retry'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:60:in `times'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:60:in `get_remote_with_retry'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:41:in `render_pact'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-support-1.15.1/lib/pact/consumer_contract/pact_file.rb:22:in `read'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_source.rb:17:in `pact_json'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:122:in `collect'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:122:in `pact_jsons'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:79:in `configure_rspec'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/provider/pact_spec_runner.rb:33:in `run'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:69:in `run_with_pact_uri_object'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:50:in `run_specs'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:21:in `call'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-1.55.5/lib/pact/cli/run_pact_verification.rb:13:in `call'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:171:in `verify_pact'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:43:in `block in call'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:42:in `collect'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:42:in `call'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/app.rb:34:in `call'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/cli/verify.rb:47:in `verify'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1/pact-win32/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.32.1/lib/pact/provider_verifier/cli/custom_thor.rb:17:in `start'
	from C:/Work/Git/pathToApp/bin/Debug/netcoreapp3.1//pact-win32/lib/app/pact-provider-verifier.rb:33:in `<main>'

I tracked down the problem to the Net::Http library used in pact_file.rb#L105

If i change the line to use credentials, according to the Net::Http documentation which says to manually provide the credentials it works as expected

 def prepare_request(uri)
      http = Net::HTTP.new(uri.host, uri.port,p_addr='UrlWithoutScheme', p_port='8080', p_user='myUser',p_pass='myPassword')
   #...  

marcpaulv avatar Apr 08 '21 09:04 marcpaulv

As a workaround (might not be the best way of handling it), for anyone else interested, I modified the pact_file.rb & http_client.rb as follows:

proxy = ENV['HTTP_PROXY'];
if proxy && match = proxy.match(/http:\/\/(.*):(.*)@(.*):(.*)/)
    user, pass, addr, port = match.captures
    http = Net::HTTP.new(uri.host, uri.port,p_addr=addr, p_port=port, p_user=user,p_pass=pass)
else
    http = Net::HTTP.new(uri.host, uri.port, :ENV)
end

Using a Post-Build event, I am overriding the initial files with the ones modified as above.

marcpaulv avatar Apr 13 '21 12:04 marcpaulv

Thanks for the great work here @marcpaulv. I'm hoping there are better ways to get the proxy credentials into into that client.

For example, on linux, usually doing something like the following would be sufficient:

export http_proxy=http://USERNAME:PASSWORD@SERVER:PORT/

cc: @bethesque.

mefellows avatar Apr 13 '21 12:04 mefellows

That is the approach I used on Windows: having that http_proxy environment variable in the form you suggested. The regex is parsing that env variable to obtain the credentials.

Not sure it works on linux either, since the problem is in the Net::Http library. Isn't it used in both Linux & Windows ?

marcpaulv avatar Apr 13 '21 12:04 marcpaulv

Closed as stale since the release of PactNet 4.x

adamrodger avatar Sep 03 '22 12:09 adamrodger