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

[PATCH v2 1/4] send-email: add an auto option for transfer encoding

From
brian m. carlson <sandals@crustytoothpaste.net>
Date
Jul 8, 2018, 22:17 UTC
Message-ID
<20180708221713.518276-2-sandals@crustytoothpaste.net>
In-Reply-To
<20180708221713.518276-1-sandals@crustytoothpaste.net>

For most patches, using a transfer encoding of 8bit provides good compatibility with most servers and makes it as easy as possible to view patches. However, there are some patches for which 8bit is not a valid encoding: RFC 5322 specifies that a message must not have lines exceeding 998 octets.

Add a transfer encoding value, auto, which indicates that a patch should use 8bit where allowed and quoted-printable otherwise. Choose quoted-printable instead of base64, since base64-encoded plain text is treated as suspicious by some spam filters.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 Documentation/git-send-email.txt | 11 +++++++----
 git-send-email.perl              | 12 +++++++-----
 t/t9001-send-email.sh            | 23 +++++++++++++++++++++++
 3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 4f3efde80c..385c7de9e2 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -137,15 +137,18 @@ Note that no attempts whatsoever are made to validate the encoding.
 	Specify encoding of compose message. Default is the value of the
 	'sendemail.composeencoding'; if that is unspecified, UTF-8 is assumed.
 
---transfer-encoding=(7bit|8bit|quoted-printable|base64)::
+--transfer-encoding=(7bit|8bit|quoted-printable|base64|auto)::
 	Specify the transfer encoding to be used to send the message over SMTP.
 	7bit will fail upon encountering a non-ASCII message.  quoted-printable
 	can be useful when the repository contains files that contain carriage
 	returns, but makes the raw patch email file (as saved from a MUA) much
 	harder to inspect manually.  base64 is even more fool proof, but also
-	even more opaque.  Default is the value of the `sendemail.transferEncoding`
-	configuration value; if that is unspecified, git will use 8bit and not
-	add a Content-Transfer-Encoding header.
+	even more opaque.  auto will use 8bit when possible, and quoted-printable
+	otherwise.
++
+Default is the value of the `sendemail.transferEncoding` configuration
+value; if that is unspecified, git will use 8bit and not add a
+Content-Transfer-Encoding header.
 
 --xmailer::
 --no-xmailer::
diff --git a/git-send-email.perl b/git-send-email.perl
index 8ec70e58ed..1736a09d21 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -1739,9 +1739,8 @@ sub process_file {
 	}
 	if (defined $target_xfer_encoding) {
 		$xfer_encoding = '8bit' if not defined $xfer_encoding;
-		$message = apply_transfer_encoding(
+		($message, $xfer_encoding) = apply_transfer_encoding(
 			$message, $xfer_encoding, $target_xfer_encoding);
-		$xfer_encoding = $target_xfer_encoding;
 	}
 	if (defined $xfer_encoding) {
 		push @xh, "Content-Transfer-Encoding: $xfer_encoding";
@@ -1852,13 +1851,16 @@ sub apply_transfer_encoding {
 	$message = MIME::Base64::decode($message)
 		if ($from eq 'base64');
 
+	$to = ($message =~ /.{999,}/) ? 'quoted-printable' : '8bit'
+		if $to eq 'auto';
+
 	die __("cannot send message as 7bit")
 		if ($to eq '7bit' and $message =~ /[^[:ascii:]]/);
-	return $message
+	return ($message, $to)
 		if ($to eq '7bit' or $to eq '8bit');
-	return MIME::QuotedPrint::encode($message, "\n", 0)
+	return (MIME::QuotedPrint::encode($message, "\n", 0), $to)
 		if ($to eq 'quoted-printable');
-	return MIME::Base64::encode($message, "\n")
+	return (MIME::Base64::encode($message, "\n"), $to)
 		if ($to eq 'base64');
 	die __("invalid transfer encoding");
 }
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index e80eacbb1b..a35cba6a4c 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -456,6 +456,29 @@ test_expect_success $PREREQ 'allow long lines with --no-validate' '
 		2>errors
 '
 
+test_expect_success $PREREQ 'short lines with auto encoding are 8bit' '
+	clean_fake_sendmail &&
+	git send-email \
+		--from="A <author@example.com>" \
+		--to=nobody@example.com \
+		--smtp-server="$(pwd)/fake.sendmail" \
+		--transfer-encoding=auto \
+		$patches &&
+	grep "Content-Transfer-Encoding: 8bit" msgtxt1
+'
+
+test_expect_success $PREREQ 'long lines with auto encoding are quoted-printable' '
+	clean_fake_sendmail &&
+	git send-email \
+		--from="Example <nobody@example.com>" \
+		--to=nobody@example.com \
+		--smtp-server="$(pwd)/fake.sendmail" \
+		--transfer-encoding=auto \
+		--no-validate \
+		longline.patch &&
+	grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
+'
+
 test_expect_success $PREREQ 'Invalid In-Reply-To' '
 	clean_fake_sendmail &&
 	git send-email \
Previous: brian m. carlsonNext: brian m. carlson
Message 12 of 16 in “Automatic transfer encoding for patches”
  1. 0/3 Automatic transfer encoding for patchesbrian m. carlson, Jul 6, 2018
  2. 1/3 send-email: add an auto option for transfer encodingbrian m. carlson, Jul 6, 2018
  3. Eric SunshineJul 6, 2018
  4. brian m. carlsonJul 6, 2018
  5. 3/3 send-email: automatically determine transfer-encodingbrian m. carlson, Jul 6, 2018
  6. 2/3 send-email: accept long lines with suitable transfer encodingbrian m. carlson, Jul 6, 2018
  7. Eric SunshineJul 6, 2018
  8. Drew DeVaultJul 6, 2018
  9. brian m. carlsonJul 6, 2018
  10. Drew DeVaultJul 6, 2018
  11. 0/4 Automatic transfer encoding for patchesbrian m. carlson, Jul 8, 2018
  12. 1/4 send-email: add an auto option for transfer encodingbrian m. carlson, Jul 8, 2018
  13. 2/4 send-email: accept long lines with suitable transfer encodingbrian m. carlson, Jul 8, 2018
  14. 4/4 docs: correct RFC specifying email line lengthbrian m. carlson, Jul 8, 2018
  15. 3/4 send-email: automatically determine transfer-encodingbrian m. carlson, Jul 8, 2018
  16. Drew DeVaultJul 8, 2018

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.