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

Allow HTTP redirects #102

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions args_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type kingpinParser struct {
latencies bool
insecure bool
disableKeepAlives bool
allowRedirects bool
method string
body string
bodyFilePath string
Expand Down Expand Up @@ -111,6 +112,10 @@ func newKingpinParser() argsParser {
"Disable HTTP keep-alive. For fasthttp use -H 'Connection: close'").
Short('a').
BoolVar(&kparser.disableKeepAlives)
app.Flag("allowRedirects",
"Allow the client to follow HTTP redirects").
Short('R').
BoolVar(&kparser.allowRedirects)

app.Flag("header", "HTTP headers to use(can be repeated)").
PlaceHolder("\"K: V\"").
Expand Down Expand Up @@ -226,6 +231,7 @@ func (k *kingpinParser) parse(args []string) (config, error) {
printLatencies: k.latencies,
insecure: k.insecure,
disableKeepAlives: k.disableKeepAlives,
allowRedirects: k.allowRedirects,
rate: k.rate.val,
clientType: k.clientType,
printIntro: pi,
Expand Down
21 changes: 21 additions & 0 deletions args_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,27 @@ func TestArgsParsing(t *testing.T) {
format: userDefinedTemplate("/path/to/tmpl.txt"),
},
},
{
[][]string{
{
programName,
"localhost:8080",
"-R",
},
},
config{
numConns: defaultNumberOfConns,
timeout: defaultTimeout,
headers: new(headersList),
method: "GET",
url: "http://localhost:8080",
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
allowRedirects: true,
},
},
}
for _, e := range expectations {
for _, args := range e.in {
Expand Down
1 change: 1 addition & 0 deletions bombardier.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func newBombardier(c config) (*bombardier, error) {
timeout: c.timeout,
tlsConfig: tlsConfig,
disableKeepAlives: c.disableKeepAlives,
allowRedirects: c.allowRedirects,

headers: c.headers,
url: c.url,
Expand Down
44 changes: 44 additions & 0 deletions bombardier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,3 +727,47 @@ func testBombardierShouldSendCustomHostHeader(
b.disableOutput()
b.bombard()
}

func TestBombardierFollowRedirects(t *testing.T) {
testAllClients(t, testBombardierFollowRedirects)
}

func testBombardierFollowRedirects(
clientType clientTyp, t *testing.T,
) {
var numFollowRedirects uint64
s := httptest.NewServer(
http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
http.Redirect(rw, r, "/foo", http.StatusFound)
} else {
rw.WriteHeader(http.StatusOK)
numFollowRedirects++
}
}),
)
defer s.Close()
numReqs := uint64(100)
b, e := newBombardier(config{
numConns: defaultNumberOfConns,
numReqs: &numReqs,
url: s.URL,
headers: new(headersList),
timeout: defaultTimeout,
method: "GET",
body: "",
clientType: clientType,
format: knownFormat("plain-text"),
allowRedirects: true,
})
if e != nil {
t.Error(e)
return
}
b.disableOutput()
b.bombard()

if numFollowRedirects != numReqs {
t.Errorf("Bombardier does not follow HTTP redirects: expected %v, got %v", numReqs, numFollowRedirects)
}
}
17 changes: 14 additions & 3 deletions clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type clientOpts struct {
timeout time.Duration
tlsConfig *tls.Config
disableKeepAlives bool
allowRedirects bool

headers *headersList
url, method string
Expand All @@ -44,6 +45,8 @@ type fasthttpClient struct {

body *string
bodProd bodyStreamProducer

allowRedirects bool
}

func newFastHTTPClient(opts *clientOpts) client {
Expand All @@ -69,6 +72,7 @@ func newFastHTTPClient(opts *clientOpts) client {
c.headers = headersToFastHTTPHeaders(opts.headers)
c.method, c.body = opts.method, opts.body
c.bodProd = opts.bodProd
c.allowRedirects = opts.allowRedirects
return client(c)
}

Expand Down Expand Up @@ -97,7 +101,12 @@ func (c *fasthttpClient) do() (

// fire the request
start := time.Now()
err = c.client.Do(req, resp)
if c.allowRedirects {
// stop after 10 consecutive redirects
err = c.client.DoRedirects(req, resp, 10)
} else {
err = c.client.Do(req, resp)
}
if err != nil {
code = -1
} else {
Expand Down Expand Up @@ -136,9 +145,11 @@ func newHTTPClient(opts *clientOpts) client {
cl := &http.Client{
Transport: tr,
Timeout: opts.timeout,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
}
if !opts.allowRedirects {
cl.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
c.client = cl

Expand Down
1 change: 1 addition & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type config struct {
numConns uint64
numReqs *uint64
disableKeepAlives bool
allowRedirects bool
duration *time.Duration
url, method, certPath, keyPath string
body, bodyFilePath string
Expand Down