You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Notice how we get a bytes.Buffer from a the buffer pool BPool, reset it, read the response body into it, save the result as binary or a string to be exported to the JS script and continue. The buffer is then returned back to the pool (defer state.BPool.Put(buf)).
The problem with that piece of code is that buf.Bytes() doesn't copy the data - it references the same underlying byte slice that the buffer uses. So, if a buffer gets reused before the current iteration has ended (which can easily happen, especially with http.batch()), it can still have references pointing to it. So, the old response body may get mangled... buf.String() doesn't have the same problem, since Go strings are immutable: https://play.golang.org/p/RLoDrXnVRiK
And while the buffer pools have been present since k6 v0.17.2 (added with commit b002f2c), the actual issue only occurred with the addition of binary response bodies in k6 v0.23.0.
The text was updated successfully, but these errors were encountered:
Fix a bunch of HTTP measurement and handling issues
This should fix#1041, #1044, #925, and a potential minor data race! Hopefully, without introducing new bugs or performance regressions...
While benchmarking my fixes to #1041, I found another issue that has been lurking in k6 for a similar amount of time now π€¦ββοΈ Specifically, it has to do with the buffer pools that are used for storing response bodies when the specified
responseType
isbinary
: https://github.com/loadimpact/k6/blob/607b63c4400c8b6852c7f51a0a6151f0bb8ec6b7/lib/netext/httpext/request.go#L367-L379Notice how we get a
bytes.Buffer
from a the buffer poolBPool
, reset it, read the response body into it, save the result as binary or a string to be exported to the JS script and continue. The buffer is then returned back to the pool (defer state.BPool.Put(buf)
).The problem with that piece of code is that
buf.Bytes()
doesn't copy the data - it references the same underlying byte slice that the buffer uses. So, if a buffer gets reused before the current iteration has ended (which can easily happen, especially withhttp.batch()
), it can still have references pointing to it. So, the old response body may get mangled...buf.String()
doesn't have the same problem, since Go strings are immutable: https://play.golang.org/p/RLoDrXnVRiKHere's a script demonstrating the issue:
And while the buffer pools have been present since k6 v0.17.2 (added with commit b002f2c), the actual issue only occurred with the addition of binary response bodies in k6 v0.23.0.
The text was updated successfully, but these errors were encountered: