- bug report #2727981 (http://curl.haxx.se/bug/view.cgi?id=2727981) by Martin
authorDaniel Stenberg <daniel@haxx.se>
Mon, 13 Apr 2009 18:01:02 +0000 (18:01 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 13 Apr 2009 18:01:02 +0000 (18:01 +0000)
  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
RELEASE-NOTES
lib/url.c

diff --git a/CHANGES b/CHANGES
index 8df917b..1c270c8 100644 (file)
--- 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:
index 8d42a46..9b241a7 100644 (file)
@@ -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)
index 22b8f7d..5c87a38 100644 (file)
--- 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);