]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tool_operate: for -O, use "default" as filename when the URL has none
authorDaniel Stenberg <daniel@haxx.se>
Sat, 3 Aug 2024 18:08:27 +0000 (20:08 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 4 Aug 2024 13:59:51 +0000 (15:59 +0200)
... or pick the last directory part from the path if available.

Instead of returning error.

Add test 690 and 691 to verify. Test 76 and 2036 no longer apply.

Closes #13988

docs/cmdline-opts/remote-name.md
src/tool_operate.c
src/tool_operhlp.c
tests/data/Makefile.am
tests/data/test2036 [deleted file]
tests/data/test690 [new file with mode: 0644]
tests/data/test691 [new file with mode: 0644]
tests/data/test76 [deleted file]

index 041800fa921d385c1012c1b7b36dad5b5a87f6de..e39dd51aea08c49022c321e0b491ad1b9e5b7376 100644 (file)
@@ -35,3 +35,8 @@ There is no URL decoding done on the filename. If it has %20 or other URL
 encoded parts of the name, they end up as-is as filename.
 
 You may use this option as many times as the number of URLs you have.
+
+Before curl 8.10.0, curl returned an error if the URL ended with a slash,
+which means that there is no filename part in the URL. Starting in 8.10.0,
+curl sets the filename to the last directory part of the URL or if that also
+is missing to `curl_response` (without extension) for this situation.
index c56b950a4128bba39f03c1404a5501476b46cc55..017119eab7a51bf054d7da9d0acacc48514621b5 100644 (file)
@@ -1147,9 +1147,13 @@ static CURLcode single_transfer(struct GlobalConfig *global,
               break;
             }
             if(!*per->outfile && !config->content_disposition) {
-              errorf(global, "Remote filename has no length");
-              result = CURLE_WRITE_ERROR;
-              break;
+              free(per->outfile);
+              per->outfile = strdup("curl_response");
+              if(!per->outfile) {
+                result = CURLE_OUT_OF_MEMORY;
+                break;
+              }
+              warnf(global, "No remote file name, uses \"%s\"", per->outfile);
             }
           }
           else if(state->urls) {
index e2e2d4c3c49f059df4237e385df67e6f701da6c0..8d356d9e4aae7682120fc9ec13f930e9b3329375 100644 (file)
@@ -182,7 +182,7 @@ fail:
  */
 CURLcode get_url_file_name(char **filename, const char *url)
 {
-  const char *pc, *pc2;
+  char *pc, *pc2;
   CURLU *uh = curl_url();
   char *path = NULL;
   CURLUcode uerr;
@@ -195,20 +195,29 @@ CURLcode get_url_file_name(char **filename, const char *url)
   uerr = curl_url_set(uh, CURLUPART_URL, url, CURLU_GUESS_SCHEME);
   if(!uerr) {
     uerr = curl_url_get(uh, CURLUPART_PATH, &path, 0);
+    curl_url_cleanup(uh);
+    uh = NULL;
     if(!uerr) {
-      curl_url_cleanup(uh);
+      int i;
 
-      pc = strrchr(path, '/');
-      pc2 = strrchr(pc ? pc + 1 : path, '\\');
-      if(pc2)
-        pc = pc2;
+      for(i = 0; i < 2; i++) {
+        pc = strrchr(path, '/');
+        pc2 = strrchr(pc ? pc + 1 : path, '\\');
+        if(pc2)
+          pc = pc2;
+        if(pc && !pc[1] && !i) {
+          /* if the path ends with slash, try removing the trailing one
+             and get the last directory part */
+          *pc = 0;
+        }
+      }
 
       if(pc)
         /* duplicate the string beyond the slash */
         pc++;
       else
         /* no slash => empty string */
-        pc = "";
+        pc = (char *)"";
 
       *filename = strdup(pc);
       curl_free(path);
index c5a11f5564ebbc86e7cb073d2ed8b013884548e2..d5ed7af56e95c19260ebf93f798b3f6316ab2056 100644 (file)
@@ -33,7 +33,7 @@ test30 test31 test32 test33 test34 test35 test36 test37 test38 test39   \
 test40 test41 test42 test43 test44 test45 test46 test47 test48 test49   \
 test50 test51 test52 test53 test54 test55 test56 test57 test58 test59   \
 test60 test61 test62 test63 test64 test65 test66 test67 test68 test69   \
-test70 test71 test72 test73 test74 test75 test76 test77 test78 test79   \
+test70 test71 test72 test73 test74 test75        test77 test78 test79   \
 test80 test81 test82 test83 test84 test85 test86 test87 test88 test89   \
 test90 test91 test92 test93 test94 test95 test96 test97 test98 test99   \
 test100 test101 test102 test103 test104 test105 test106 test107 test108 \
@@ -100,7 +100,7 @@ test652 test653 test654 test655 test656 test658 test659 test660 test661 \
 test662 test663 test664 test665 test666 test667 test668 test669 test670 \
 test671 test672 test673 test674 test675 test676 test677 test678 test679 \
 test680 test681 test682 test683 test684 test685 test686 test687 test688 \
-test689 \
+test689 test690 test691 \
 \
 test700 test701 test702 test703 test704 test705 test706 test707 test708 \
 test709 test710 test711 test712 test713 test714 test715 test716 test717 \
@@ -238,7 +238,7 @@ test2000 test2001 test2002 test2003 test2004 \
 \
                                                                test2023 \
 test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
-test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \
+test2032 test2033 test2034 test2035          test2037 test2038 test2039 \
 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \
 test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
 test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
diff --git a/tests/data/test2036 b/tests/data/test2036
deleted file mode 100644 (file)
index 9fd89a2..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<testcase>
-<info>
-<keywords>
-FAILURE
-</keywords>
-</info>
-#
-# Server-side
-<reply>
-</reply>
-
-#
-# Client-side
-<client>
-<server>
-none
-</server>
-<features>
-http
-</features>
-<name>
-HTTP, -O with no slash at all in the URL
-</name>
- <command option="no-output">
-%HOSTIP:%NOLISTENPORT -O
-</command>
-</client>
-
-#
-# Verify data after the test has been "shot"
-<verify>
-<errorcode>
-23
-</errorcode>
-</verify>
-</testcase>
diff --git a/tests/data/test690 b/tests/data/test690
new file mode 100644 (file)
index 0000000..6f33338
--- /dev/null
@@ -0,0 +1,67 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data crlf="yes" nocheck="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+-O with URL without path using trailing slash
+</name>
+<command option="no-output">
+http://%HOSTIP:%HTTPPORT/ -O --output-dir %LOGDIR
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="yes">
+GET / HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file crlf="yes" name="%LOGDIR/curl_response">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test691 b/tests/data/test691
new file mode 100644 (file)
index 0000000..b8a9a08
--- /dev/null
@@ -0,0 +1,67 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data crlf="yes" nocheck="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+-O with URL with path using trailing slash
+</name>
+<command option="no-output">
+http://%HOSTIP:%HTTPPORT/path/to/here/ -O --output-dir %LOGDIR
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="yes">
+GET /path/to/here/ HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file crlf="yes" name="%LOGDIR/here">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test76 b/tests/data/test76
deleted file mode 100644 (file)
index 4c83566..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<testcase>
-<info>
-<keywords>
-FAILURE
-</keywords>
-</info>
-#
-# Server-side
-<reply>
-</reply>
-
-#
-# Client-side
-<client>
-<server>
-none
-</server>
-<features>
-http
-</features>
-<name>
-HTTP, -O with no file name part in the URL
-</name>
- <command option="no-output">
-http://%HOSTIP:%NOLISTENPORT/%TESTNUMBER/ -O
-</command>
-</client>
-
-#
-# Verify data after the test has been "shot"
-<verify>
-<errorcode>
-23
-</errorcode>
-</verify>
-</testcase>