diff --git a/args_parser.go b/args_parser.go index 11c7684..722eaa0 100644 --- a/args_parser.go +++ b/args_parser.go @@ -33,6 +33,7 @@ type kingpinParser struct { method string body string bodyFilePath string + proxy string stream bool certPath string keyPath string @@ -56,6 +57,7 @@ func newKingpinParser() argsParser { method: "GET", body: "", bodyFilePath: "", + proxy: "", stream: false, certPath: "", keyPath: "", @@ -151,6 +153,10 @@ func newKingpinParser() argsParser { }). Bool() + app.Flag("proxy", "Use the specified HTTP proxy"). + Default(""). + StringVar(&kparser.proxy) + app.Flag( "print", "Specifies what to output. Comma-separated list of values"+ " 'intro' (short: 'i'), 'progress' (short: 'p'),"+ @@ -222,6 +228,7 @@ func (k *kingpinParser) parse(args []string) (config, error) { method: k.method, body: k.body, bodyFilePath: k.bodyFilePath, + proxy: k.proxy, stream: k.stream, keyPath: k.keyPath, certPath: k.certPath, diff --git a/args_parser_test.go b/args_parser_test.go index 6d871d0..c22cb51 100644 --- a/args_parser_test.go +++ b/args_parser_test.go @@ -403,6 +403,35 @@ func TestArgsParsing(t *testing.T) { format: knownFormat("plain-text"), }, }, + { + [][]string{ + { + programName, + "--http2", + "--proxy", "http://proxyHost:proxyPort", + "https://somehost.somedomain", + }, + { + programName, + "--http2", + "--proxy=http://proxyHost:proxyPort", + "https://somehost.somedomain", + }, + }, + config{ + numConns: defaultNumberOfConns, + timeout: defaultTimeout, + headers: new(headersList), + method: "GET", + url: "https://somehost.somedomain:443", + clientType: nhttp2, + printIntro: true, + printProgress: true, + printResult: true, + format: knownFormat("plain-text"), + proxy: "http://proxyHost:proxyPort", + }, + }, { [][]string{ { diff --git a/bombardier.go b/bombardier.go index 5efe68e..ee3167a 100644 --- a/bombardier.go +++ b/bombardier.go @@ -136,6 +136,7 @@ func newBombardier(c config) (*bombardier, error) { headers: c.headers, url: c.url, method: c.method, + proxy: c.proxy, body: pbody, bodProd: bsp, bytesRead: &b.bytesRead, diff --git a/clients.go b/clients.go index 3de0030..7e50a69 100644 --- a/clients.go +++ b/clients.go @@ -27,8 +27,8 @@ type clientOpts struct { tlsConfig *tls.Config disableKeepAlives bool - headers *headersList - url, method string + headers *headersList + url, method, proxy string body *string bodProd bodyStreamProducer @@ -132,11 +132,19 @@ type httpClient struct { func newHTTPClient(opts *clientOpts) client { c := new(httpClient) + tr := &http.Transport{ TLSClientConfig: opts.tlsConfig, MaxIdleConnsPerHost: int(opts.maxConns), DisableKeepAlives: opts.disableKeepAlives, } + + if opts.proxy != "" { + url_i := url.URL{} + url_proxy, _ := url_i.Parse(opts.proxy) + tr.Proxy = http.ProxyURL(url_proxy) + } + tr.DialContext = httpDialContextFunc(opts.bytesRead, opts.bytesWritten) if opts.HTTP2 { _ = http2.ConfigureTransport(tr) diff --git a/config.go b/config.go index 20fbac5..f387acf 100644 --- a/config.go +++ b/config.go @@ -8,15 +8,15 @@ import ( ) type config struct { - numConns uint64 - numReqs *uint64 - disableKeepAlives bool - duration *time.Duration - url, method, certPath, keyPath string - body, bodyFilePath string - stream bool - headers *headersList - timeout time.Duration + numConns uint64 + numReqs *uint64 + disableKeepAlives bool + duration *time.Duration + url, method, certPath, keyPath, proxy string + body, bodyFilePath string + stream bool + headers *headersList + timeout time.Duration // TODO(codesenberg): printLatencies should probably be // re(named&maked) into printPercentiles or even let // users provide their own percentiles and not just