]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl: return error if etag options are used with multiple URLs
authorDaniel Stenberg <daniel@haxx.se>
Thu, 12 Dec 2024 16:03:59 +0000 (17:03 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 13 Dec 2024 09:11:26 +0000 (10:11 +0100)
And document it.

Add tests 484 and 485

Fixes #15729
Reported-by: Tamir Duberstein
Closes #15731

docs/cmdline-opts/etag-compare.md
docs/cmdline-opts/etag-save.md
src/tool_cfgable.h
src/tool_getparam.c
tests/data/Makefile.am
tests/data/test484 [new file with mode: 0644]
tests/data/test485 [new file with mode: 0644]

index d69cbdf34c4baee828b62306270bf15baea37357..114806552bcd4a9f2a1e6b53042cef4d30662924 100644 (file)
@@ -25,3 +25,5 @@ line with the desired ETag. An empty file is parsed as an empty ETag.
 
 Use the option --etag-save to first save the ETag from a response, and then
 use this option to compare against the saved ETag in a subsequent request.
+
+Use this option with a single URL only.
index aa346adad3bb957b13571c87a75d9bfb95465946..c81773b6e263ce685e689b85085fe3b4ab18fd24 100644 (file)
@@ -17,6 +17,6 @@ Example:
 # `--etag-save`
 
 Save an HTTP ETag to the specified file. An ETag is a caching related header,
-usually returned in a response.
+usually returned in a response. Use this option with a single URL only.
 
 If no ETag is sent by the server, an empty file is created.
index ae59a9bf672dc2293acdd588b2e354f650e0a0b0..62f0e58cc430da169b3cd696b063b931cc2d653f 100644 (file)
@@ -130,6 +130,7 @@ struct OperationConfig {
   struct getout *url_get;   /* point to the node to fill in URL */
   struct getout *url_out;   /* point to the node to fill in outfile */
   struct getout *url_ul;    /* point to the node to fill in upload */
+  size_t num_urls;          /* number of URLs added to the list */
 #ifndef CURL_DISABLE_IPFS
   char *ipfs_gateway;
 #endif /* !CURL_DISABLE_IPFS */
index d352c80a5282615e2e7662bb1c04fa450893915a..63b328c1897c66411c887b80c7dad968b6306418 100644 (file)
@@ -1019,7 +1019,8 @@ const struct LongShort *findlongopt(const char *opt)
                  sizeof(aliases[0]), findarg);
 }
 
-static ParameterError parse_url(struct OperationConfig *config,
+static ParameterError parse_url(struct GlobalConfig *global,
+                                struct OperationConfig *config,
                                 const char *nextarg)
 {
   ParameterError err = PARAM_OK;
@@ -1050,6 +1051,11 @@ static ParameterError parse_url(struct OperationConfig *config,
     /* fill in the URL */
     err = getstr(&url->url, nextarg, DENY_BLANK);
     url->flags |= GETOUT_URL;
+    if((++config->num_urls > 1) && (config->etag_save_file ||
+                                    config->etag_compare_file)) {
+      errorf(global, "The etag options only work on a single URL");
+      return PARAM_BAD_USE;
+    }
   }
   return err;
 }
@@ -1911,7 +1917,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
       config->xattr = toggle;
       break;
     case C_URL: /* --url */
-      err = parse_url(config, nextarg);
+      err = parse_url(global, config, nextarg);
       break;
     case C_FTP_SSL: /* --ftp-ssl */
     case C_SSL: /* --ssl */
@@ -2549,10 +2555,20 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
         config->socks5_auth &= ~CURLAUTH_GSSAPI;
       break;
     case C_ETAG_SAVE: /* --etag-save */
-      err = getstr(&config->etag_save_file, nextarg, DENY_BLANK);
+      if(config->num_urls > 1) {
+        errorf(global, "The etag options only work on a single URL");
+        err = PARAM_BAD_USE;
+      }
+      else
+        err = getstr(&config->etag_save_file, nextarg, DENY_BLANK);
       break;
     case C_ETAG_COMPARE: /* --etag-compare */
-      err = getstr(&config->etag_compare_file, nextarg, DENY_BLANK);
+      if(config->num_urls > 1) {
+        errorf(global, "The etag options only work on a single URL");
+        err = PARAM_BAD_USE;
+      }
+      else
+        err = getstr(&config->etag_compare_file, nextarg, DENY_BLANK);
       break;
     case C_CURVES: /* --curves */
       err = getstr(&config->ssl_ec_curves, nextarg, DENY_BLANK);
index bcdd965808052ddf4981feeb1a53d43b18fcbe20..bd9a0bbaaff1e36f164c6da3177ba31d412d8ad7 100644 (file)
@@ -78,7 +78,7 @@ test444 test445 test446 test447 test448 test449 test450 test451 test452 \
 test453 test454 test455 test456 test457 test458 test459 test460 test461 \
 test462 test463 test467 test468 test469 test470 test471 test472 test473 \
 test474 test475 test476 test477 test478 test479 test480 test481 test482 \
-test483 \
+test483 test484 test485 \
 test490 test491 test492 test493 test494 test495 test496 test497 test498 \
 test499 test500 test501 test502 test503 test504 test505 test506 test507 \
 test508 test509 test510 test511 test512 test513 test514 test515 test516 \
diff --git a/tests/data/test484 b/tests/data/test484
new file mode 100644 (file)
index 0000000..4c5c4cc
--- /dev/null
@@ -0,0 +1,44 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+etags
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<name>
+Use --etag-compare and -save with more than one URL
+</name>
+<command>
+http://example.com/%TESTNUMBER --etag-compare %LOGDIR/etag%TESTNUMBER --etag-save %LOGDIR/etag%TESTNUMBER --url http://example.net/fooo
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+2
+</errorcode>
+<stderr mode="text">
+curl: The etag options only work on a single URL
+curl: option --url: is badly used here
+%if manual
+curl: try 'curl --help' or 'curl --manual' for more information
+%else
+curl: try 'curl --help' for more information
+%endif
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/data/test485 b/tests/data/test485
new file mode 100644 (file)
index 0000000..a6405a6
--- /dev/null
@@ -0,0 +1,44 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+etags
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<name>
+Use --etag-compare and -save with more than one URL, URLs specified first
+</name>
+<command>
+http://example.com/%TESTNUMBER http://example.net/fooo --etag-save %LOGDIR/etag%TESTNUMBER
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+2
+</errorcode>
+<stderr mode="text">
+curl: The etag options only work on a single URL
+curl: option --etag-save: is badly used here
+%if manual
+curl: try 'curl --help' or 'curl --manual' for more information
+%else
+curl: try 'curl --help' for more information
+%endif
+</stderr>
+</verify>
+</testcase>