git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC 3/3] imap_send: add support for curl over tunnel

From
Nicolas Morey-Chaisemartin <nicolas@morey-chaisemartin.com>
Date
Aug 9, 2017, 14:46 UTC
Message-ID
<3f49822c-2766-1904-4449-716dadec958f@morey-chaisemartin.com>
In-Reply-To
<ab866314-608b-eaca-b335-12cffe165526@morey-chaisemartin.com>

Starting from libcurl 7.21.5, libcurl can be tricked into using an already open socket. This allows to use tunneling with libcurl instead of the legacy imap code.

Signed-off-by: Nicolas Morey-Chaisemartin <nicolas@morey-chaisemartin.com>
---
 Documentation/git-imap-send.txt |  4 ++--
 imap-send.c                     | 45 +++++++++++++++++++++++++++++++++++------
 2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 5d1e4c80c..e765c08d7 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -38,8 +38,8 @@ OPTIONS
 	Be quiet.
 
 --curl::
-	Use libcurl to communicate with the IMAP server, unless tunneling
-	into it.  Ignored if Git was built without the USE_CURL_FOR_IMAP_SEND
+	Use libcurl to communicate with the IMAP server.
+	Ignored if Git was built without the USE_CURL_FOR_IMAP_SEND
 	option set.
 
 --no-curl::
diff --git a/imap-send.c b/imap-send.c
index e5ff70096..31b93d873 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1408,6 +1408,26 @@ static int append_msgs_to_imap(struct imap_server_conf *server,
 }
 
 #ifdef USE_CURL_FOR_IMAP_SEND
+static curl_socket_t curl_tunnel_socket(void *clientp,
+					curlsocktype purpose,
+					struct curl_sockaddr *address)
+{
+	return (unsigned long)clientp;
+}
+
+static int sockopt_callback(void *clientp, curl_socket_t curlfd,
+				 curlsocktype purpose)
+{
+	/* CURL_SOCKOPT_ALREADY_CONNECTED was intreocued in 7.21.5
+	 * and is needed to get curl working on an existing fd */
+#if LIBCURL_VERSION_NUM >= 0x071505
+	return CURL_SOCKOPT_ALREADY_CONNECTED;
+#else
+	return CURL_SOCKOPT_ERROR;
+#endif
+}
+
+
 static CURL *setup_curl(struct imap_server_conf *srvc)
 {
 	CURL *curl;
@@ -1424,8 +1444,21 @@ static CURL *setup_curl(struct imap_server_conf *srvc)
 	curl_easy_setopt(curl, CURLOPT_USERNAME, server.user);
 	curl_easy_setopt(curl, CURLOPT_PASSWORD, server.pass);
 
-	strbuf_addstr(&path, server.use_ssl ? "imaps://" : "imap://");
-	strbuf_addstr(&path, server.host);
+	if (srvc->tunnel) {
+		int fds[2];
+
+		setup_tunnel(srvc, fds);
+		curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, curl_tunnel_socket);
+		curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, (unsigned long)fds[0]);
+		curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
+		/* Create a fake hostname to avoid resolution issue and in case
+		 * imap.host was not set */
+		strbuf_addstr(&path, "imap://localhost");
+	} else {
+		strbuf_addstr(&path, server.use_ssl ? "imaps://" : "imap://");
+		strbuf_addstr(&path, server.host);
+	}
+
 	if (!path.len || path.buf[path.len - 1] != '/')
 		strbuf_addch(&path, '/');
 	strbuf_addstr(&path, server.folder);
@@ -1570,12 +1603,12 @@ int cmd_main(int argc, const char **argv)
 
 	/* write it to the imap server */
 
-	if (server.tunnel)
-		return append_msgs_to_imap(&server, &all_msgs, total);
-
 #ifdef USE_CURL_FOR_IMAP_SEND
 	if (use_curl)
-		return curl_append_msgs_to_imap(&server, &all_msgs, total);
+#if LIBCURL_VERSION_NUM < 0x071505
+		if (!server.tunnel)
+#endif
+			return curl_append_msgs_to_imap(&server, &all_msgs, total);
 #endif
 
 	return append_msgs_to_imap(&server, &all_msgs, total);
-- 
2.14.0.3.gb4ff627ec.dirty
Previous: Nicolas Morey-ChaisemartinNext: Nicolas Morey-Chaisemartin
Message 3 of 22 in “[RFC 0/3] imap-send curl tunnelling support”
  1. Nicolas Morey-ChaisemartinAug 9, 2017
  2. 1/3 imap-send: move tunnel setup to its own functionNicolas Morey-Chaisemartin, Aug 9, 2017
  3. 3/3 imap_send: add support for curl over tunnelNicolas Morey-Chaisemartin, Aug 9, 2017
  4. 2/3 imap-send: use a socketpair instead of pipe to communicate with the tunnelNicolas Morey-Chaisemartin, Aug 9, 2017
  5. Nicolas Morey-ChaisemartinAug 15, 2017
  6. Stefan BellerAug 15, 2017
  7. Johannes SchindelinAug 16, 2017
  8. Nicolas Morey-ChaisemartinAug 21, 2017
  9. Johannes SixtAug 22, 2017
  10. Nicolas Morey-ChaisemartinAug 22, 2017
  11. Johannes SchindelinAug 23, 2017
  12. Jeff KingAug 16, 2017
  13. Nicolas Morey-ChaisemartinAug 21, 2017
  14. Jeff KingAug 23, 2017
  15. Nicolas Morey-ChaisemartinAug 24, 2017
  16. Jeff KingAug 24, 2017
  17. Daniel StenbergAug 24, 2017
  18. Jeff KingAug 24, 2017
  19. Daniel StenbergAug 24, 2017
  20. Nicolas Morey-ChaisemartinAug 24, 2017
  21. Jeff KingAug 24, 2017
  22. Jeff KingAug 16, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.