From 379bfa5a36809b3c44bc792cffd36c832b5d9fbb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 13 Apr 2009 18:01:02 +0000 Subject: - bug report #2727981 (http://curl.haxx.se/bug/view.cgi?id=2727981) by Martin Storsjo pointed out how setting CURLOPT_NOBODY to 0 could be downright confusing as it set the method to either GET or HEAD. The example he showed looked like: curl_easy_setopt(curl, CURLOPT_PUT, 1); curl_easy_setopt(curl, CURLOPT_NOBODY, 0); The new way doesn't alter the method until the request is about to start. If CURLOPT_NOBODY is then 1 the HTTP request will be HEAD. If CURLOPT_NOBODY is 0 and the request happens to have been set to HEAD, it will then instead be set to GET. I believe this will be less surprising to users, and hopefully not hit any existing users badly. --- CHANGES | 14 ++++++++++++++ RELEASE-NOTES | 3 ++- lib/url.c | 27 +++++++++++++++++---------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 8df917b5f..1c270c83a 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,20 @@ Changelog Daniel Stenberg (13 Apr 2009) +- bug report #2727981 (http://curl.haxx.se/bug/view.cgi?id=2727981) by Martin + Storsjö pointed out how setting CURLOPT_NOBODY to 0 could be downright + confusing as it set the method to either GET or HEAD. The example he showed + looked like: + + curl_easy_setopt(curl, CURLOPT_PUT, 1); + curl_easy_setopt(curl, CURLOPT_NOBODY, 0); + + The new way doesn't alter the method until the request is about to start. If + CURLOPT_NOBODY is then 1 the HTTP request will be HEAD. If CURLOPT_NOBODY is + 0 and the request happens to have been set to HEAD, it will then instead be + set to GET. I believe this will be less surprising to users, and hopefully + not hit any existing users badly. + - Toshio Kuratomi reported a memory leak problem with libcurl+NSS that turned out to be leaking cacerts. Kamil Dudka helped me complete the fix. The issue is found in Redhat's bug tracker: diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 8d42a4665..9b241a7a4 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -27,6 +27,7 @@ This release includes the following bugfixes: o Sun compilers specific preprocessor block removed from curlbuild.h.dist o allow creation of four way fat libcurl Mac OS X Framework o memory leaks in libcurl+NSS + o improved the CURLOPT_NOBODY set to 0 confusions This release includes the following known bugs: @@ -37,6 +38,6 @@ advice from friends like these: Daniel Fandrich, Yang Tse, David James, Chris Deidun, Bill Egert, Andre Guibert de Bruet, Andreas Farber, Frank Hempel, Pierre Brico, - Kamil Dudka, Jim Freeman, Daniel Johnson, Toshio Kuratomi + Kamil Dudka, Jim Freeman, Daniel Johnson, Toshio Kuratomi, Martin Storsjö Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/url.c b/lib/url.c index 22b8f7dfd..5c87a3873 100644 --- a/lib/url.c +++ b/lib/url.c @@ -887,13 +887,6 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * Do not include the body part in the output data stream. */ data->set.opt_no_body = (bool)(0 != va_arg(param, long)); - - /* in HTTP lingo, no body means using the HEAD request and 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. */ - data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET; break; case CURLOPT_FAILONERROR: /* @@ -909,12 +902,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, * using the PUT request. */ data->set.upload = (bool)(0 != va_arg(param, long)); - if(data->set.upload) + if(data->set.upload) { /* If this is HTTP, PUT is what's needed to "upload" */ data->set.httpreq = HTTPREQ_PUT; + data->set.opt_no_body = FALSE; /* this is implied */ + } else - /* In HTTP, the opposite of upload is either GET or a HEAD */ - data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET; + /* In HTTP, the opposite of upload is GET (unless NOBODY is true as + then this can be changed to HEAD later on) */ + data->set.httpreq = HTTPREQ_GET; break; case CURLOPT_FILETIME: /* @@ -4872,6 +4868,17 @@ static CURLcode do_init(struct connectdata *conn) conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ data->state.expect100header = FALSE; + if(data->set.opt_no_body) + /* in HTTP lingo, no body means using the HEAD request... */ + data->set.httpreq = HTTPREQ_HEAD; + else if(HTTPREQ_HEAD == data->set.httpreq) + /* ... 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. */ + data->set.httpreq = HTTPREQ_GET; + /* NB: the content encoding software depends on this initialization */ Curl_easy_initHandleData(data); -- cgit v1.2.3