2016-10-18 1 views
1

J'essaye d'envoyer une pièce jointe binaire en utilisant le python 3.5.2 smtplib sur TLS. Ma plate-forme est OSX et j'utilise python installé depuis homebrew.python 3 smtplib: la pièce jointe binaire ne code pas correctement dans flask lorsque gnupg est actif

Lorsque je reçois la pièce jointe, le codage semble être activé. Au lieu du fichier original qui commence par cet hexagone:

ffd8 ffe0 0010 4a46 4946 0001 0100 0001 

i.e., <FF><D8><FF><E0>^@^PJFIF^@^A^A 

l'hexagone de départ de mon attachement tel que reçu a quelques restes de base64 étranges:

5c75 6463 6666 5c75 6463 6438 5c75 6463 6666 5c75 6463 6530 0010 4a46 4946 0001 

i.e., \udcff\udcd8\udcff\udce0^@^PJFIF 

Ceci est un cas minimal qui tombe en panne, ce qui est assez bien exactement ce qui est dans la documentation officielle, à l'exception de l'ajout de la logique TLS et GnuPG:

import gnupg 
gpg = gnupg.GPG('/path/to/gpg') 

import smtplib 
from email.mime.multipart import MIMEMultipart 
from email.mime.image import MIMEImage 

def send_my_email(): 
    msg = MIMEMultipart() 
    msg['Subject'] = 'subject' 
    msg['From'] = '[email protected]' 
    msg['To'] = '[email protected]' 
    with open('/tmp/image.jpg', mode='rb') as image_file: 
     image = MIMEImage(image_file.read()) 
    msg.attach(image) 
    s = smtplib.SMTP('smtp.gmail.com', 587) 
    s.starttls() 
    s.login('[email protected]', 'password') 
    s.send_message(msg) 
    s.quit() 

Sur la base d'une autre question ici, j'ai essayé ce lieu de send_message() et il a également échoué:

s.sendmail('[email protected]', ['[email protected]'], msg.as_string()) 

J'ai aussi essayé d'ajouter explicitement _subtype='jpg' quand j'init MIMEImage, en ajoutant un en-tête Content-Transfer-Encoding, et en ajoutant un en-tête Content-Disposition et aucun de ceux qui semblaient faire une différence.

J'ai vérifié que je n'ai pas de problème avec mon client de messagerie lorsqu'il reçoit des pièces jointes codées en base64 d'autres clients.

J'ai regardé la source smtplib et j'ai remarqué que la façon dont smtplib gère les séparateurs de ligne semble un peu étrange et je me demande si cela est peut-être lié. (voir aussi ref: https://bugs.python.org/issue14645)

Dois-je encoder quelque chose différemment, définir quelque chose de spécial pour ma plate-forme, ou est-ce un problème? Merci!


Mise à jour: Ce problème existe seulement quand je suis en cours d'exécution Flask et ne se produit pas à l'extérieur de la Gourde. Je suis en train de tenter d'isoler le problème dans mon environnement Flask. Je pensais que ce pourrait être flask_mail mais enlever cela n'a pas résolu le problème. Le code ci-dessous échoue lorsqu'il est exécuté depuis Flask sur mon système, mais pas si je l'exécute à partir d'un script shell provenant du même environnement virtuel et du même binaire python. Je ne m'attends pas à des réponses à ce stade en raison de la complexité, mais je laisserai cela ouvert à la postérité.

Mise à jour 2: J'ai réduit ce problème à une interaction avec la bibliothèque gnupg de https://github.com/isislovecruft/python-gnupg/. J'ai mis à jour mon exemple minimal pour refléter cela. Ce patch singe de codecs python dans python-gnupug est responsable du problème: codecs.register_error('strict', codecs.replace_errors)

+1

Il semble que le fichier est en cours de lecture dans une chaîne de python (unicode) et en cours de sérialisation après le codage utf-8 cette chaîne. Je suppose que MIMEImage a besoin d'aide, mais je n'ai pas utilisé le code email.mime sur 3.x, donc je ne peux pas vous diriger directement vers le problème. – cco

+0

Aha, je vais voir si j'ai besoin de faire quelque chose différemment quand je lis le fichier. Merci! – mirth23

+0

Après avoir converti 'app.open_resource()' en 'open()', votre programme fonctionne parfaitement pour moi. Pouvez-vous fournir un court programme ** complet ** qui démontre le problème? Voir [mcve] pour plus d'informations. –

Répondre