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
Empty HTTP headers not thread-safe #3578
Comments
Confirmed. The issue comes from the fact that the code finds the semicolon there, puts a temporary colon in its place and then puts the semicolon back again after some checks. This of course doesn't work when done on the same list in multiple parallel threads... Lines 1781 to 1852 in e652252
|
Thanks for your report and the clear repro. It takes about n100 for me or n1000 with valgrind (which shows nothing unexpected). I suspect this is caused by Lines 1790 to 1796 in f3294d9
I don't think the user's passed in data, of which we are accessing directly without a copy, should be modified even temporarily. The easiest fix would be copy headers->data and then modify our copy. It could even be limited to only the semicolon (like we could have a hdrline and hdrline_is_heap). To do it without a copy would mean changing checkprefix to recognize semicolon. This is just a hunch I haven't tried a fix yet. |
Previously the function would edit the provider header in-place when a semicolon is used to signify an empty header. This made it impossible to use the same set of custom headers in multiple threads simultaneously. This approach now makes a local copy when it needs to edit the string. Reported-by: d912e3 on github Fixes #3578 Closes #xxxx
Previously the function would edit the provided header in-place when a semicolon is used to signify an empty header. This made it impossible to use the same set of custom headers in multiple threads simultaneously. This approach now makes a local copy when it needs to edit the string. Reported-by: d912e3 on github Fixes #3578 Closes #3579
I did this
client.c
sends m HTTP requests with n empty headers named Header (i.e.,"Header;"
) in parallel by cloning a prepared handle and performing it in a thread:server.go
returns the number of headers named Header to each request:Run
server
and executeclient
repeatedly, e.g.:I expected the following
The client should always return the same number of lines with the same number of headers received by the server as specified with the flags
-m
and-n
.When using the
-c
flag and lettingclient
send non-empty headers (i.e.,"Header: foo"
) instead, the output is as expected.Thus, empty headers are not thread-safe.
curl/libcurl version
The text was updated successfully, but these errors were encountered: