Empfang von MIME-Mail mit binären Anhängen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
vboehm
User
Beiträge: 6
Registriert: Dienstag 16. April 2013, 16:57

Hallo,
ich hab' da mal wieder ein Problem:

Ich möchte eine Multipart MIME-Mail (eigentlich ist es keine Mail, sondern eine Multipart/related SOAP-Message; aber das sollte keine Geige spielen) zerlegen und auswerten. Mit den textuellen Teilen klappt das mit email.message auch prima.Ich zerlege die Mail mit get_payload() in ihre Bestandteile und dann erhalte ich den Body jedes Einzelteils wieder mit get_payload(). Aber einige Mails/SOAP-Antworten einhalten PDFs, die als

Code: Alles auswählen

Content-Type: application/pdf
Content-ID: xxxxxxx-yyyy-zzzzzzzzzzzzzzzzzz
Content-Transfer-Encoding: binary
deklariert sind. Und bei denen greift dann leider der (un)schöne letzte Absatz aus der Beschreibung von get_payload()
When decode is False (the default) the body is returned as a string without decoding the Content-Transfer-Encoding. However, for a Content-Transfer-Encoding of 8bit, an attempt is made to decode the original bytes using the charset specified by the Content-Type header, using the replace error handler. If no charset is specified, or if the charset given is not recognized by the email package, the body is decoded using the default ASCII charset.
D.h. die schwachsinnige ASCII-Umsetzung macht das PDF kaputt. Und das alles, weil es scheint's nicht vorgesehen ist, dass jemand per Mail etwas anderes als Text verschickt. Es gibt keine Funktion get_binaray_payload().

Kennt jemand von euch eine Möglichkeit eine MIME-Mail vernünftig in Einzelteile zu zerlegen?

Die Inhalts-Deklaration im Header des MIME-Parts kann ich mir leider nicht aussuchen, da sie vom Sender vorgegeben ist (außerdem ist sie ja nicht falsch).

mfg Volker

PS: Wenn ihr eine Python-SOAP-Bibliothek kennt, die Multipart und SOAP 1.2 kann, wäre das natürlich ganz toll, aber da wage ich vor 2025 nicht drauf zu hoffen; weil das gibt's alles erst seit über 10 Jahren und deshalb ist es noch viel zu neu.
BlackJack

@vboehm: Eine Verschlechterung bei Python 3 würde ich sagen. Ein Bibliotheksmodul was jetzt wo Zeichenketten Unicode-Objekte sind, entscheiden muss ob etwas Text oder Binärdaten ist, beziehungsweise einfach davon ausgeht das alles Text ist, obwohl das nicht immer der Fall ist. Mit Python 2 wäre das noch einfach(er) möglich gewesen. Bei Python 3 ist wohl der einfachste Weg an der öffentlichen API vorbei direkt auf das `_payload`-Attribut zuzugreifen.

Edit: Auch 2025 würde ich da nicht drauf hoffen. Wenn Du SOAP brauchst, bewegst Du Dich in einem Umfeld das Pythonistas nicht gerne betreten. Das benutzt heute auch niemand mehr der nicht unbedingt muss. Und wer unbedingt muss hat sehr wahrscheinlich ein „Enterprise”-System vor sich. Und da benutzt man Java und 1000-seitige Spezifikation für jeden kleinen Furz. :twisted:
vboehm
User
Beiträge: 6
Registriert: Dienstag 16. April 2013, 16:57

Vielen Dank für die kurze aber traurige Antwort :-(
Bei Python 3 ist wohl der einfachste Weg an der öffentlichen API vorbei direkt auf das `_payload`-Attribut zuzugreifen.
Das funktioniert leider auch nicht, weil auch das _payload-Attribut schon vom Typ 'str' ist. Zusätzlich enthält es scheint's Zeichen, die sich nicht in UTF-8 kodieren lassen - was ja eigentlich unmöglich sein sollte -.

Code: Alles auswählen

    outfile.write(part._payload)            # geht nicht, weil str nicht in eine Binärdatei schreibbar ist

    outfile.write(part._payload.encode())   # geht nicht wegen "'utf-8' codec can't encode character '\udce2' in position 10: surrogates not allowed"
Tolle Wurst!! Ich bin begeistert!

Ansonsten hast Du natürlich mit Deinem Kommtar zu SOAP 100%-ig Recht. Ich benutze für die gleiche Funktionalität (RPC) JSON-RPC, das man mit ca. 350 Zeilen Bibliotheks-Code erschlagen kann. Aber leider schießen in letzter Zeit Hanseln wie Pilze aus dem Boden, die SOAP für den letzten Schrei halten, und das dann auch noch mit allen erdenklichen Erweiterungen nutzen müssen, die aus SOAP praktisch ein Closed-Shop-Java-System machen. Aber wenn man auf deren Daten Zugreifen möchte/muss hat man leider die Arschkarte gezogen.

Dann werd ich mir wohl in Java einen SOAP-1.2-mit-Multipart/related--zu--JSON/RPC-Proxy bauen ... Ich hab ja sonst nichts zu tun ...

mfg Volker
Antworten