threads / discuss / 47347

imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

Subject: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

## tl;dr

17 messages between Nov 29, 2017 and Dec 18, 2017.

replies: 16people: 9as markdown or json

Doron Behar· Nov 29, 2017, 17:13 UTC · lore
Hi,

I'm trying to send a patch with the command `git imap-send`, I used the examples in the manual page as the main reference for my configuration:

```
[imap]
	folder = "[Gmail]/Drafts"
	host = imaps://imap.gmail.com
	user = doron.behar@gmail.com
	port = 993
	sslverify = false
```
This is my `cat patch.out | git imap-send` output:

``` Password for 'imaps://doron.behar@gmail.com@imap.gmail.com': sending 3 messages curl_easy_perform() failed: URL using bad/illegal format or missing URL ```

The URI doesn't seem OK to me, I tried using `imap.user = doron.behar` and the URI was `imaps://doron.behar@imap.gmail.com` but that ended up with the same error as in the previous case.

I would love to get some help here, a Google Search didn't help as well.
Thanks.
Jonathan Nieder· Nov 30, 2017, 02:04 UTC · re: Doron Behar · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

(+cc: Nicolas) Hi,

Doron Behar wrote:
Show 19 quoted lines
> I'm trying to send a patch with the command `git imap-send`, I used the
> examples in the manual page as the main reference for my configuration:
>
> ```
> [imap]
> 	folder = "[Gmail]/Drafts"
> 	host = imaps://imap.gmail.com
> 	user = doron.behar@gmail.com
> 	port = 993
> 	sslverify = false
> ```
>
> This is my `cat patch.out | git imap-send` output:
>
> ```
> Password for 'imaps://doron.behar@gmail.com@imap.gmail.com':
> sending 3 messages
> curl_easy_perform() failed: URL using bad/illegal format or missing URL
> ```

Thanks for reporting this. I suspect this is related to v2.15.0-rc0~63^2 (imap-send: use curl by default when possible, 2017-09-14) --- e.g. perhaps our custom IMAP code was doing some escaping on the username that libcurl does not do.

"man git imap-send" says this is a recommended configuration, so I don't think it's a configuration error.

What platform are you on?  What version of libcurl are you using?
In libcurl::lib/easy.c I am also seeing
    if(mcode)
      return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
which looks suspicious.
Nicolas, am I on the right track?

Thanks, Jonathan

Show 7 quoted lines
> The URI doesn't seem OK to me, I tried using `imap.user = doron.behar` and the
> URI was `imaps://doron.behar@imap.gmail.com` but that ended up with the same
> error as in the previous case.
>
> I would love to get some help here, a Google Search didn't help as well.
>
> Thanks.
Jeff King· Nov 30, 2017, 03:28 UTC · re: Jonathan Nieder · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

