Programmering

MIME Multipart, boundary og linjeskift

3. august 2012 · Ingen Kommentarer

MIME Multipart-meldinger er kresne og er vanskelige å håndkode.
Det er allikevel mulig å håndkode dem hvis man har god nok teksteditor (som kan vise kontrolltegn som linjeskift) og god tålmodighet og tunga rett i munnen.

MIME-meldinger krever CRLF-endinger på linjene før og etter boundary-kodene og etter hver MIME-header.
I eksempelet nedenfor representeres hvert linjeskift som LF.

MIME-meldingseksempel

De steder hvor det står ^M brukes CR, som oftest rett før linjeskiftet.


--part-boundary-1^M
Content-Type: text/plain; charset=utf-8; name=litt-tekst.txt^M
Content-ID:
^M
Content-Disposition: attachment; name="litt-tekst.txt"; filename="litt-tekst.txt"^M
^M
Dette er noe tekst i en fil som heter some-text.txt
Denne fila bruker UNIX-linjeendinger, altså LF og ikke CRLF,
og det er helt i orden, siden innholdet av denne tekstfila er utenfor kontekst av MIME.

Dette er siste linje i fila^M
--part-boundary-1^M
Content-Type: image/png; name=lite-bilde.png^M
content-transfer-encoding: base64^M
^M
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAAL
EwAACxMBAJqcGAAAAAd0SU1FB9wIAwwLKSOxKhgAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRo
IEdJTVBXgQ4XAAAAMklEQVQoz2P8z4AD/Mcuw8RAIhjGGv7/J0UDbtUMDAws+KQZGUnxAzbVuDXg
UD1SYxoAH7UJHx3uIsQAAAAASUVORK5CYII=
^M
--part-boundary-1--^M

Store og små bokstaver i navn på MIME-headere har ingen betydning.

Blokk og separatorkoder (boundary)

I denne meldingen bruker vi separatorkoden (boundary) part-boundary-1.
Separatorene i fila prefikses med --, som viser til start på en MIME Part-blokk.
En slik blokk varer fram til neste separator av samme kode.
Siste separator appendes med -- i tillegg til prefiksen, som betyr at det ikke er flere blokker.

En blokk i en multipart kan også være en multipart, men blokker under denne separeres med egen separatorkode.

Teste meldingen mot en server

For å teste opplasting med HTTP til en web servlet kan man bruke curl.
Vi lagrer multipart-meldingen på fil melding.multipart.
For at serveren skal kunne forstå multipart-meldingen må Content-Type-headeren spesifiseres som multipart/related og boundary satt til part-boundary-1.

Eksempel på kommando:


$ curl -X POST \
    -H "Content-Type: multipart/related; boundary=\"part-boundary-1\"" \
    --data-binary @melding.multipart \
    "http://localhost:8080/multipartServlet"

Forskjellige biblioteker og krav til CRLF

Det er noe forskjeller i hvordan forskjellige kodebiblioteker tolker multipart-meldinger.
Noen tillater linjeendinger med bare LF (uten CR), mens andre er strengere og krever CRLF.

Servlet 3 sin multipart-parser er streng og krever CRLF.
Samme er tilfellet med CXF sin SOAP-Attachment-parser.

Telia MMS MMSC-parser er derimot mer tilgivende.

Ansvarsfraskrivelse…

Det er ikke sikkert jeg har forstått dette 100% ennå.
Det kan være at mitt håndkoda eksempel over inneholder noen skrivefeil.
Jeg hadde Java i tankene da jeg skrev dette, og det er Java jeg har arbeidet med for behandling av MIME-meldinger da jeg forsket på feilscenariene jeg har hatt med linjeendinger.

Mer om MIME-meldinger

RFC 1341 og spesielt seksjonen 7.2 om multipart gir mer informasjon om strukturen til MIME multiparts.