主にメールのデータにおいて単一のデータに複数の種類のデータを含めて扱う際の「MIME」についてです。後述のS/MIMEの予備知識となる前提知識です。
全体でひとつのまとまりになっている「テキストデータ」やその他のデータに対して電子署名を生成する場合は、文字通りシンプルに電子署名を生成し、受信者は「これが電子署名対象のデータで、これが電子署名だな」と目視で判別すれば済むのですが、電子メールのようなシステムが自動で処理するデータであったり、複数の要素を含む構造化された複雑なデータに対して電子署名を生成する際は少し事情が異なってきます。
なぜこの電子署名の話の中でMIMEの話をするのかというと、電子メールへの電子署名の生成においては電子メールがMIME化されていることが前提であったり、後述するcXMLを用いた企業間商取引においてもXMLに添付ファイルを付けた状態で電子署名をする際にはMIMEの取り扱いが発生するからです。
1. MIMEはデータの種類を告げるインデックス
まずMIMEの基本機能として、「データ送信時に予め送る、データの種類を告げるインデックス」です。封筒の送付状に書いてある「内容物」の記述に例えられます。「サーバーがブラウザに送るデータの」と限定する解説もありますが、そのような限定をする必要はありません。送るデータの中身を受信者に明示する場合に使います。
2. MIME multipart(マルチパート)
次に、MIMEの拡張としての機能ですが、送られた単一のデータ内に個別に切り分けて処理する必要がある場合にも使われます。封筒の中にある小包装ごとの荷札のようなものです。例えば電子メールの場合ですが、電子メールには「送信者」「受信者」「本文」「添付データ」などの情報が構成要素としてあるわけですが、それぞれの情報につき受信した際の処理が異なるはずです。また、商取引に使われるXMLデータには「価格」「日付」「メッセージ」「PDF見積書」といったそれぞれ受信した際の処理が異なるはずの情報が含まれます。ですので、送られてきたひとまとまりのデータの中に「これはテキスト」「これは画像」「これはPDF」のように小包装することで受信後の情報処理方法を明示します。このように単一のデータの中に複数のMIME Typeが存在する状態をMIME multipart(マルチパート)といいます。またこのように複数のMIME要素をひとまとめにした封筒である全体を「MIME Envelope(エンベロープ)」と呼びます。
マルチパートなデータについて語られる際は「メール」であることが前提として語られるのですが、実際はメールである必要はありません。例えば、サーバー間通信でXMLを送受信する際にXML自体だけではなく他のデータ(例:画像やPDF)を添付して送りたい場合にもMIME multipartは使えます。
MIME multipartは送受信するデータを下記の構造で送ります。単にXMLだけを送る場合、データ送信の最初に「Content-type: text/xml; charset=”UTF-8″」を明示して「これからtext/xml形式のデータを送るよ」と伝えれば良いです。
単にXMLだけを送る場合:
POST /cXML HTTP/1.0 <--! begin MIME body part header --> Content-type: text/xml; charset="UTF-8" <--! end MIME body part header --> <?xml version="1.0" encoding="UTF-8"?> <xml> <element1> ..... </element1> <element2> ..... </element2> </xml>
これに対して、例えばXMLと添付ファイル(ここではJPG画像とする)を送る場合は下記のように「Content-type: multipart/mixed; boundary=some_unique_identifier」のように「これからマルチパートのデータを送るよ」と伝え、続いて各データのMIME Typeを個別に宣言して送っていきます。マルチパートの各データの関連性によって下記の3種類をはじめとする宣言が便宜的に用意されています(その他の宣言タイプは https://www.iana.org/assignments/media-types/media-types.xhtml#multipart 参照)。
また、各データのMIME Type宣言の前に「–some_unique_identifier(この文字列そのままではなく、ホントに生成した固有の英数字の文字列)」という文字列を入れて仕切っていきます。
XMLと添付ファイルを送る場合:
POST /cXML HTTP/1.0 Content-type: multipart/related; boundary="some_unique_identifier" <--! begin first MIME body part header --> --some_unique_identifier Content-type: text/xml; charset="UTF-8" Content-ID:<--! end first MIME body part header --> <?xml version="1.0" encoding="UTF-8"?> <xml> <element1> ..... </element1> <element2> ..... </element2> </xml> <--! begin second MIME body part header --> --some_unique_identifier Content-Type: image/jpeg; name="sample.png" Content-ID: <--! end second MIME body part header --> data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALoAAABkCAYAAAAxOiquAAAUoklEQVR42u1dCZgcRRV2e2Y3CRARurp7pmd2s8nObhYXIrgqNySgCCriFZBbgUgQCRDkEAGDEUUUEC+IEA4hQDiFiKByCIh4oBzGCARUQnb2yAUJRwhJxvf62K2uruo5tmd3M/ve99UX2Omuqq7661316tV73kNERERUKXVvkzJ6k9ZH8xqbDWVel8YW5uv0B6D8Gcq/8nXsqa469iD89 ....
3. MIMEタイプ
MIMEタイプの宣言は「そのデータの種類」にスラッシュを挟んで「データとして扱う際に必要な前処理がわかる情報」を記述して行います。
3.1. text
基本的にはそのまま人間が読んで理解できるテキストデータを表します(下記が一例)。
3.2. image
それぞれの画像形式としてデコードすることで閲覧できるデータを表します(下記が一例)。
3.3. video
それぞれの動画形式としてデコードすることで閲覧できるデータを表します(下記が一例)。
3.4. audio
それぞれの音声形式としてデコードすることで聴けるデータを表します(下記が一例)。
3.5. application
それぞれに関連づけられたアプリケーションで開くことで利用できるデータを表します(下記が一例)。
ちなみに、XMLデータに関しては「text/xml」というMIMEタイプと「application/xml」というMIMEタイプがありますが、どちらの用途も同じです。もしMIMEタイプでXMLかどうかを判別するコードを自分で作る場合はどちらかのみではなく両方を拾うようにしておく必要があります。
長くなったので、次回は「複数のMIMEタイプを含むマルチパートのデータをPHPで処理してみる」について述べます。