Skip to content

Commit

Permalink
clients.go: change implementation to send Host header correctly
Browse files Browse the repository at this point in the history
Turns out there is a way to send Host header correctly with fasthttp.
This commit also adds a bunch of tests to improve coverage.

Updates #41.
  • Loading branch information
codesenberg committed Dec 18, 2018
1 parent 6e5be6e commit 4b1b549
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 7 deletions.
50 changes: 50 additions & 0 deletions args_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,41 @@ func TestArgsParsing(t *testing.T) {
in [][]string
out config
}{
{
[][]string{
{programName, ":8080"},
{programName, "localhost:8080"},
},
config{
numConns: defaultNumberOfConns,
timeout: defaultTimeout,
headers: new(headersList),
method: "GET",
url: "http://localhost:8080",
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
[][]string{
{programName, "https://"},
{programName, "https://:443"},
{programName, "https://localhost"},
},
config{
numConns: defaultNumberOfConns,
timeout: defaultTimeout,
headers: new(headersList),
method: "GET",
url: "https://localhost:443",
printIntro: true,
printProgress: true,
printResult: true,
format: knownFormat("plain-text"),
},
},
{
[][]string{{programName, "https://somehost.somedomain"}},
config{
Expand Down Expand Up @@ -790,3 +825,18 @@ func TestArgsParsingWithInvalidPrintSpec(t *testing.T) {
}
}
}

func TestTryParseUrl(t *testing.T) {
invalid := []string{
"ftp://bla:89",
"http://bla:bla:bla",
"htp:/bla:bla:bla",
}

for _, url := range invalid {
_, err := tryParseURL(url)
if err == nil {
t.Errorf("%q is not a valid URL", url)
}
}
}
38 changes: 38 additions & 0 deletions bombardier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -703,3 +703,41 @@ func testBombardierStreamsBodyFromFile(clientType clientTyp, t *testing.T) {
b.disableOutput()
b.bombard()
}

func TestBombardierShouldSendCustomHostHeader(t *testing.T) {
testAllClients(t, testBombardierShouldSendCustomHostHeader)
}

func testBombardierShouldSendCustomHostHeader(
clientType clientTyp, t *testing.T,
) {
host := "custom-host"
s := httptest.NewServer(
http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
if r.Host != host {
t.Errorf("Host must be %q, but it's %q", host, r.Host)
}
}),
)
defer s.Close()
numReqs := uint64(100)
headers := headersList([]header{
{"Host", host},
})
b, e := newBombardier(config{
numConns: defaultNumberOfConns,
numReqs: &numReqs,
url: s.URL,
headers: &headers,
timeout: defaultTimeout,
method: "GET",
body: "",
clientType: clientType,
format: knownFormat("plain-text"),
})
if e != nil {
t.Error(e)
}
b.disableOutput()
b.bombard()
}
26 changes: 19 additions & 7 deletions clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,28 @@ type clientOpts struct {
}

type fasthttpClient struct {
client *fasthttp.Client
client *fasthttp.HostClient

headers *fasthttp.RequestHeader
url, method string
headers *fasthttp.RequestHeader
host, requestURI, method string

body *string
bodProd bodyStreamProducer
}

func newFastHTTPClient(opts *clientOpts) client {
c := new(fasthttpClient)
c.client = &fasthttp.Client{
MaxConnsPerHost: int(opts.maxConns),
u, err := url.Parse(opts.url)
if err != nil {
// opts.url guaranteed to be valid at this point
panic(err)
}
c.host = u.Host
c.requestURI = "/" + u.Path + "?" + u.RawQuery
c.client = &fasthttp.HostClient{
Addr: u.Host,
IsTLS: u.Scheme == "https",
MaxConns: int(opts.maxConns),
ReadTimeout: opts.timeout,
WriteTimeout: opts.timeout,
DisableHeaderNamesNormalizing: true,
Expand All @@ -58,7 +67,7 @@ func newFastHTTPClient(opts *clientOpts) client {
),
}
c.headers = headersToFastHTTPHeaders(opts.headers)
c.url, c.method, c.body = opts.url, opts.method, opts.body
c.method, c.body = opts.method, opts.body
c.bodProd = opts.bodProd
return client(c)
}
Expand All @@ -72,8 +81,11 @@ func (c *fasthttpClient) do() (
if c.headers != nil {
c.headers.CopyTo(&req.Header)
}
if len(req.Header.Host()) == 0 {
req.Header.SetHost(c.host)
}
req.Header.SetMethod(c.method)
req.SetRequestURI(c.url)
req.SetRequestURI(c.requestURI)
if c.body != nil {
req.SetBodyString(*c.body)
} else {
Expand Down

0 comments on commit 4b1b549

Please sign in to comment.