On Wed, Nov 29, 2017 at 06:04:45PM -0800, Jonathan Nieder wrote:
Show 14 quoted lines
> > Password for 'imaps://doron.behar@gmail.com@imap.gmail.com':
> > sending 3 messages
> > curl_easy_perform() failed: URL using bad/illegal format or missing URL
> > ```
> 
> Thanks for reporting this.  I suspect this is related to
> v2.15.0-rc0~63^2 (imap-send: use curl by default when possible,
> 2017-09-14) --- e.g. perhaps our custom IMAP code was doing some
> escaping on the username that libcurl does not do.
> 
> "man git imap-send" says this is a recommended configuration, so I
> don't think it's a configuration error.
> 
> What platform are you on?  What version of libcurl are you using?
All good thoughts/questions. I have two suggestions to add:
 1. As an immediate work-around, running "imap-send --no-curl" may work. 
    That will at least get this case working while we debug.
 2. Setting GIT_TRACE_CURL=1 may dump more verbose information. But one
    caveat: if you get as far as authenticating, then the trace will
    contain your password. We redact HTTP auth from the trace output,
    but not imap ones.
-Peff
Jeff King· Nov 30, 2017, 03:55 UTC · re: Jeff King · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

On Wed, Nov 29, 2017 at 10:28:32PM -0500, Jeff King wrote:
>  2. Setting GIT_TRACE_CURL=1 may dump more verbose information. But one
>     caveat: if you get as far as authenticating, then the trace will
>     contain your password. We redact HTTP auth from the trace output,
>     but not imap ones.

I tried my hand at a patch, but it ended up a lot more complicated than I would have liked. Thoughts?

diff --git a/http.c b/http.c
index 713525f38e..fcc9001af6 100644
--- a/http.c
+++ b/http.c
@@ -560,7 +560,7 @@ static void set_curl_keepalive(CURL *c)
 }
 #endif
 
-static void redact_sensitive_header(struct strbuf *header)
+static void redact_http_header(struct strbuf *header)
 {
 	const char *sensitive_header;
 
@@ -577,7 +577,60 @@ static void redact_sensitive_header(struct strbuf *header)
 	}
 }
 
-static void curl_dump_header(const char *text, unsigned char *ptr, size_t size, int hide_sensitive_header)
+static void redact_imap_header(struct strbuf *header)
+{
+	const char *p;
+
+	/* skip past the command tag */
+	p = strchr(header->buf, ' ');
+	if (!p)
+		return; /* no tag */
+	p++;
+
+	if (skip_prefix(p, "AUTHENTICATE ", &p)) {
+		/* the first token is the auth type, which is OK to log */
+		while (*p && !isspace(*p))
+			p++;
+		/* the rest is an opaque blob; fall through to redact */
+	} else if (skip_prefix(p, "LOGIN ", &p)) {
+		/* fall through to redact both login and password */
+	} else {
+		/* not a sensitive header */
+		return;
+	}
+
+	strbuf_setlen(header, p - header->buf);
+	strbuf_addstr(header, " <redacted>");
+}
+
+static void redact_sensitive_header(CURL *handle, struct strbuf *header)
+{
+	const char *url;
+	int ret;
+
+	ret = curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url);
+	if (!ret && url) {
+		if (starts_with(url, "http")) {
+			redact_http_header(header);
+			return;
+		}
+		if (starts_with(url, "imap")) {
+			redact_imap_header(header);
+			return;
+		}
+	}
+
+	/*
+	 * We weren't able to figure out the protocol. Err on the side of
+	 * redacting too much.
+	 */
+	redact_http_header(header);
+	redact_imap_header(header);
+}
+
+static void curl_dump_header(CURL *handle, const char *text,
+			     unsigned char *ptr, size_t size,
+			     int hide_sensitive_header)
 {
 	struct strbuf out = STRBUF_INIT;
 	struct strbuf **headers, **header;
@@ -591,7 +644,7 @@ static void curl_dump_header(const char *text, unsigned char *ptr, size_t size,
 
 	for (header = headers; *header; header++) {
 		if (hide_sensitive_header)
-			redact_sensitive_header(*header);
+			redact_sensitive_header(handle, *header);
 		strbuf_insert((*header), 0, text, strlen(text));
 		strbuf_insert((*header), strlen(text), ": ", 2);
 		strbuf_rtrim((*header));
@@ -641,7 +694,7 @@ static int curl_trace(CURL *handle, curl_infotype type, char *data, size_t size,
 		break;
 	case CURLINFO_HEADER_OUT:
 		text = "=> Send header";
-		curl_dump_header(text, (unsigned char *)data, size, DO_FILTER);
+		curl_dump_header(handle, text, (unsigned char *)data, size, DO_FILTER);
 		break;
 	case CURLINFO_DATA_OUT:
 		text = "=> Send data";
@@ -653,7 +706,7 @@ static int curl_trace(CURL *handle, curl_infotype type, char *data, size_t size,
 		break;
 	case CURLINFO_HEADER_IN:
 		text = "<= Recv header";
-		curl_dump_header(text, (unsigned char *)data, size, NO_FILTER);
+		curl_dump_header(handle, text, (unsigned char *)data, size, NO_FILTER);
 		break;
 	case CURLINFO_DATA_IN:
 		text = "<= Recv data";
Nicolas Morey-Chaisemartin· Nov 30, 2017, 09:39 UTC · re: Jonathan Nieder · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

Le 30/11/2017 à 03:04, Jonathan Nieder a écrit :
Show 46 quoted lines
> (+cc: Nicolas)
> Hi,
>
> Doron Behar wrote:
>
>> I'm trying to send a patch with the command `git imap-send`, I used the
>> examples in the manual page as the main reference for my configuration:
>>
>> ```
>> [imap]
>> 	folder = "[Gmail]/Drafts"
>> 	host = imaps://imap.gmail.com
>> 	user = doron.behar@gmail.com
>> 	port = 993
>> 	sslverify = false
>> ```
>>
>> This is my `cat patch.out | git imap-send` output:
>>
>> ```
>> Password for 'imaps://doron.behar@gmail.com@imap.gmail.com':
>> sending 3 messages
>> curl_easy_perform() failed: URL using bad/illegal format or missing URL
>> ```
> Thanks for reporting this.  I suspect this is related to
> v2.15.0-rc0~63^2 (imap-send: use curl by default when possible,
> 2017-09-14) --- e.g. perhaps our custom IMAP code was doing some
> escaping on the username that libcurl does not do.
>
> "man git imap-send" says this is a recommended configuration, so I
> don't think it's a configuration error.
>
> What platform are you on?  What version of libcurl are you using?
>
> In libcurl::lib/easy.c I am also seeing
>
>     if(mcode)
>       return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
>
> which looks suspicious.
>
> Nicolas, am I on the right track?
>
> Thanks,
> Jonathan
>
This is due to the weird "[Gmail]" prefix in the folder.
I tried manually replacing it with:
        folder = %5BGmail%5D/Drafts
in .git/config and it works.

curl is doing some fancy handling with brackets and braces. It make sense for multiple FTP downloads like ftp://ftp.numericals.com/file[1-100].txt, not in our case. The curl command line has a --globoff argument to disable this "regexp" support and it seems to fix the gmail case. However I couldn't find a way to change this value through the API...

I guess we should open a bug upstream to get access to this setting through the API and add a patch that HTTP encode brackets and braces in the meantime.
Nicolas
Nicolas Morey-Chaisemartin· Nov 30, 2017, 09:47 UTC · re: Nicolas Morey-Chaisemartin · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

Le 30/11/2017 à 10:39, Nicolas Morey-Chaisemartin a écrit :
Show 55 quoted lines
>
> Le 30/11/2017 à 03:04, Jonathan Nieder a écrit :
>> (+cc: Nicolas)
>> Hi,
>>
>> Doron Behar wrote:
>>
>>> I'm trying to send a patch with the command `git imap-send`, I used the
>>> examples in the manual page as the main reference for my configuration:
>>>
>>> ```
>>> [imap]
>>> 	folder = "[Gmail]/Drafts"
>>> 	host = imaps://imap.gmail.com
>>> 	user = doron.behar@gmail.com
>>> 	port = 993
>>> 	sslverify = false
>>> ```
>>>
>>> This is my `cat patch.out | git imap-send` output:
>>>
>>> ```
>>> Password for 'imaps://doron.behar@gmail.com@imap.gmail.com':
>>> sending 3 messages
>>> curl_easy_perform() failed: URL using bad/illegal format or missing URL
>>> ```
>> Thanks for reporting this.  I suspect this is related to
>> v2.15.0-rc0~63^2 (imap-send: use curl by default when possible,
>> 2017-09-14) --- e.g. perhaps our custom IMAP code was doing some
>> escaping on the username that libcurl does not do.
>>
>> "man git imap-send" says this is a recommended configuration, so I
>> don't think it's a configuration error.
>>
>> What platform are you on?  What version of libcurl are you using?
>>
>> In libcurl::lib/easy.c I am also seeing
>>
>>     if(mcode)
>>       return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
>>
>> which looks suspicious.
>>
>> Nicolas, am I on the right track?
>>
>> Thanks,
>> Jonathan
>>
> This is due to the weird "[Gmail]" prefix in the folder.
> I tried manually replacing it with:
>         folder = %5BGmail%5D/Drafts
> in .git/config and it works.
>
> curl is doing some fancy handling with brackets and braces. It make sense for multiple FTP downloads like ftp://ftp.numericals.com/file[1-100].txt, not in our case.
> The curl command line has a --globoff argument to disable this "regexp" support and it seems to fix the gmail case.
In fact no, StackOverflow was wrong :)
> However I couldn't find a way to change this value through the API...
>
> I guess we should open a bug upstream to get access to this setting through the API and add a patch that HTTP encode brackets and braces in the meantime.
>
This means with have to URI encode the folder. DO we have a helper for that ?
Nicolas
Daniel Stenberg· Nov 30, 2017, 09:46 UTC · re: Nicolas Morey-Chaisemartin · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

On Thu, 30 Nov 2017, Nicolas Morey-Chaisemartin wrote:
Show 10 quoted lines
> This is due to the weird "[Gmail]" prefix in the folder.
> I tried manually replacing it with:
>         folder = %5BGmail%5D/Drafts
> in .git/config and it works.
>
> curl is doing some fancy handling with brackets and braces. It make sense 
> for multiple FTP downloads like ftp://ftp.numericals.com/file[1-100].txt, 
> not in our case. The curl command line has a --globoff argument to disable 
> this "regexp" support and it seems to fix the gmail case. However I couldn't 
> find a way to change this value through the API...

That's just a feature of the command line tool, "globbing" isn't a function provided by the library. libcurl actually "just" expects a plain old URL.

But with the risk of falling through the cracks into the rathole that is "what is a URL" (I've blogged about the topic several times in the past and I will surely do it again in the future):

A "legal" URL (as per RFC 3986) does not contain brackets, such symbols should be used URL encoded: %5B and %5D.

This said: I don't know exactly why brackets cause a problem in this case. It could still be worth digging into and see if libcurl could deal with them better here...

-- 
  / daniel.haxx.se
Nicolas Morey-Chaisemartin· Nov 30, 2017, 09:51 UTC · re: Daniel Stenberg · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

Le 30/11/2017 à 10:46, Daniel Stenberg a écrit :
Show 11 quoted lines
> On Thu, 30 Nov 2017, Nicolas Morey-Chaisemartin wrote:
>
>> This is due to the weird "[Gmail]" prefix in the folder.
>> I tried manually replacing it with:
>>         folder = %5BGmail%5D/Drafts
>> in .git/config and it works.
>>
>> curl is doing some fancy handling with brackets and braces. It make sense for multiple FTP downloads like ftp://ftp.numericals.com/file[1-100].txt, not in our case. The curl command line has a --globoff argument to disable this "regexp" support and it seems to fix the gmail case. However I couldn't find a way to change this value through the API...
>
> That's just a feature of the command line tool, "globbing" isn't a function provided by the library. libcurl actually "just" expects a plain old URL.
>
Yep that what I figured looking a bit further in the code.
Show 6 quoted lines
> But with the risk of falling through the cracks into the rathole that is "what is a URL" (I've blogged about the topic several times in the past and I will surely do it again in the future):
>
> A "legal" URL (as per RFC 3986) does not contain brackets, such symbols should be used URL encoded: %5B and %5D.
>
> This said: I don't know exactly why brackets cause a problem in this case. It could still be worth digging into and see if libcurl could deal with them better here...
>

It would make sense to have a way to ask libcurl to URI encode for us. I'm guessing there's already the code for that somewhere in curl and we would be wise to use it. But to work wqith older version we'll have to do it ourselves anyway.

Nicolas
Daniel Stenberg· Nov 30, 2017, 09:55 UTC · re: Nicolas Morey-Chaisemartin · lore

Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL

On Thu, 30 Nov 2017, Nicolas Morey-Chaisemartin wrote:
> It would make sense to have a way to ask libcurl to URI encode for us. I'm 
> guessing there's already the code for that somewhere in curl and we would be 
> wise to use it. But to work wqith older version we'll have to do it 
> ourselves anyway.
libcurl only offers curl_easy_escape() which URL encodes a string.

But that's not really usably on an entire existing URL or path since it would then also encode the slashes etc. You want to encode the relevant pieces and then put them together appropriately into the final URL...

-- 
  / daniel.haxx.se
Nicolas Morey-Chaisemartin· Nov 30, 2017, 10:07 UTC · re: Doron Behar · lore

[PATCH] imap-send: URI encode server folder

URI encode the server folder string before passing it to libcurl. This fixes the access to the draft folder on Gmail accounts (named [Gmail]/Drafts)

Reported-by: Doron Behar <doron.behar@gmail.com>
Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
---
 imap-send.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/imap-send.c b/imap-send.c
index 54e6a80fd..36c7c1b4f 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1412,6 +1412,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
 {
 	CURL *curl;
 	struct strbuf path = STRBUF_INIT;
+	char *uri_encoded_folder;
 
 	if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
 		die("curl_global_init failed");
@@ -1429,7 +1430,12 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
 	strbuf_addstr(&path, server.host);
 	if (!path.len || path.buf[path.len - 1] != '/')
 		strbuf_addch(&path, '/');
-	strbuf_addstr(&path, server.folder);
+
+	uri_encoded_folder = curl_easy_escape(curl, server.folder, 0);
+	if (!uri_encoded_folder)
+		die("failed to encode server folder");
+	strbuf_addstr(&path, uri_encoded_folder);
+	curl_free(uri_encoded_folder);
 
 	curl_easy_setopt(curl, CURLOPT_URL, path.buf);
 	strbuf_release(&path);
-- 
2.15.1.272.g8e603414b
Eric Sunshine· Nov 30, 2017, 17:53 UTC · re: Nicolas Morey-Chaisemartin · lore

Re: [PATCH] imap-send: URI encode server folder

On Thu, Nov 30, 2017 at 5:07 AM, Nicolas Morey-Chaisemartin <nmoreychaisemartin@suse.com> wrote:

> URI encode the server folder string before passing it to libcurl.
> This fixes the access to the draft folder on Gmail accounts (named [Gmail]/Drafts)

For someone reading this commit message in the future -- someone who didn't follow the email thread which led to this patch -- "this fixes" doesn't say much about the actual problem being addressed. Can you expand the commit message a bit to make it more self-contained? At minimum, perhaps show the error message you were experiencing, and cite (as Daniel pointed out) RFC 3986 and the bit about a "legal" URL not containing brackets.

Also, a natural question which pops into the head of someone reading this patch is whether other parts of the URL (host, user, etc.) also need to be handled similarly. It's possible that you audited the code and determined that they are handled fine already, but the reader of the commit message is unable to infer that. Consequently, it might be nice to have a sentence about that, as well ("other parts of the URL are already encoded, thus are fine" or "other parts of the URL are not subject to this problem because ...").

The patch itself looks okay (from a cursory read).
Thanks.
Show 34 quoted lines
> Reported-by: Doron Behar <doron.behar@gmail.com>
> Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
> ---
>  imap-send.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/imap-send.c b/imap-send.c
> index 54e6a80fd..36c7c1b4f 100644
> --- a/imap-send.c
> +++ b/imap-send.c
> @@ -1412,6 +1412,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
>  {
>         CURL *curl;
>         struct strbuf path = STRBUF_INIT;
> +       char *uri_encoded_folder;
>
>         if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
>                 die("curl_global_init failed");
> @@ -1429,7 +1430,12 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
>         strbuf_addstr(&path, server.host);
>         if (!path.len || path.buf[path.len - 1] != '/')
>                 strbuf_addch(&path, '/');
> -       strbuf_addstr(&path, server.folder);
> +
> +       uri_encoded_folder = curl_easy_escape(curl, server.folder, 0);
> +       if (!uri_encoded_folder)
> +               die("failed to encode server folder");
> +       strbuf_addstr(&path, uri_encoded_folder);
> +       curl_free(uri_encoded_folder);
>
>         curl_easy_setopt(curl, CURLOPT_URL, path.buf);
>         strbuf_release(&path);
> --
> 2.15.1.272.g8e603414b
Junio C Hamano· Dec 5, 2017, 15:30 UTC · re: Eric Sunshine · lore

Re: [PATCH] imap-send: URI encode server folder

Eric Sunshine <sunshine@sunshineco.com> writes:
Show 5 quoted lines
> ... Can you
> expand the commit message a bit to make it more self-contained? At
> minimum, perhaps show the error message you were experiencing, and
> cite (as Daniel pointed out) RFC 3986 and the bit about a "legal" URL
> not containing brackets.
Thanks for a good suggestion.
Show 48 quoted lines
>
> Also, a natural question which pops into the head of someone reading
> this patch is whether other parts of the URL (host, user, etc.) also
> need to be handled similarly. It's possible that you audited the code
> and determined that they are handled fine already, but the reader of
> the commit message is unable to infer that. Consequently, it might be
> nice to have a sentence about that, as well ("other parts of the URL
> are already encoded, thus are fine" or "other parts of the URL are not
> subject to this problem because ...").
>
> The patch itself looks okay (from a cursory read).
>
> Thanks.
>
>> Reported-by: Doron Behar <doron.behar@gmail.com>
>> Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
>> ---
>>  imap-send.c | 8 +++++++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/imap-send.c b/imap-send.c
>> index 54e6a80fd..36c7c1b4f 100644
>> --- a/imap-send.c
>> +++ b/imap-send.c
>> @@ -1412,6 +1412,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
>>  {
>>         CURL *curl;
>>         struct strbuf path = STRBUF_INIT;
>> +       char *uri_encoded_folder;
>>
>>         if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
>>                 die("curl_global_init failed");
>> @@ -1429,7 +1430,12 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
>>         strbuf_addstr(&path, server.host);
>>         if (!path.len || path.buf[path.len - 1] != '/')
>>                 strbuf_addch(&path, '/');
>> -       strbuf_addstr(&path, server.folder);
>> +
>> +       uri_encoded_folder = curl_easy_escape(curl, server.folder, 0);
>> +       if (!uri_encoded_folder)
>> +               die("failed to encode server folder");
>> +       strbuf_addstr(&path, uri_encoded_folder);
>> +       curl_free(uri_encoded_folder);
>>
>>         curl_easy_setopt(curl, CURLOPT_URL, path.buf);
>>         strbuf_release(&path);
>> --
>> 2.15.1.272.g8e603414b
Kaartic Sivaraam· Dec 18, 2017, 18:25 UTC · re: Eric Sunshine · lore

[PATCH v2] imap-send: URI encode server folder

From: Nicolas Morey-Chaisemartin <nmoreychaisemartin@suse.com>

When trying to send a patch using 'imap-send' with 'curl' and the following configuration:

[imap]
	folder = "[Gmail]/Drafts"
	host = imaps://imap.gmail.com
	port = 993
	sslverify = false
resulted in the following error,
    curl_easy_perform() failed: URL using bad/illegal format or missing URL

That was a consequence of the not URI encoding the folder portion of the URL which contained characters such as '[' which are not allowed in a URI. According to RFC3986, these characters should be "URI encoded".

So, URI encode the folder portion of the URL to ensure it doesn't contain characters that aren't allowed in a URI.

Reported-by: Doron Behar <doron.behar@gmail.com>
Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
---

I came across the same issue that lead to this patch recently and found that this patch didn't make it in. So, I thought I could help out and hence this v2.

Eric Sunshine <sunshine@sunshineco.com> writes:
Show 7 quoted lines
> For someone reading this commit message in the future -- someone who
> didn't follow the email thread which led to this patch -- "this fixes"
> doesn't say much about the actual problem being addressed. Can you
> expand the commit message a bit to make it more self-contained? At
> minimum, perhaps show the error message you were experiencing, and
> cite (as Daniel pointed out) RFC 3986 and the bit about a "legal" URL
> not containing brackets.
I guess I covered this part.
Show 8 quoted lines
> Also, a natural question which pops into the head of someone reading
> this patch is whether other parts of the URL (host, user, etc.) also
> need to be handled similarly. It's possible that you audited the code
> and determined that they are handled fine already, but the reader of
> the commit message is unable to infer that. Consequently, it might be
> nice to have a sentence about that, as well ("other parts of the URL
> are already encoded, thus are fine" or "other parts of the URL are not
> subject to this problem because ...").

I'm not sure about this one. I guess the host and user don't need encoding as I suspect they wouldn't contain characters that aren't allowed. I might be wrong, though. Let me know if I'm missing something.

Thanks, Kaartic

 imap-send.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/imap-send.c b/imap-send.c
index 54e6a80fd..36c7c1b4f 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1412,6 +1412,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
 {
 	CURL *curl;
 	struct strbuf path = STRBUF_INIT;
+	char *uri_encoded_folder;
 
 	if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
 		die("curl_global_init failed");
@@ -1429,7 +1430,12 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
 	strbuf_addstr(&path, server.host);
 	if (!path.len || path.buf[path.len - 1] != '/')
 		strbuf_addch(&path, '/');
-	strbuf_addstr(&path, server.folder);
+
+	uri_encoded_folder = curl_easy_escape(curl, server.folder, 0);
+	if (!uri_encoded_folder)
+		die("failed to encode server folder");
+	strbuf_addstr(&path, uri_encoded_folder);
+	curl_free(uri_encoded_folder);
 
 	curl_easy_setopt(curl, CURLOPT_URL, path.buf);
 	strbuf_release(&path);
-- 
2.15.1.620.gb9897f467
Eric Sunshine· Dec 18, 2017, 18:48 UTC · re: Kaartic Sivaraam · lore

Re: [PATCH v2] imap-send: URI encode server folder

On Mon, Dec 18, 2017 at 1:25 PM, Kaartic Sivaraam <kaartic.sivaraam@gmail.com> wrote:

> From: Nicolas Morey-Chaisemartin <nmoreychaisemartin@suse.com>
> [...]
> resulted in the following error,
s/resulted/results/
>     curl_easy_perform() failed: URL using bad/illegal format or missing URL
>
> That was a consequence of the not URI encoding the folder portion of

s/That was/This is/ s/the not/not/ s/URI encoding/URI-encoding/

> the URL which contained characters such as '[' which are not
s/contained/contains/
Show 13 quoted lines
> allowed in a URI. According to RFC3986, these characters should be
> "URI encoded".
>
> So, URI encode the folder portion of the URL to ensure it doesn't
> contain characters that aren't allowed in a URI.
>
> Reported-by: Doron Behar <doron.behar@gmail.com>
> Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
> ---
>
> I came across the same issue that lead to this patch recently and found
> that this patch didn't make it in. So, I thought I could help out and
> hence this v2.
Thanks for taking up the slack.
Kaartic Sivaraam· Dec 18, 2017, 19:11 UTC · re: Eric Sunshine · lore

[PATCH v3] imap-send: URI encode server folder

From: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>

When trying to send a patch using 'imap-send' with 'curl' and the following configuration:

[imap]
	folder = "[Gmail]/Drafts"
	host = imaps://imap.gmail.com
	port = 993
	sslverify = false
results in the following error,
    curl_easy_perform() failed: URL using bad/illegal format or missing URL

This is a consequence of not URI-encoding the folder portion of the URL which contains characters such as '[' which are not allowed in a URI. According to RFC3986, these characters should be URI-encoded.

So, URI-encode the folder before adding it to the URI to ensure it doesn't contain characters that aren't allowed in a URI.

Reported-by: Doron Behar <doron.behar@gmail.com>
Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
Signed-off-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
---
Changes in v3:
    - updated commit message as suggested by Eric (convert past tense
      to present tense) and added a few tweaks to it that striked me
Eric Sunshine <sunshine@sunshineco.com> writes:
> Thanks for taking up the slack.

You're welcome. It was easier than waiting for this patch to be updated so it could get into 'pu' ;-)

 imap-send.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/imap-send.c b/imap-send.c
index 54e6a80fd..36c7c1b4f 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1412,6 +1412,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
 {
 	CURL *curl;
 	struct strbuf path = STRBUF_INIT;
+	char *uri_encoded_folder;
 
 	if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
 		die("curl_global_init failed");
@@ -1429,7 +1430,12 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
 	strbuf_addstr(&path, server.host);
 	if (!path.len || path.buf[path.len - 1] != '/')
 		strbuf_addch(&path, '/');
-	strbuf_addstr(&path, server.folder);
+
+	uri_encoded_folder = curl_easy_escape(curl, server.folder, 0);
+	if (!uri_encoded_folder)
+		die("failed to encode server folder");
+	strbuf_addstr(&path, uri_encoded_folder);
+	curl_free(uri_encoded_folder);
 
 	curl_easy_setopt(curl, CURLOPT_URL, path.buf);
 	strbuf_release(&path);
-- 
2.15.1.620.gb9897f467
Jonathan Nieder· Dec 18, 2017, 22:19 UTC · re: Kaartic Sivaraam · lore

Re: [PATCH v3] imap-send: URI encode server folder

Kaartic Sivaraam wrote:
Show 29 quoted lines
> From: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
>
> When trying to send a patch using 'imap-send' with 'curl' and the
> following configuration:
>
> [imap]
> 	folder = "[Gmail]/Drafts"
> 	host = imaps://imap.gmail.com
> 	port = 993
> 	sslverify = false
>
> results in the following error,
>
>     curl_easy_perform() failed: URL using bad/illegal format or missing URL
>
> This is a consequence of not URI-encoding the folder portion of
> the URL which contains characters such as '[' which are not
> allowed in a URI. According to RFC3986, these characters should be
> URI-encoded.
>
> So, URI-encode the folder before adding it to the URI to ensure it doesn't
> contain characters that aren't allowed in a URI.
>
> Reported-by: Doron Behar <doron.behar@gmail.com>
> Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
> Signed-off-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
> ---
>  imap-send.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
Thanks!
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>

Is there a straightforward way to check that this behavior gets preserved in tests?

Sincerely, Jonathan

Junio C Hamano· Dec 18, 2017, 22:32 UTC · re: Kaartic Sivaraam · lore

Re: [PATCH v3] imap-send: URI encode server folder

Kaartic Sivaraam <kaartic.sivaraam@gmail.com> writes:
Show 36 quoted lines
> From: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
>
> When trying to send a patch using 'imap-send' with 'curl' and the
> following configuration:
>
> [imap]
> 	folder = "[Gmail]/Drafts"
> 	host = imaps://imap.gmail.com
> 	port = 993
> 	sslverify = false
>
> results in the following error,
>
>     curl_easy_perform() failed: URL using bad/illegal format or missing URL
>
> This is a consequence of not URI-encoding the folder portion of
> the URL which contains characters such as '[' which are not
> allowed in a URI. According to RFC3986, these characters should be
> URI-encoded.
>
> So, URI-encode the folder before adding it to the URI to ensure it doesn't
> contain characters that aren't allowed in a URI.
>
> Reported-by: Doron Behar <doron.behar@gmail.com>
> Signed-off-by: Nicolas Morey-Chaisemartin <NMoreyChaisemartin@suse.com>
> Signed-off-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
> ---
> Changes in v3:
>     - updated commit message as suggested by Eric (convert past tense
>       to present tense) and added a few tweaks to it that striked me
>
> Eric Sunshine <sunshine@sunshineco.com> writes:
>> Thanks for taking up the slack.
>
> You're welcome. It was easier than waiting for this patch to be
> updated so it could get into 'pu' ;-)
Looks good.  Thanks.
Show 29 quoted lines
>  imap-send.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/imap-send.c b/imap-send.c
> index 54e6a80fd..36c7c1b4f 100644
> --- a/imap-send.c
> +++ b/imap-send.c
> @@ -1412,6 +1412,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
>  {
>  	CURL *curl;
>  	struct strbuf path = STRBUF_INIT;
> +	char *uri_encoded_folder;
>  
>  	if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
>  		die("curl_global_init failed");
> @@ -1429,7 +1430,12 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
>  	strbuf_addstr(&path, server.host);
>  	if (!path.len || path.buf[path.len - 1] != '/')
>  		strbuf_addch(&path, '/');
> -	strbuf_addstr(&path, server.folder);
> +
> +	uri_encoded_folder = curl_easy_escape(curl, server.folder, 0);
> +	if (!uri_encoded_folder)
> +		die("failed to encode server folder");
> +	strbuf_addstr(&path, uri_encoded_folder);
> +	curl_free(uri_encoded_folder);
>  
>  	curl_easy_setopt(curl, CURLOPT_URL, path.buf);
>  	strbuf_release(&path);

← back to recent threads