Skip to content

Commit

Permalink
Add repeat option support
Browse files Browse the repository at this point in the history
Add an option to repeat the same request multiple times, reusing the
same HTTP connection.
  • Loading branch information
rs committed Apr 27, 2018
1 parent a8a8dc0 commit 6ada476
Showing 1 changed file with 41 additions and 32 deletions.
73 changes: 41 additions & 32 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ var (
// Command line flags.
httpMethod string
postBody string
repeat int
followRedirects bool
onlyHeader bool
insecure bool
Expand All @@ -72,6 +73,7 @@ const maxRedirects = 10
func init() {
flag.StringVar(&httpMethod, "X", "GET", "HTTP method to use")
flag.StringVar(&postBody, "d", "", "the body of a POST or PUT request; from file use @filename")
flag.IntVar(&repeat, "r", 0, "Repeat the same request N times on the same connection")
flag.BoolVar(&followRedirects, "L", false, "follow 30x redirects")
flag.BoolVar(&onlyHeader, "I", false, "don't read body of request")
flag.BoolVar(&insecure, "k", false, "allow insecure SSL connections")
Expand Down Expand Up @@ -127,8 +129,11 @@ func main() {
}

url := parseURL(args[0])
tr := newTransport(url)

visit(url)
for i := repeat + 1; i > 0; i-- {
visit(tr, url)
}
}

// readClientCert - helper function to read client certificate
Expand Down Expand Up @@ -197,9 +202,42 @@ func headerKeyValue(h string) (string, string) {
return strings.TrimRight(h[:i], " "), strings.TrimLeft(h[i:], " :")
}

func newTransport(url *url.URL) *http.Transport {
tr := &http.Transport{
Proxy: http.ProxyFromEnvironment,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}

switch url.Scheme {
case "https":
host, _, err := net.SplitHostPort(url.Host)
if err != nil {
host = url.Host
}

tr.TLSClientConfig = &tls.Config{
ServerName: host,
InsecureSkipVerify: insecure,
Certificates: readClientCert(clientCertFile),
}

// Because we create a custom TLSClientConfig, we have to opt-in to HTTP/2.
// See https://github.com/golang/go/issues/14275
err = http2.ConfigureTransport(tr)
if err != nil {
log.Fatalf("failed to prepare transport for HTTP/2: %v", err)
}
}

return tr
}

// visit visits a url and times the interaction.
// If the response is a 30x, visit follows the redirect.
func visit(url *url.URL) {
func visit(tr *http.Transport, url *url.URL) {
req := newRequest(httpMethod, url, postBody)

var tStart, tDNSStart, tDNSEnd, tConnectStart, tConnectEnd, tTLSStart, tTLSEnd, tConnected, tTTBF, tDone time.Time
Expand Down Expand Up @@ -229,35 +267,6 @@ func visit(url *url.URL) {
}
req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))

tr := &http.Transport{
Proxy: http.ProxyFromEnvironment,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}

switch url.Scheme {
case "https":
host, _, err := net.SplitHostPort(req.Host)
if err != nil {
host = req.Host
}

tr.TLSClientConfig = &tls.Config{
ServerName: host,
InsecureSkipVerify: insecure,
Certificates: readClientCert(clientCertFile),
}

// Because we create a custom TLSClientConfig, we have to opt-in to HTTP/2.
// See https://github.com/golang/go/issues/14275
err = http2.ConfigureTransport(tr)
if err != nil {
log.Fatalf("failed to prepare transport for HTTP/2: %v", err)
}
}

client := &http.Client{
Transport: tr,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
Expand Down Expand Up @@ -363,7 +372,7 @@ func visit(url *url.URL) {
log.Fatalf("maximum number of redirects (%d) followed", maxRedirects)
}

visit(loc)
visit(tr, loc)
}
}

Expand Down

0 comments on commit 6ada476

Please sign in to comment.