]> granicus.if.org Git - curl/commitdiff
Introuced --data-urlencode to the curl tool for easier url encoding of the
authorDaniel Stenberg <daniel@haxx.se>
Tue, 20 Nov 2007 10:08:42 +0000 (10:08 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 20 Nov 2007 10:08:42 +0000 (10:08 +0000)
data sent in a post.

CHANGES
RELEASE-NOTES
docs/curl.1
src/main.c

diff --git a/CHANGES b/CHANGES
index 88a7affca9c515c8c0e86463c49b445478058fec..19074e2c3cbbd2d8ec0fc824cc775132cdaf4910 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,14 @@
                                   Changelog
 
 
+Daniel S (20 Nov 2007)
+- Fixed a very long-lasting mprintf() bug that occured when we did "%.*s%s",
+  since the second %s would then wrongly used the numerical precision argument
+  instead and crash.
+
+- Introuced --data-urlencode to the curl tool for easier url encoding of the
+  data sent in a post.
+
 Daniel S (18 Nov 2007)
 - Rob Crittenden fixed SSL connections with NSS done with the multi-interface
 
index 8106e9d7a05139dfacf96200d2871f7d731a475d..7fa5962732398553d6c1dcad3c5c94bd8516796e 100644 (file)
@@ -1,7 +1,7 @@
 Curl and libcurl 7.17.2
 
  Public curl releases:         103
- Command line options:         121
+ Command line options:         122
  curl_easy_setopt() options:   147
  Public functions in libcurl:  55
  Public web site mirrors:      42
@@ -10,7 +10,7 @@ Curl and libcurl 7.17.2
 
 This release includes the following changes:
  
- o 
+ o --data-urlencode was added
 
 This release includes the following bugfixes:
 
index 0d0a3a12f0b8e34d38769fbe25e226e82b60fb89..b5d5eb7883122bfa913c9e7333c2da69ab1b3733 100644 (file)
@@ -261,6 +261,20 @@ the \fI--data-ascii\fP option, this is for you.
 
 If this option is used several times, the ones following the first will
 append data.
+.IP "--data-urlencode <data>"
+(HTTP) This posts data, similar to the other --data options with the exception
+that this will do partial URL encoding. (Added in 7.17.2)
+
+The <data> part should be using one of the two following syntaxes:
+.RS
+.IP "name=content"
+This will make curl URL encode the content part and pass that on. Note that
+the name part is not encoded.
+.IP "name@filename"
+This will make curl load data from the given file, URL encode that data and
+pass it on in the POST like \fIname=urlencoded-data\fP. Note that the name
+part is not encoded.
+.RE
 .IP "--digest"
 (HTTP) Enables HTTP Digest authentication. This is a authentication that
 prevents the password from being sent over the wire in clear text. Use this in
index d1b7009b75db6da9506df6610ea6afed218fd685..d0bbdcdd7e3fbd7f68266eb4fba1418eaeb516bb 100644 (file)
@@ -357,6 +357,7 @@ struct OutStruct {
 };
 
 struct Configurable {
+  CURL *easy; /* once we have one, we keep it here */
   bool remote_time;
   char *random_file;
   char *egd_file;
@@ -619,6 +620,7 @@ static void help(void)
     " -d/--data <data>   HTTP POST data (H)",
     "    --data-ascii <data>  HTTP POST ASCII data (H)",
     "    --data-binary <data> HTTP POST binary data (H)",
+    "    --data-urlencode <name=data/name@filename> HTTP POST data url encoded (H)",
     "    --negotiate     Use HTTP Negotiate Authentication (H)",
     "    --digest        Use HTTP Digest Authentication (H)",
     "    --disable-eprt  Inhibit using EPRT or LPRT (F)",
@@ -1532,6 +1534,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
     {"d", "data",        TRUE},
     {"da", "data-ascii", TRUE},
     {"db", "data-binary", TRUE},
+    {"de", "data-urlencode", TRUE},
     {"D", "dump-header", TRUE},
     {"e", "referer",     TRUE},
     {"E", "cert",        TRUE},
@@ -2045,12 +2048,83 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
       /* postfield data */
       {
         char *postdata=NULL;
+        FILE *file;
+
+        if(subletter == 'e') { /* --data-urlencode*/
+          /* [name]=[content], we encode the content part only
+           * [name]@[file name]
+           *
+           * Case 2: we first load the file using that name and then encode
+           * the content.
+           */
+          char *p = strchr(nextarg, '=');
+          long size = 0;
+          size_t nlen;
+          if(!p)
+            p = strchr(nextarg, '@');
+          if(!p) {
+            warnf(config, "bad use of --data-urlencode\n");
+            return PARAM_BAD_USE;
+          }
+          nlen = p - nextarg; /* length of the name part */
+          if('@' == *p) {
+            /* a '@' letter, it means that a file name or - (stdin) follows */
+
+            p++; /* pass the separator */
 
-        if('@' == *nextarg) {
+            if(curlx_strequal("-", p)) {
+              file = stdin;
+              SET_BINMODE(stdin);
+            }
+            else {
+              file = fopen(p, "rb");
+              if(!file)
+                warnf(config,
+                      "Couldn't read data from file \"%s\", this makes "
+                      "an empty POST.\n", nextarg);
+            }
+
+            postdata = file2memory(file, &size);
+
+            if(file && (file != stdin))
+              fclose(file);
+          }
+          else {
+            GetStr(&postdata, ++p);
+            size = strlen(postdata);
+          }
+
+          if(!postdata) {
+            /* no data from the file, point to a zero byte string to make this
+               get sent as a POST anyway */
+            postdata=strdup("");
+          }
+          else {
+            char *enc = curl_easy_escape(config->easy, postdata, size);
+            if(enc) {
+              /* now make a string with the name from above and append the
+                 encoded string */
+              size_t outlen = nlen + strlen(enc) + 2;
+              char *n = malloc(outlen);
+              if(!n)
+                return PARAM_NO_MEM;
+
+              snprintf(n, outlen, "%.*s=%s", nlen, nextarg, enc);
+              curl_free(enc);
+              free(postdata);
+              if(n) {
+                postdata = n;
+              }
+              else
+                return PARAM_NO_MEM;
+            }
+            else
+              return PARAM_NO_MEM;
+          }
+        }
+        else if('@' == *nextarg) {
           /* the data begins with a '@' letter, it means that a file name
              or - (stdin) follows */
-          FILE *file;
-
           nextarg++; /* pass the @ */
 
           if(curlx_strequal("-", nextarg)) {
@@ -3334,6 +3408,9 @@ static void free_config_fields(struct Configurable *config)
   curl_slist_free_all(config->postquote);
   curl_slist_free_all(config->headers);
   curl_slist_free_all(config->telnet_options);
+
+  if(config->easy)
+    curl_easy_cleanup(config->easy);
 }
 
 #ifdef WIN32
@@ -3443,9 +3520,9 @@ CURLcode _my_setopt(CURL *curl, struct Configurable *config, const char *name,
   if(config->libcurl) {
     /* we only use this for real if --libcurl was used */
 
-    bufp = curl_maprintf("%scurl_easy_setopt(hnd, %s, %s);%s",
-                         remark?"/* ":"", name, value,
-                         remark?" [REMARK] */":"");
+    bufp = curlx_maprintf("%scurl_easy_setopt(hnd, %s, %s);%s",
+                          remark?"/* ":"", name, value,
+                          remark?" [REMARK] */":"");
 
     if (!bufp || !curl_slist_append(easycode, bufp))
       ret = CURLE_OUT_OF_MEMORY;
@@ -3577,6 +3654,17 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
   }
 #endif
 
+  /*
+   * Get a curl handle to use for all forthcoming curl transfers.  Cleanup
+   * when all transfers are done.
+   */
+  curl = curl_easy_init();
+  if(!curl) {
+    clean_getout(config);
+    return CURLE_FAILED_INIT;
+  }
+  config->easy = curl;
+
   memset(&outs,0,sizeof(outs));
 
   config->outs = &outs;
@@ -3733,16 +3821,6 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
     }
   }
 
-  /*
-   * Get a curl handle to use for all forthcoming curl transfers.  Cleanup
-   * when all transfers are done.
-   */
-  curl = curl_easy_init();
-  if(!curl) {
-    clean_getout(config);
-    return CURLE_FAILED_INIT;
-  }
-
   /* This is the first entry added to easycode and it initializes the slist */
   easycode = curl_slist_append(easycode, "CURL *hnd = curl_easy_init();");
   if(!easycode) {
@@ -4663,6 +4741,7 @@ quit_curl:
 
   /* cleanup the curl handle! */
   curl_easy_cleanup(curl);
+  config->easy = NULL; /* cleanup now */
   if (easycode)
     curl_slist_append(easycode, "curl_easy_cleanup(hnd);");