... 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
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.
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) {
*/
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;
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);
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 \
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 \
\
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 \
+++ /dev/null
-<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>
--- /dev/null
+<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>
--- /dev/null
+<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>
+++ /dev/null
-<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>