Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test Socks proxy in supported Faraday adapters #7

Merged
merged 10 commits into from
Sep 20, 2019
13 changes: 9 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ services:
- ./server/run.sh:/app/run.sh

tests:
build: ./tests
build:
context: ./tests
args:
faraday_gem_ref: ${FARADAY_GEM_REF:-master}
faraday_http_gem_ref: ${FARADAY_HTTP_GEM_REF:-master}
socksify_gem_ref: ${FARADAY_SOCKSIFY_GEM_REF:-master}
depends_on:
- server
- proxy
Expand All @@ -45,9 +50,9 @@ services:
environment:
- HTTP_HOST=faraday-live.localhost
- PROXY_HOST=live-proxy.localhost
- FARADAY_ADAPTER=${TEST_ADAPTER:-}
- FARADAY_METHOD=${TEST_METHOD:-}
- SERVER_PROTOCOL=${TEST_PROTO:-}
- TEST_ADAPTER=${TEST_ADAPTER:-}
- TEST_METHOD=${TEST_METHOD:-}
- TEST_PROTO=${TEST_PROTO:-}
volumes:
- certca:/root/.local/share/mkcert/:ro
- certdata:/certs:ro
Expand Down
4 changes: 3 additions & 1 deletion docs/dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ This runs tests against these webservers and proxies:
1. HTTP server on port 80 (`TEST_PROTO=http`)
2. Self-signed HTTPS server on port 443 (`TEST_PROTO=unverified`)
3. Verified and valid HTTPS server on port 443 (`TEST_PROTO=https`)
4. Proxy server (`TEST_PROTO=proxy`)
4. HTTP proxy server (`TEST_PROTO=http_proxy`)
5. SOCKS proxy server (`TEST_PROTO=socks_proxy`)
6. LEGACY: Only HTTP proxy server (`TEST_PROTO=proxy`)

You can choose to run one or more explicitly:

Expand Down
7 changes: 7 additions & 0 deletions proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM golang:1.12.3
RUN go get -u github.com/elazarl/goproxy
RUN go get -u github.com/armon/go-socks5

# no auth, http
EXPOSE 8080
Expand All @@ -13,6 +14,12 @@ EXPOSE 9080
# auth:pass, https
EXPOSE 9080

# no auth, socks
EXPOSE 6000

# auth:pass, socks
EXPOSE 6001

WORKDIR /app
COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o proxy .
Expand Down
22 changes: 21 additions & 1 deletion proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"flag"
"log"
"net/http"

socks5 "github.com/armon/go-socks5"
)

