Currently the HTTP digest authentication is part of the http.request() method, it would probably be better off (more readable and testable for sure) as a http.RoundTripper wrapper like these. This issue is a spin-off from the original HTTP request refactoring one.
While testing the fixes for https://github.com/loadimpact/k6/issues/1044 and https://github.com/loadimpact/k6/issues/1041, I looked through the current HTTP digest authentication code and noticed that it prematurely returns from MakeRequest() when there's an error, unlike the rest of the code below. So, as a consequence, the response timings aren't properly populated...
Additionally, something that I've omitted to mention in the original issue message - currently the HTTP digest authentication will always make 2 separate http requests.
Connected Golang issue: https://github.com/golang/go/issues/29409
The current digest authentication library we use is github.com/Soontao/goHttpDigestClient, some alternatives:
There are some bugs with cookie handling in the NTLM authentication (https://github.com/loadimpact/k6/issues/1210), which is currently handled in a very similar way to the digest authentication, so we should investigate if the same bug occurs here...
Our current dependency seems to be dead, and has a bug that's can cause a panic... It assumes that a header value always contains key=value pairs: https://github.com/loadimpact/k6/blob/9586f2f4624548e40e9a0567cf821b5523489a36/vendor/github.com/Soontao/goHttpDigestClient/challenge.go#L37-L38
And funky server responses can cause k6 to panic with:
panic: runtime error: index out of range [1] with length 1 [recovered]
panic: runtime error: index out of range [1] with length 1 [recovered]
panic: runtime error: index out of range [1] with length 1
goroutine 57 [running]:
github.com/loadimpact/k6/vendor/github.com/dop251/goja.AssertFunction.func1.1(0xc0028b5cd8)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/runtime.go:1456 +0x98
panic(0xdfd920, 0xc002cb62e0)
/usr/local/go/src/runtime/panic.go:679 +0x1b2
github.com/loadimpact/k6/vendor/github.com/dop251/goja.(*vm).try.func1(0xc00049dc70, 0x0, 0xc0028b5ba8, 0x0, 0x0, 0x0, 0xc0028b5c00)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/vm.go:373 +0x3b0
panic(0xdfd920, 0xc002cb62e0)
/usr/local/go/src/runtime/panic.go:679 +0x1b2
github.com/loadimpact/k6/vendor/github.com/Soontao/goHttpDigestClient.NewChallenge(0xc002ccc090, 0x81, 0x10)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/Soontao/goHttpDigestClient/challenge.go:38 +0x26e
github.com/loadimpact/k6/vendor/github.com/Soontao/goHttpDigestClient.GetChallengeFromHeader(0xc00018a818, 0x0)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/Soontao/goHttpDigestClient/client.go:30 +0x5b
github.com/loadimpact/k6/lib/netext/httpext.digestTransport.RoundTrip(0x10a5aa0, 0xc001c44840, 0xc000c73a00, 0x0, 0x0, 0xc0028b4e58)
/home/alpine/go/src/github.com/loadimpact/k6/lib/netext/httpext/digest_transport.go:69 +0x1a5
net/http.send(0xc000c73a00, 0x10a71a0, 0xc001723e70, 0x0, 0x0, 0x0, 0xc001770b90, 0xc0028b4b40, 0x2, 0x8)
/usr/local/go/src/net/http/client.go:250 +0x443
net/http.(*Client).send(0xc001c44a50, 0xc000c73a00, 0x0, 0x0, 0x0, 0xc001770b90, 0x1, 0x2, 0x0)
/usr/local/go/src/net/http/client.go:174 +0xfa
net/http.(*Client).do(0xc001c44a50, 0xc000c73a00, 0x0, 0x0, 0x0)
/usr/local/go/src/net/http/client.go:641 +0x3ce
net/http.(*Client).Do(...)
/usr/local/go/src/net/http/client.go:509
github.com/loadimpact/k6/lib/netext/httpext.MakeRequest(0x10b8a80, 0xc001c44270, 0xc000e08f00, 0x0, 0x0, 0x0)
/home/alpine/go/src/github.com/loadimpact/k6/lib/netext/httpext/request.go:317 +0x7c1
github.com/loadimpact/k6/js/modules/k6/http.(*HTTP).Request(0xc00011a000, 0x10b8a80, 0xc001c44270, 0xe921d4, 0x3, 0x10c5760, 0xc002482a00, 0xc001cca7e0, 0x2, 0x2, ...)
/home/alpine/go/src/github.com/loadimpact/k6/js/modules/k6/http/request.go:110 +0x19d
github.com/loadimpact/k6/js/modules/k6/http.(*HTTP).Get(0xc00011a000, 0x10b8a80, 0xc001c44270, 0x10c5760, 0xc002482a00, 0xc0017235b0, 0x1, 0x1, 0x0, 0x0, ...)
/home/alpine/go/src/github.com/loadimpact/k6/js/modules/k6/http/request.go:52 +0x15b
reflect.Value.call(0xe364e0, 0xc00011a000, 0x1213, 0xe97b43, 0x9, 0xc001096780, 0x3, 0x3, 0xb, 0xdfca40, ...)
/usr/local/go/src/reflect/value.go:460 +0x5f6
reflect.Value.CallSlice(0xe364e0, 0xc00011a000, 0x1213, 0xc001096780, 0x3, 0x3, 0x194, 0xc000fc26f0, 0x8c84a3)
/usr/local/go/src/reflect/value.go:334 +0xb4
github.com/loadimpact/k6/js/common.Bind.func1(0x10c5580, 0xc000f7d060, 0xc000c14300, 0x2, 0x8, 0x1e6fcf496b80abe, 0x40c6d8)
/home/alpine/go/src/github.com/loadimpact/k6/js/common/bridge.go:241 +0x780
github.com/loadimpact/k6/vendor/github.com/dop251/goja.(*vm)._nativeCall(0xc00049dc70, 0xc0024e89a0, 0x2)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/vm.go:1835 +0x291
github.com/loadimpact/k6/vendor/github.com/dop251/goja.call.exec(0x2, 0xc00049dc70)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/vm.go:1819 +0x4a2
github.com/loadimpact/k6/vendor/github.com/dop251/goja.(*vm).run(0xc00049dc70)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/vm.go:289 +0x99
github.com/loadimpact/k6/vendor/github.com/dop251/goja.(*funcObject).Call(0xc000f6bb00, 0x10c5bc0, 0x19796e0, 0xc001723220, 0x1, 0x1, 0x10c5bc0, 0x19796e0)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/func.go:130 +0x2cc
github.com/loadimpact/k6/vendor/github.com/dop251/goja.AssertFunction.func1.2()
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/runtime.go:1461 +0x96
github.com/loadimpact/k6/vendor/github.com/dop251/goja.(*vm).try(0xc00049dc70, 0xc000fc2c50, 0x0)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/vm.go:379 +0x147
github.com/loadimpact/k6/vendor/github.com/dop251/goja.AssertFunction.func1(0x10c5bc0, 0x19796e0, 0xc001723220, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0)
/home/alpine/go/src/github.com/loadimpact/k6/vendor/github.com/dop251/goja/runtime.go:1460 +0x13a
github.com/loadimpact/k6/js.(*VU).runFn(0xc0006d5cc0, 0x10b89c0, 0xc0019ee380, 0xc000ab49c0, 0x10b8901, 0xc000f7d280, 0xc001723220, 0x1, 0x1, 0xc00007a0c0, ...)
/home/alpine/go/src/github.com/loadimpact/k6/js/runner.go:477 +0x35e
github.com/loadimpact/k6/js.(*VU).RunOnce(0xc0006d5cc0, 0x10b89c0, 0xc0019ee380, 0x0, 0x0)
/home/alpine/go/src/github.com/loadimpact/k6/js/runner.go:427 +0x277
github.com/loadimpact/k6/core/local.(*vuHandle).run(0xc0015aff40, 0xc00007e070, 0xc00007a480, 0xc00012c600)
/home/alpine/go/src/github.com/loadimpact/k6/core/local/local.go:70 +0x152
github.com/loadimpact/k6/core/local.(*Executor).scale.func1(0xc0015aff40, 0xc000d47b00, 0xc00007a480, 0xc00012c600)
/home/alpine/go/src/github.com/loadimpact/k6/core/local/local.go:349 +0x4d
created by github.com/loadimpact/k6/core/local.(*Executor).scale
/home/alpine/go/src/github.com/loadimpact/k6/core/local/local.go:348 +0x328
Most helpful comment
Connected Golang issue: https://github.com/golang/go/issues/29409
The current digest authentication library we use is github.com/Soontao/goHttpDigestClient, some alternatives: