Skip to content

Commit

Permalink
Expect a 401 first for NTLM and digest requests
Browse files Browse the repository at this point in the history
  • Loading branch information
mstoykov committed Feb 19, 2021
1 parent 17e5cc2 commit ad8c94d
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
69 changes: 69 additions & 0 deletions js/modules/k6/http/response_callback_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package http

import (
"context"
"fmt"
"testing"

"github.com/dop251/goja"
Expand Down Expand Up @@ -361,6 +362,74 @@ func TestResponseCallbackInActionWithoutPassedTag(t *testing.T) {
})
}

func TestDigestWithResponseCallback(t *testing.T) {
t.Parallel()
tb, state, samples, rt, _ := newRuntime(t)
defer tb.Cleanup()

state.HTTPResponseCallback = DefaultHTTPResponseCallback()

urlWithCreds := tb.Replacer.Replace(
"http://testuser:testpwd@HTTPBIN_IP:HTTPBIN_PORT/digest-auth/auth/testuser/testpwd",
)

allHTTPMetrics := []*stats.Metric{
metrics.HTTPReqs,
metrics.HTTPReqFailed,
metrics.HTTPReqBlocked,
metrics.HTTPReqConnecting,
metrics.HTTPReqDuration,
metrics.HTTPReqReceiving,
metrics.HTTPReqSending,
metrics.HTTPReqWaiting,
metrics.HTTPReqTLSHandshaking,
}
_, err := rt.RunString(fmt.Sprintf(`
var res = http.get(%q, { auth: "digest" });
if (res.status !== 200) { throw new Error("wrong status: " + res.status); }
if (res.error_code !== 0) { throw new Error("wrong error code: " + res.error_code); }
`, urlWithCreds))
require.NoError(t, err)
bufSamples := stats.GetBufferedSamples(samples)

reqsCount := 0
for _, container := range bufSamples {
for _, sample := range container.GetSamples() {
if sample.Metric.Name == "http_reqs" {
reqsCount++
}
}
}

require.Equal(t, 2, reqsCount)

urlRaw := tb.Replacer.Replace(
"http://HTTPBIN_IP:HTTPBIN_PORT/digest-auth/auth/testuser/testpwd")

tags := map[string]string{
"method": "GET",
"url": urlRaw,
"name": urlRaw,
"status": "401",
"group": "",
"proto": "HTTP/1.1",
"passed": "true",
"error_code": "1401",
}
assertRequestMetricsEmittedSingle(t, bufSamples[0], tags, allHTTPMetrics, func(sample stats.Sample) {
if sample.Metric.Name == metrics.HTTPReqFailed.Name {
require.EqualValues(t, sample.Value, 0)
}
})
tags["status"] = "200"
delete(tags, "error_code")
assertRequestMetricsEmittedSingle(t, bufSamples[1], tags, allHTTPMetrics, func(sample stats.Sample) {
if sample.Metric.Name == metrics.HTTPReqFailed.Name {
require.EqualValues(t, sample.Value, 0)
}
})
}

func deleteSystemTag(state *lib.State, tag string) {
enabledTags := state.Options.SystemTags.Map()
delete(enabledTags, tag)
Expand Down
16 changes: 16 additions & 0 deletions lib/netext/httpext/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,24 @@ func MakeRequest(ctx context.Context, preq *ParsedHTTPRequest) (*Response, error
}

if preq.Auth == "digest" {
// In both digest and NTLM it is expected that the first response will be 401
// this does mean that a non 401 response will be marked as failed/unexpected
if tracerTransport.responseCallback != nil {
originalResponseCallback := tracerTransport.responseCallback
tracerTransport.responseCallback = func(status int) bool {
tracerTransport.responseCallback = originalResponseCallback
return status == 401
}
}
transport = digestTransport{originalTransport: transport}
} else if preq.Auth == "ntlm" {
if tracerTransport.responseCallback != nil {
originalResponseCallback := tracerTransport.responseCallback
tracerTransport.responseCallback = func(status int) bool {
tracerTransport.responseCallback = originalResponseCallback
return status == 401
}
}
transport = ntlmssp.Negotiator{RoundTripper: transport}
}

Expand Down

0 comments on commit ad8c94d

Please sign in to comment.