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

17 messages from 2017-11-29 to 2017-12-18. Participants: Doron Behar, Jonathan Nieder, Jeff King, Nicolas Morey-Chaisemartin, Daniel Stenberg, Eric Sunshine, Junio C Hamano, Kaartic Sivaraam.
Thread: https://gitlist.dev/t/47347

## Doron Behar, 2017-11-29 17:13

Subject: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <20171129171301.l3coiflkfyy533yz@NUC.localdomain>
URL: https://gitlist.dev/e/20171129171301.l3coiflkfyy533yz%40NUC.localdomain

```
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, 2017-11-30 02:04

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <20171130020445.GF15098@aiede.mtv.corp.google.com>
URL: https://gitlist.dev/e/20171130020445.GF15098%40aiede.mtv.corp.google.com
In-Reply-To: <20171129171301.l3coiflkfyy533yz@NUC.localdomain>

```
(+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

> 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, 2017-11-30 03:28

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <20171130032832.GA25577@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20171130032832.GA25577%40sigill.intra.peff.net
In-Reply-To: <20171130020445.GF15098@aiede.mtv.corp.google.com>

```
On Wed, Nov 29, 2017 at 06:04:45PM -0800, Jonathan Nieder wrote:

> > 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, 2017-11-30 03:55

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <20171130035527.GB25577@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20171130035527.GB25577%40sigill.intra.peff.net
In-Reply-To: <20171130032832.GA25577@sigill.intra.peff.net>

```
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, 2017-11-30 09:39

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <50fb321e-bbfc-adae-992d-eea1b818171e@suse.de>
URL: https://gitlist.dev/e/50fb321e-bbfc-adae-992d-eea1b818171e%40suse.de
In-Reply-To: <20171130020445.GF15098@aiede.mtv.corp.google.com>

```


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.
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, 2017-11-30 09:47

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <6b1b1c11-cf17-35e8-1d33-42102d9526ea@suse.de>
URL: https://gitlist.dev/e/6b1b1c11-cf17-35e8-1d33-42102d9526ea%40suse.de
In-Reply-To: <50fb321e-bbfc-adae-992d-eea1b818171e@suse.de>

```


Le 30/11/2017 à 10:39, Nicolas Morey-Chaisemartin a écrit :
>
> 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, 2017-11-30 09:46

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <alpine.DEB.2.20.1711301041250.30591@tvnag.unkk.fr>
URL: https://gitlist.dev/e/alpine.DEB.2.20.1711301041250.30591%40tvnag.unkk.fr
In-Reply-To: <50fb321e-bbfc-adae-992d-eea1b818171e@suse.de>

```
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.

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
```

## Daniel Stenberg, 2017-11-30 09:55

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <alpine.DEB.2.20.1711301052350.30591@tvnag.unkk.fr>
URL: https://gitlist.dev/e/alpine.DEB.2.20.1711301052350.30591%40tvnag.unkk.fr
In-Reply-To: <44bbb765-fb0d-5b80-c697-76a9b6ff0811@morey-chaisemartin.com>

```
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, 2017-11-30 09:51

Subject: Re: imap-send with gmail: curl_easy_perform() failed: URL using bad/illegal format or missing URL
Message-ID: <44bbb765-fb0d-5b80-c697-76a9b6ff0811@morey-chaisemartin.com>
URL: https://gitlist.dev/e/44bbb765-fb0d-5b80-c697-76a9b6ff0811%40morey-chaisemartin.com
In-Reply-To: <alpine.DEB.2.20.1711301041250.30591@tvnag.unkk.fr>

```


Le 30/11/2017 à 10:46, Daniel Stenberg a écrit :
> 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.

> 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

```

## Nicolas Morey-Chaisemartin, 2017-11-30 10:07

Subject: [PATCH] imap-send: URI encode server folder
Message-ID: <18c9478b-19fc-69f2-229f-67c05a42d4f5@suse.com>
URL: https://gitlist.dev/e/18c9478b-19fc-69f2-229f-67c05a42d4f5%40suse.com
In-Reply-To: <20171129171301.l3coiflkfyy533yz@NUC.localdomain>

```
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, 2017-11-30 17:53

Subject: Re: [PATCH] imap-send: URI encode server folder
Message-ID: <CAPig+cSEYHfupRt+-0sZK6H3_WcT_=wdNB2FfdYuB6geGQYZ3A@mail.gmail.com>
URL: https://gitlist.dev/e/CAPig%2BcSEYHfupRt%2B-0sZK6H3_WcT_%3DwdNB2FfdYuB6geGQYZ3A%40mail.gmail.com
In-Reply-To: <18c9478b-19fc-69f2-229f-67c05a42d4f5@suse.com>

```
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.

> 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, 2017-12-05 15:30

Subject: Re: [PATCH] imap-send: URI encode server folder
Message-ID: <xmqqd13tjioz.fsf@gitster.mtv.corp.google.com>
URL: https://gitlist.dev/e/xmqqd13tjioz.fsf%40gitster.mtv.corp.google.com
In-Reply-To: <CAPig+cSEYHfupRt+-0sZK6H3_WcT_=wdNB2FfdYuB6geGQYZ3A@mail.gmail.com>

```
Eric Sunshine <sunshine@sunshineco.com> writes:

> ... 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.


>
> 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, 2017-12-18 18:25

Subject: [PATCH v2] imap-send: URI encode server folder
Message-ID: <20171218182546.9962-1-kaartic.sivaraam@gmail.com>
URL: https://gitlist.dev/e/20171218182546.9962-1-kaartic.sivaraam%40gmail.com
In-Reply-To: <CAPig+cSEYHfupRt+-0sZK6H3_WcT_=wdNB2FfdYuB6geGQYZ3A@mail.gmail.com>

```
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:
> 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.


> 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, 2017-12-18 18:48

Subject: Re: [PATCH v2] imap-send: URI encode server folder
Message-ID: <CAPig+cSOn8PV52aL0Ky5uUwFfNMWye93UQGioRiXjj0ze9HX+g@mail.gmail.com>
URL: https://gitlist.dev/e/CAPig%2BcSOn8PV52aL0Ky5uUwFfNMWye93UQGioRiXjj0ze9HX%2Bg%40mail.gmail.com
In-Reply-To: <20171218182546.9962-1-kaartic.sivaraam@gmail.com>

```
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/

> 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, 2017-12-18 19:11

Subject: [PATCH v3] imap-send: URI encode server folder
Message-ID: <20171218191113.18600-1-kaartic.sivaraam@gmail.com>
URL: https://gitlist.dev/e/20171218191113.18600-1-kaartic.sivaraam%40gmail.com
In-Reply-To: <CAPig+cSOn8PV52aL0Ky5uUwFfNMWye93UQGioRiXjj0ze9HX+g@mail.gmail.com>

```
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, 2017-12-18 22:19

Subject: Re: [PATCH v3] imap-send: URI encode server folder
Message-ID: <20171218221945.GC7854@aiede.mtv.corp.google.com>
URL: https://gitlist.dev/e/20171218221945.GC7854%40aiede.mtv.corp.google.com
In-Reply-To: <20171218191113.18600-1-kaartic.sivaraam@gmail.com>

```
Kaartic Sivaraam wrote:

> 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, 2017-12-18 22:32

Subject: Re: [PATCH v3] imap-send: URI encode server folder
Message-ID: <xmqq7etjy8ej.fsf@gitster.mtv.corp.google.com>
URL: https://gitlist.dev/e/xmqq7etjy8ej.fsf%40gitster.mtv.corp.google.com
In-Reply-To: <20171218191113.18600-1-kaartic.sivaraam@gmail.com>

```
Kaartic Sivaraam <kaartic.sivaraam@gmail.com> writes:

> 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.


>  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);

```
