send-email: add an auto option for transfer encoding

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
brian m. carlson 2018-07-08 22:17:10 +00:00 committed by Junio C Hamano
parent 53f9a3e157
commit 7a36987fff
3 changed files with 37 additions and 9 deletions

View file

@ -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 Specify encoding of compose message. Default is the value of the
'sendemail.composeencoding'; if that is unspecified, UTF-8 is assumed. '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. Specify the transfer encoding to be used to send the message over SMTP.
7bit will fail upon encountering a non-ASCII message. quoted-printable 7bit will fail upon encountering a non-ASCII message. quoted-printable
can be useful when the repository contains files that contain carriage 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 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 harder to inspect manually. base64 is even more fool proof, but also
even more opaque. Default is the value of the `sendemail.transferEncoding` even more opaque. auto will use 8bit when possible, and quoted-printable
configuration value; if that is unspecified, git will use 8bit and not otherwise.
add a Content-Transfer-Encoding header. +
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:: --xmailer::
--no-xmailer:: --no-xmailer::

View file

@ -1739,9 +1739,8 @@ sub process_file {
} }
if (defined $target_xfer_encoding) { if (defined $target_xfer_encoding) {
$xfer_encoding = '8bit' if not defined $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); $message, $xfer_encoding, $target_xfer_encoding);
$xfer_encoding = $target_xfer_encoding;
} }
if (defined $xfer_encoding) { if (defined $xfer_encoding) {
push @xh, "Content-Transfer-Encoding: $xfer_encoding"; push @xh, "Content-Transfer-Encoding: $xfer_encoding";
@ -1852,13 +1851,16 @@ sub apply_transfer_encoding {
$message = MIME::Base64::decode($message) $message = MIME::Base64::decode($message)
if ($from eq 'base64'); if ($from eq 'base64');
$to = ($message =~ /.{999,}/) ? 'quoted-printable' : '8bit'
if $to eq 'auto';
die __("cannot send message as 7bit") die __("cannot send message as 7bit")
if ($to eq '7bit' and $message =~ /[^[:ascii:]]/); if ($to eq '7bit' and $message =~ /[^[:ascii:]]/);
return $message return ($message, $to)
if ($to eq '7bit' or $to eq '8bit'); 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'); if ($to eq 'quoted-printable');
return MIME::Base64::encode($message, "\n") return (MIME::Base64::encode($message, "\n"), $to)
if ($to eq 'base64'); if ($to eq 'base64');
die __("invalid transfer encoding"); die __("invalid transfer encoding");
} }

View file

@ -456,6 +456,29 @@ test_expect_success $PREREQ 'allow long lines with --no-validate' '
2>errors 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' ' test_expect_success $PREREQ 'Invalid In-Reply-To' '
clean_fake_sendmail && clean_fake_sendmail &&
git send-email \ git send-email \