I did this
Curl parses <scheme>:///path not as an empty authority section followed by a path, but as if the path were an authority.
My understanding (see below for motivation) is that this is correct in the case of the "special schemes" but not for other schemes.
Here's a repro in C, please forgive the machine-written code; I did edit it but I'm not much of a C writer. (Full bot disclaimer, this issue was discovered by me poking at trurl following discussions about the at protocol, not by a robot, but I did use the robot to help me in my investigation):
#include <curl/curl.h>
#include <stdio.h>
static void show(const char *url, unsigned int flags) {
CURLU *u = curl_url();
char *scheme = NULL, *host = NULL, *port = NULL, *path = NULL;
CURLUcode rc;
printf("== %-40s (flags=0x%x)\n", url, flags);
rc = curl_url_set(u, CURLUPART_URL, url, flags);
if (rc) {
printf(" curl_url_set rc=%d (%s)\n", rc, curl_url_strerror(rc));
curl_url_cleanup(u);
printf("\n");
return;
}
curl_url_get(u, CURLUPART_SCHEME, &scheme, 0);
curl_url_get(u, CURLUPART_HOST, &host, CURLU_GET_EMPTY);
curl_url_get(u, CURLUPART_PORT, &port, 0);
curl_url_get(u, CURLUPART_PATH, &path, 0);
printf(" scheme=%s host=\"%s\" port=%s path=%s\n",
scheme ? scheme : "(null)", host ? host : "(null)",
port ? port : "(null)", path ? path : "(null)");
curl_free(scheme);
curl_free(host);
curl_free(port);
curl_free(path);
curl_url_cleanup(u);
printf("\n");
}
int main(void) {
/* unknown scheme, trurl-style flags */
unsigned int f = CURLU_NON_SUPPORT_SCHEME;
printf("--- unknown scheme path is read as authority ---\n");
show("at:///foo", f);
// CURLU_NO_AUTHORITY doesn't change anything here
show("at:///foo", f | CURLU_NO_AUTHORITY);
show(
"at:///did:plc:vwzwgnygau7ed7b7wt5ux7y2/app.bsky.feed.post/3k5nobkf2w72g",
f);
printf("--- HTTP parses the path as an authority ---\n");
show("http:///foo.com/path", 0);
return 0;
}
I expected the following
I believe that per RFC 3986, the authority section for at:///path ought properly to be considered empty, and path to be the path.
- Firefox and the
whatwg url parser tool both parse https:///foo as a hostname foo, which matches curl's behavior
- Firefox and the
whatwg parser both parse at:///foo as an empty hostname followed by the path /foo
- I think this is because the scheme is none of the above, so it does not enter "special authority slashes state"
So my expectation is the following:
- If the scheme of a URL of the form
scheme:///foo is any of {ftp, file, http, https, ws, and wss}
- curl already does the right thing, parsing
foo as a hostname
- Else
- curl ought to parse the URL with an empty hostname and a path of
/foo
Why does this matter?
The at protocol accidentally specified invalid authority names, and they're considering using an empty authority section in their at URLs to remediate the situation.
That's how I noticed this issue - I wondered how trurl would parse the proposed URLs with an empty authority, and found that it parsed them incorrectly; cf the issue I filed there
It seems to be a minor edge case, but one that would be worth fixing. I'd be happy to do the work to submit a PR if you thought it was worth fixing.
curl/libcurl version
verified on curl master branch, revision 6841d59af6
operating system
Mac OS 26.5.1
I did this
Curl parses
<scheme>:///pathnot as an empty authority section followed by a path, but as if the path were an authority.My understanding (see below for motivation) is that this is correct in the case of the "special schemes" but not for other schemes.
Here's a repro in C, please forgive the machine-written code; I did edit it but I'm not much of a C writer. (Full bot disclaimer, this issue was discovered by me poking at
trurlfollowing discussions about theatprotocol, not by a robot, but I did use the robot to help me in my investigation):I expected the following
I believe that per RFC 3986, the authority section for
at:///pathought properly to be considered empty, andpathto be the path.whatwgurl parser tool both parsehttps:///fooas a hostnamefoo, which matches curl's behaviorftp,file,http,https,ws, andwssschemes, and nothing elsewhatwgparser both parseat:///fooas an empty hostname followed by the path/fooSo my expectation is the following:
scheme:///foois any of {ftp,file,http,https,ws, andwss}fooas a hostname/fooWhy does this matter?
The
atprotocol accidentally specified invalid authority names, and they're considering using an empty authority section in theiratURLs to remediate the situation.That's how I noticed this issue - I wondered how
trurlwould parse the proposed URLs with an empty authority, and found that it parsed them incorrectly; cf the issue I filed thereIt seems to be a minor edge case, but one that would be worth fixing. I'd be happy to do the work to submit a PR if you thought it was worth fixing.
curl/libcurl version
verified on curl master branch, revision
6841d59af6operating system
Mac OS 26.5.1