Skip to content
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

Setting and unsetting CURLOPT_NOBODY causes hang #5725

causal-agent opened this issue Jul 26, 2020 · 4 comments

Setting and unsetting CURLOPT_NOBODY causes hang #5725

causal-agent opened this issue Jul 26, 2020 · 4 comments


Copy link

causal-agent commented Jul 26, 2020

Since curl 7.71.0, setting and unsetting CURLOPT_NOBODY causes the request following unsetting it to hang. This behaviour was introduced in 9c845be, which sets the request method to HEAD when CURLOPT_NOBODY is set, but does not change it away from HEAD when it is unset. Notably, this comment and the behaviour it describes was removed 9c845be#diff-8fb104c402dc51bdffef05a372f32aa2L4000

     /* ... but if unset there really is no perfect method that is the
        "opposite" of HEAD but in reality most people probably think GET
        then. The important thing is that we can't let it remain HEAD if the
        opt_no_body is set FALSE since then we'll behave wrong when getting
        HTTP. */

I did this

#include <curl/curl.h>
int main(void) {
	CURL *curl = curl_easy_init();
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
	curl_easy_setopt(curl, CURLOPT_URL, "");
	curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
	curl_easy_setopt(curl, CURLOPT_NOBODY, 0L);

I expected the following

A HEAD request followed by a GET request (behaviour prior to 7.71.0). Instead, the second request is still a HEAD request, but curl waits to receive a body, causing a hang.

curl/libcurl version

curl 7.71.0 (amd64-portbld-freebsd12.1) libcurl/7.71.0 OpenSSL/1.1.1d zlib/1.2.11 nghttp2/1.41.0
Release-Date: 2020-06-24
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smtp smtps telnet tftp 
Features: alt-svc AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz NTLM NTLM_WB SPNEGO SSL TLS-SRP UnixSockets

operating system

FreeBSD [snip] 12.1-RELEASE-p7 FreeBSD 12.1-RELEASE-p7 GENERIC  amd64
Copy link

bagder commented Jul 26, 2020

This does indeed change the behavior, but let me also point out that setting CURLOPT_NOBODY to 0L is not how to reset a handle back to doing a GET (precisely because the "opposite" of HEAD is not necessarily GET) and it is not documented to do that. We added CURLOPT_HTTPGET for exactly that purpose

Copy link

Yeah that's the workaround I found, although it wasn't obvious. Perhaps that should be called out more clearly in the documentation for CURLOPT_NOBODY.

bagder added a commit that referenced this issue Jul 27, 2020
Unsetting CURLOPT_NOBODY with 0L when doing HTTP has no documented
action but before 7.71.0 that used to switch back to GET and with this
change (assuming the method is still set to HEAD) this behavior is
brought back.

Reported-by: causal-agent on github
Isssue: #5725
@bagder bagder linked a pull request Jul 27, 2020 that will close this issue
@bagder bagder self-assigned this Jul 27, 2020
Copy link

bagder commented Jul 27, 2020

@causal-agent do #5728 and #5729 improve things for you?

Copy link

Looks good, thanks!

@bagder bagder closed this as completed in 91cb16b Jul 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Successfully merging a pull request may close this issue.

2 participants