var (
Expand All @@ -15,6 +17,24 @@ var (
func main() {
flag.Parse()

unauthSocks, err := socks5.New(&socks5.Config{})
if err != nil {
panic(err)
}

authSocks, err := socks5.New(&socks5.Config{
Credentials: socks5.StaticCredentials(map[string]string{
"faraday": "live",
}),
})
if err != nil {
panic(err)
}

log.Println("Starting Socks Proxy servers on :6000, :6001...")
go unauthSocks.ListenAndServe("tcp", ":6000")
go authSocks.ListenAndServe("tcp", ":6001")

servers := &ServerList{}
servers.Add(":8080", newProxy("http_proxy"))
servers.Add(":9080", newProxy("http_auth_proxy"))
Expand All @@ -39,7 +59,7 @@ func (l *ServerList) Listen() {
}

func (l *ServerList) listen(srv *http.Server) {
log.Printf("Starting Proxy server on %s...", srv.Addr)
log.Printf("Starting HTTP Proxy server on %s...", srv.Addr)
if srv.TLSConfig == nil {
srv.ListenAndServe()
return
Expand Down
16 changes: 11 additions & 5 deletions tests/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@
FROM ruby:2.6.2 as build
ENV LANG C.UTF-8
WORKDIR /app
COPY Gemfile .
COPY Gemfile.lock .

# install all non-git gems
RUN gem install bundler -v '~> 2.0.1' --no-document
RUN bundle install --without development test -j4 --retry 3

ARG faraday_gem_ref=master
ARG faraday_http_gem_ref=master
COPY Gemfile .
COPY Gemfile.lock .

RUN bundle install --without development test -j4 --retry 3

# install just the non-git gems. These will change more frequently.
RUN echo "gem 'faraday', git: 'https://github.com/lostisland/faraday'," >> Gemfile
ARG faraday_gem_ref=master
RUN echo " ref: '$faraday_gem_ref', require: 'faraday'" >> Gemfile

RUN echo "gem 'faraday-http', git: 'https://github.com/lostisland/faraday-http'," >> Gemfile
ARG faraday_http_gem_ref=master
RUN echo " ref: '$faraday_http_gem_ref', require: 'faraday/http'" >> Gemfile

RUN echo "gem 'socksify', git: 'https://github.com/astro/socksify-ruby'," >> Gemfile
ARG socksify_gem_ref=master
RUN echo " ref: '$socksify_gem_ref'" >> Gemfile

RUN bundle install \
# Remove unneeded files (cached *.gem, *.o, *.c)
&& rm -rf /usr/local/bundle/cache/*.gem \
Expand Down
21 changes: 18 additions & 3 deletions tests/spec/insecure_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,30 @@
proxy: :http_proxy,
server: :http,
}
end if ServerProtocols.proxy?
end if ServerProtocols.http_proxy?

describe "#{adapter} using Socks proxy with HTTP server" do
include_examples 'a proxied connection', adapter, {
proxy: :socks_proxy,
server: :http,
}
end if ServerProtocols.socks_proxy? && adapter.socks_proxy?

describe "#{adapter} using authenticated HTTP proxy with HTTP server" do
include_examples 'a proxied connection', adapter, {
proxy: :http_auth_proxy,
server: :http,
auth: "faraday:live",
auth: "faraday:live",
}
end if ServerProtocols.http_proxy?

describe "#{adapter} using authenticated Socks proxy with HTTP server" do
include_examples 'a proxied connection', adapter, {
proxy: :socks_auth_proxy,
server: :http,
auth: "faraday:live",
}
end if ServerProtocols.proxy?
end if ServerProtocols.socks_proxy? && adapter.socks_proxy?

describe "#{adapter} with unverified HTTPS server" do
let(:url_kind) { :https }
Expand Down
25 changes: 20 additions & 5 deletions tests/spec/secure_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,30 @@
proxy: :http_proxy,
server: :https,
}
end if ServerProtocols.proxy?
end if ServerProtocols.http_proxy?

describe "#{adapter} using HTTP proxy with HTTPS server" do
describe "#{adapter} using authenticated HTTP proxy with HTTPS server" do
include_examples 'a proxied connection', adapter, {
proxy: :http_auth_proxy,
server: :https,
auth: "faraday:live",
}
end if ServerProtocols.proxy?
end if ServerProtocols.http_proxy?

describe "#{adapter} using Socks proxy with HTTPS server" do
include_examples 'a proxied connection', adapter, {
proxy: :socks_proxy,
server: :https,
}
end if ServerProtocols.socks_proxy? && adapter.socks_proxy?

describe "#{adapter} using authenticated Socks proxy with HTTPS server" do
include_examples 'a proxied connection', adapter, {
proxy: :socks_auth_proxy,
server: :https,
auth: "faraday:live",
}
end if ServerProtocols.socks_proxy? && adapter.socks_proxy?

describe "#{adapter} using HTTPS proxy with HTTPS server" do
it "fails to connect" do
Expand All @@ -29,7 +44,7 @@
end
expect { conn.get 'wat' }.to raise_error(Faraday::ConnectionFailed)
end
end if ServerProtocols.proxy? && !adapter.https_proxy_bug?
end if ServerProtocols.http_proxy? && !adapter.https_proxy_bug?

describe "#{adapter} using authenticated HTTPS proxy with HTTPS server" do
it "fails to connect" do
Expand All @@ -40,5 +55,5 @@
end
expect { conn.get 'wat' }.to raise_error(Faraday::ConnectionFailed)
end
end if ServerProtocols.proxy? && !adapter.https_proxy_bug?
end if ServerProtocols.http_proxy? && !adapter.https_proxy_bug?
end
5 changes: 3 additions & 2 deletions tests/spec/support/adapters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def self.adapter_keys
end

def self.explicit_adapters
ENV['FARADAY_ADAPTER'].to_s.split(',').map! do |key|
ENV['TEST_ADAPTER'].to_s.split(',').map! do |key|
key.strip!
key.downcase!
key.to_sym
Expand All @@ -52,6 +52,7 @@ def to_s
:connect_with_response_body, # enables CONNECT tests WITH response body
:unverified_https_bug, # https://github.com/technoweenie/faraday-live/issues/4
:https_proxy_bug, # https://github.com/technoweenie/faraday-live/issues/6
:socks_proxy,
].each do |feature|
define_method("#{feature}?") { @features.include?(feature) }
end
Expand Down Expand Up @@ -81,7 +82,7 @@ def connect_method?
:trace_method, :connect_with_response_body),

:net_http => Adapter.new(:net_http,
:trace_method, :connect_with_response_body),
:socks_proxy, :trace_method, :connect_with_response_body),

:patron => Adapter.new(:patron,
:unverified_https_bug),
Expand Down
7 changes: 6 additions & 1 deletion tests/spec/support/examples/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@
end

# proxy does not modify https requests
expected = server_url_kind == :https ? '' : "goproxy (#{proxy_url_kind})"
expected = case proxy_url_kind
when :socks_proxy, :socks_auth_proxy
""
else
server_url_kind == :https ? "" : "goproxy (#{proxy_url_kind})"
end
include_examples 'common request tests', server_url_kind, adapter,
response_header: {
'Via' => expected,
Expand Down
2 changes: 1 addition & 1 deletion tests/spec/support/http_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def self.http_methods!
end

def self.explicit_methods
ENV['FARADAY_METHOD'].to_s.split(',').map! do |key|
ENV['TEST_METHOD'].to_s.split(',').map! do |key|
key.strip!
key.downcase!
key.to_sym
Expand Down
10 changes: 7 additions & 3 deletions tests/spec/support/protocols.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ def self.unverified_https?
protocols.include?(:unverified)
end

def self.proxy?
protocols.include?(:proxy)
def self.http_proxy?
protocols.include?(:proxy) || protocols.include?(:http_proxy)
end

def self.socks_proxy?
protocols.include?(:socks_proxy)
end

def self.test?(*protos)
Expand All @@ -34,7 +38,7 @@ def self.protocols!
end

def self.explicit_protocols
ENV['SERVER_PROTOCOL'].to_s.split(',').map! do |key|
ENV['TEST_PROTO'].to_s.split(',').map! do |key|
key.strip!
key.downcase!
key.to_sym
Expand Down
10 changes: 10 additions & 0 deletions tests/spec/support/urls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,14 @@ def self.https_auth_proxy_server(auth = nil)
auth += "@" if auth
"http://#{auth}#{ENV['PROXY_HOST']}:9443"
end

def self.socks_proxy_server(auth = nil)
auth += "@" if auth
"socks://#{auth}#{ENV['PROXY_HOST']}:6000"
end

def self.socks_auth_proxy_server(auth = nil)
auth += "@" if auth
"socks://#{auth}#{ENV['PROXY_HOST']}:6001"
end
end