-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add TLS connection info to response object #322
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
Conversation
Draft (hidden) documentation is now also available at: |
I want to make a structural change here, because for the first time in k6' history, we have a use for constants. Making this easy-to-read string comparisons (ocsp.status === "good") sounds good in theory, until someone typo's it as "god" and suddenly we're refusing to trust any authority short of a holy scripture. And while that's a fairly easy one to catch, what about "tls1.2" vs "TLS1.2"? The change I'm proposing is:
The actual naming of the constants is up for debate, and I think OCSP status may be better implemented as a tristate bool ( |
js/modules/k6/http/http.go
Outdated
"sync" | ||
"time" | ||
|
||
"golang.org/x/crypto/ocsp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please merge this into the import block below.
js/modules/k6/http/http.go
Outdated
} | ||
|
||
type OCSP struct { | ||
StapledResponse OCSPStapledResponse |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this indirection really needed...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not, maybe it should just be res.ocsp_response
on the JS side?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe even just res.ocsp
?
js/modules/k6/http/http.go
Outdated
tags["proto"] = resp.Proto | ||
|
||
if res.TLS != nil { | ||
tlsState := res.TLS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can shorten this down to if tlsState := res.TLS; tlsState != nil {
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 typical Go noob mistake 😄
js/modules/k6/http/http.go
Outdated
resp.TLSVersion = "tls1.2" | ||
} | ||
resp.TLSCipherSuite = lib.SupportedTLSCipherSuitesToString[tlsState.CipherSuite] | ||
resp.OCSP.StapledResponse = OCSPStapledResponse{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is redundant.
js/modules/k6/http/http.go
Outdated
|
||
if res.TLS != nil { | ||
tlsState := res.TLS | ||
switch tlsState.Version { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make this a helper function, then assign resp.OCSP.StapledResponse
to a fully initialized object. These switches are real lengthy.
js/modules/k6/http/http.go
Outdated
resp.OCSP.StapledResponse.ProducedAt = ocspRes.ProducedAt.String() | ||
resp.OCSP.StapledResponse.ThisUpdate = ocspRes.ThisUpdate.String() | ||
resp.OCSP.StapledResponse.NextUpdate = ocspRes.NextUpdate.String() | ||
resp.OCSP.StapledResponse.RevokedAt = ocspRes.RevokedAt.String() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be in a format we can compare on the JS side... UNIX timestamps?
(I'm also kind of questioning what purpose it will serve for a load test script; I suppose it could be useful for logging, but not much more.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, should we use JS Date objects or Epoch milliseconds (to compare with Date.now()
and Date.getTime()
) when exposing to JS? Had the same question in the cookie PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just in the interest of performance, I think maybe giving a UNIX timestamp would be better than instancing whole date objects every time. The JS-native way seems to be to deal with milliseconds for them, so then you can just do new Date(revokedAt)
.
js/modules/k6/http/http_test.go
Outdated
_, err := common.RunString(rt, `http.get("https://expired.badssl.com/");`) | ||
assert.EqualError(t, err, "GoError: Get https://expired.badssl.com/: x509: certificate has expired or is not yet valid") | ||
}) | ||
t.Run("tls10", func(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These versions are nigh identical and would do better templated than copypasted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will look into that.
I'd also like TLS version and OCSP status to be added as tags to responses. |
@liclac Haha, Agree on the use of constants for TLS version and cipher suites. I'll change the OCSP status to use constants as well. IMHO that's more clear when reading than a tristate. |
ad9135d
to
2bca667
Compare
2bca667
to
bfa56d8
Compare
@liclac Requested changes have now been done, please have another look. |
js/modules/k6/http/http.go
Outdated
case tls.VersionTLS12: | ||
res.TLSVersion = h.TLS_1_2 | ||
} | ||
res.TLSCipherSuite = lib.SupportedTLSCipherSuitesToString[tlsState.CipherSuite] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newline, please.
js/modules/k6/http/http.go
Outdated
res.TLSVersion = h.TLS_1_2 | ||
} | ||
res.TLSCipherSuite = lib.SupportedTLSCipherSuitesToString[tlsState.CipherSuite] | ||
ocspStapledRes := OCSP{Status: h.OCSP_STATUS_UNKNOWN} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newline, please.
js/modules/k6/http/http.go
Outdated
func (res *HTTPResponse) setTLSInfo(h *HTTP, tlsState *tls.ConnectionState) { | ||
switch tlsState.Version { | ||
case tls.VersionSSL30: | ||
res.TLSVersion = h.SSL_3_0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These constants should honestly be global const
s, passing in the HTTP object just to read them feels silly.
js/modules/k6/http/http.go
Outdated
Duration, Blocked, LookingUp, Connecting, Sending, Waiting, Receiving float64 | ||
} | ||
|
||
type HTTPResponse struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This struct is honestly getting big enough that I'd split it off into a response.go
file.
js/modules/k6/http/http.go
Outdated
tags["status"] = strconv.Itoa(resp.Status) | ||
tags["proto"] = resp.Proto | ||
|
||
if tlsState := res.TLS; res.TLS != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tlsState
is longer than res.TLS
. As far as shorthands go, that's pretty lousy.
@liclac Requested changes have been made. |
This PR adds TLS version, cipher suite and OCSP stapled response information to each HTTP response object, implementing #298.
Example usage:
and
The OCSP
stapled_response
object also contains the following properties:ocsp.stapled_response.revocation_reason
: a stringocsp.stapled_response.produced_at
: a date stringocsp.stapled_response.this_update
: a date stringocsp.stapled_response.next_update
: a date stringocsp.stapled_response.revoked_at
: a date string