send-email: add an auto option for transfer encoding
authorbrian m. carlson <sandals@crustytoothpaste.net>
Sun, 8 Jul 2018 22:17:10 +0000 (22:17 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Jul 2018 17:55:12 +0000 (10:55 -0700)
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>
Documentation/git-send-email.txt
git-send-email.perl
t/t9001-send-email.sh
index 4f3efde80cd8e4f0b1a5b6699ad3e569f19ca516..385c7de9e2b936007e6a9a4626f40373f24f88de 100644 (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
        'sendemail.composeencoding'; if that is unspecified, UTF-8 is assumed.
 
        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
        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::
 
 --xmailer::
 --no-xmailer::
index 8ec70e58ed5c4caace7701549038b63f9a3e9aad..1736a09d21ec4718526f579b49d9d1209a9c19aa 100755 (executable)
@@ -1739,9 +1739,8 @@ sub process_file {
        }
        if (defined $target_xfer_encoding) {
                $xfer_encoding = '8bit' if not defined $xfer_encoding;
        }
        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);
                        $message, $xfer_encoding, $target_xfer_encoding);
-               $xfer_encoding = $target_xfer_encoding;
        }
        if (defined $xfer_encoding) {
                push @xh, "Content-Transfer-Encoding: $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');
 
        $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:]]/);
        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');
                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');
        die __("invalid transfer encoding");
 }
                if ($to eq 'base64');
        die __("invalid transfer encoding");
 }
index e80eacbb1b81a319232c0b5f28aab3c82d795a93..a35cba6a4cc0c608701323b613f6076504a9f59b 100755 (executable)
@@ -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' '
        clean_fake_sendmail &&
        git send-email \
 test_expect_success $PREREQ 'Invalid In-Reply-To' '
        clean_fake_sendmail &&
        git send-email \