MIME:

分散システム特論
MIME
Multipurpose Internet Mail Extensions
情報工学専攻 修士課程一年 谷口秀夫研究室
矢野 大介
発表手順
1. MIME関連のRFC
2. 単純なテキストメッセージ(RFC822)
3. MIME(RFC2045)
4. 実装(Sylpheed)
No.2
MIME関連のRFC
1982年
RFC822
Standard for APRA Internet Text Massages
1996年
RFC2045 MIME Part One: Format of Internet Message Bodies
RFC2046 MIME Part Two: Media Types
RFC2047 MIME Part Three: Message Header Extensions for
Non-ASCII Text
RFC2048 MIME Part Four: Registration Procedures
RFC2049 MIME Part Five: Conformance Criteria and Examples
No.3
単純なテキストメッセージ
(RFC822)
テキストメッセージの「テキスト」とは
ASCIIコード(7ビットコード) のこと
上位4ビット
下位4ビット
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
1
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
2
SP
!
"
#
$
%
&
‘
(
)
*
+
,
.
/
3
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
4
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
5
P
Q
R
S
T
U
V
W
X
Y
Z
[
]
^
_
6
`
a
b
c
d
e
f
g
h
I
j
k
l
m
n
o
7
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
DEL
この範囲のコードだけがインターネットメールで送受信可能 No.4
テキストメッセージフォーマット
インターネットテキストメッセージのフォーマット
ヘッダフィールドと本文から構成される
ヘッダフィールドと本文は空行(CRLFのみの行)で区切られる
ヘッダフィールドは必ずメッセージ本文の前に置く
本文はオプションであり、なくてもかまわない
(1) ヘッダフィールドのフォーマット
フィールド名:フィールド値[;パラメータ名=パラメータ値]
(2) 本文のフォーマット
任意の文字数のASCIIテキスト
行の形にフォーマットされる(行の終端はCRLF)
RFC821(SMTP)で行の長さに関する規定あり
・ 1行あたり1000字以下(CRLFを含む)に制限
(通常は80字以内に収める)
No.5
ヘッダの種類
(1)必須ヘッダ
(3)動的なヘッダ
Date:送信日時
To:メッセージ受信者
From:送信者(作成者)
( Sender:実際の送信者)*
(2)オプションヘッダ
Return-Path:エンベロープの
MAIL FROM: の内容
Received:配送経路情報
Message-ID:メールを一通一通区別する
為の世界中で一意な文字列
(4)ユーザ定義ヘッダ
Cc:コピーの受信者
Bcc:受信メッセージに
表示されない受信者
Subject:表題
Reply-to: 返信先の指定
Comment: コメント
Keyword:キーワード
Encrypted:暗号化(タイプ)
“X-” で始まるASCII文字
(コロンを除く0x21~0x7E)
* メッセージの送信者(プログラム)と作成者が異なる場合に必要
No.6
ヘッダに関する注意事項
長いヘッダ
ヘッダ値が長い場合
(1) US-ASCII文字の単一行として長いまま送る(256文字以内)
(2) 複数行に折り返す(1行あたり72文字以内)
・CRLFとそれに続くいくつかの空白文字のシーケンスを
行の途中にセパレータとしてはさみ、複数行に分割する
・必ず既存の空白文字の位置で折り返す
・メールアドレスの場合は、アドレスに続くカンマの直後で
折り返す
ヘッダの順序
ヘッダの出現順序についての規定はない
No.7
単純なテキストメッセージの例
Return-Path: <[email protected]>
Received: from crest (hisame.csce.kyushu-u.ac.jp [133.5.22.121])
by crest.csce.kyushu-u.ac.jp (8.9.3+3.2W/3.7W99041514) with ESMTP id W\
AA03253
for <[email protected]>; Fri, 04 Jan 2002 12:49:47 +0900 (JS\
T)
Message-Id: <[email protected]>
X-UIDL: A'A!!^+7!!5]e"!/"c!!
Subject: test mail
From: d_yano <[email protected]>
To: d_yano <[email protected]>
Date: Fri, 04 Jan 2002 12:49:47 +0900
空行(CRLFのみの行)
Hi!
This is a simple text message.
ヘッダ
本文
No.8
MIME
以前の単純なテキストによるインターネットメールでは
ワープロなどのアプリケーションデータ(バイナリコード)
日本語などの英語以外の言語コード(8ビットコード)
といったデータを含めることができなかった
MIME(Multipurpose Internet Mail Extensions)
バイナリデータや8ビットコードデータなどのコンテンツを
送受信可能にする仕組み
コンテンツをタイプで識別し、アプリケーションや言語と関連付けて
格納する仕組み
コンテンツをUS-ASCIIサブセットのテキストにエンコードする仕様
No.9
MIMEメッセージフォーマット
MIMEメッセージは、通常のインターネットテキストメッセージ
単純なテキストメッセージフォーマットとの違い
(1)いくつかの特別なMIMEに関わるヘッダを持つ
(2)ある約束事に従った本文を持つ
マルチパートメッセージの場合
MIMEバウンダリと呼ばれる特別な文字列によって
いくつかのパートにわかれている
各パートの先頭にはMIMEヘッダが付加される
各パートがUS-ASCIIでエンコードされたデータを持つ
No.10
MIMEヘッダフィールド
(1)MIMEメッセージヘッダ
RFC822形式のメッセージヘッダに追加されたヘッダ
MIME-Version
Content-Type
Content-Transfer-Encoding
Content-ID
Content-Description
Content-Disposition
(2)MIMEパートヘッダ
マルチパートメッセージの各本文パートの先頭に置かれ、
各パートのコンテンツについての情報を記述する
MIME-Version 以外のMIMEメッセージヘッダ
→ MIMEパートヘッダは必ず “Content-” で始まる
※ MIMEヘッダの出現順序についての規定はない
No.11
MIME-Version
メッセージがMIMEの仕様に従って構成されていることを示す
メッセージの作成に使用されたMIMEのバーションを表す
現時点でのMIMEバーションは、1.0しか存在しない
MIMEメッセージは必ず以下と全く同じヘッダフィールドを持つ
MIME-Version: 1.0
No.12
Content-Type(1)
目的はMUA(Mail User Agent)がメッセージを解析し、メッセージに
含まれるデータのタイプを識別し、正しく表示できるようにすること
このフィールド値はメディアタイプ(RFC2046)と呼ばれる
メディアタイプには、メディアタイプとサブタイプがある
フィールドのフォーマットは以下のようになる
Content-Type: メディアタイプ/サブタイプ[;パラメータ名=パラメータ値]
Content-Typeヘッダが指定されていない場合は初期値として
以下の値をとる
Content-Type: text/plain; charset=us-ascii
※ メディアタイプ・サブタイプ・パラメータ名は大文字小文字を区別しない
No.13
Content-Type(2)
メディアタイプ(RFC2046)
Discrete Media Type
(1) text:テキストデータ、HTMLデータ、リッチテキストなど
(2) image:GIFやJPGなどの画像データ
(3) audio:WAVEなどの音声データ
(4) video:MPEGなどの動画データ
(5) application:アプリケーション独自のデータ
Composite Media Type
(6) multipart:マルチパート型メッセージ
(7) message:RFC822に準拠したメールメッセージなど
※ 任意のバイナリデータをメッセージに添付するには
application/octet-streamメディアタイプを使用する
No.14
Content-Type(3)
サブタイプ
あるメディアタイプに特徴的な書式を特定する
各メディアタイプには1つまたはそれ以上のサブタイプが
定義されている
新しいサブタイプを定義する場合
(1) RFC2048に従って、IANA(Internet Assigned Number
Authority)に登録する
(2) 外部登録を行わず、“X-”で始まる値を使用する
パラメータ
メッセージへの付加的な情報を表す
たいていはある特定のサブタイプに関連付けられているが、
メディアタイプによりパラメータを定義する場合もある
例 multipart メディアタイプを使用する場合には、boundary パラメータ
text メディアタイプを使用する場合には、charset パラメータ
を指定する
No.15
Content-Type(4)
MIMEバウンダリ(RFC2046)
MIMEメッセージ内でのメッセージパート間の境界を定義する
7ビットUS-ASCIIテキストで記述された文字列
メッセージ内で一意な文字列でなければならない
Content-Type: multipart/mixed; boundary=“boundary_str”
1つのパートの開始を意味する境界識別子は
--boundary_str
全体のマルチパートの終了を意味する境界識別子は
--boundary_str--
バウンダリに挟まれた各パートは、さらにバウンダリを定義し
パートをネストすることができる
※ MIMEバウンダリに使用される文字列は大文字小文字を区別する
No.16
Content-Transfer-Encoding
メッセージまたはメッセージパートのエンコード方式を表す
フィールドのフォーマットは以下のようになる
Content-Transfer-Encoding: エンコード方式
エンコード方式は以下のものがある
(1) 7bit: 本文が7bitテキストコードであることを示す
(2) 8bit: 本文が8bitテキストコードであることを示す
(3) binary: テキスト以外のバイナリデータであることを示す
(4) quoted-printable: quoted printable形式のデータ(7bit)
(5) base64: base64形式のデータ(7bit)
Content-Typeがmultipartまたはmessageの場合は、
7bit、8bit、binary以外の方式をとることができない
※ エンコード方式を表す値は大文字小文字を区別しない
No.17
Content-ID
あるメッセージの本文から別のメッセージの本文を参照できる
このフィールド値は世界中で一意でなければならない
通常シリアル番号とホスト指名部分からなる
例 Content-ID: <[email protected]>
Content-IDヘッダは必須ではないが、massege/external-bodyの
場合には必須になる(RFC2046)
No.18
Content-Description
US-ASCIIテキストによるメッセージのコンテンツの説明を
付けることができる
Content-Descriptionヘッダは常に選択的である
例 Content-Description: The attachment below is PGP-encoded.
説明のテキストのデフォルトはUS-ASCIIだが、特別な文字
エンコードメカニズムにより、他の文字セットでも記述できる
ヘッダでの非ASCII文字の利用について(RFC2047)
エンコード形式
=?文字セット?エンコード方式?エンコード済みテキスト?=
例
エンコード前 Content-Description: 日本語
エンコード後 Content-Description: =?iso-2022-jp?B?GyRCRnxLXDhsGyhC?=
※ この形式の文字列はMIMEヘッダのパラメータで使われてはならない
No.19
Content-Disposition(RFC2183)
本文に含まれるファイルの提示方法についてのヒントを与える
フィールドのフォーマットは以下のようになる
Content-Disposition: タイプ[;パラメータ名=パラメータ値]
タイプには以下のものがある
(1) inline:メール本文など、その他の要素と一緒に表示する
(2) attachment:通常の外部添付として扱う
パラメータには、filenameなどがあり、filenameはオリジナルの
添付ファイル名を伝えることができる
No.20
MIMEメッセージの例
From: [email protected]
To: [email protected]
Subject: =?ISO-2022-JP?…
Date: Sun, 01 Sep 2001 15:15:15 +0900
Mime-Version: 1.0
Content-Type: Multipart/Mixed; boundary=“Boundary”
(空行)
--Boundary
Content-Type: Text/Plan; charset=iso-2022-jp
Content-Transfer-Encodeing: 7bit
(空
行)
…本文パートのボディ…
--Boundary
Content-Type: Image/Gif; name=“xx.gif”
Content-Transfer-Encodeing: base64
Content-Disposition: attachment; filename=“xx.gif”
(空
行)
…添付文書パートのボディ…
--Boundary--
メッセージヘッダ
ヘッダ
MIME
パート
本文
本文
MIME
パート
No.21
MIMEエンコード
インターネットメールの制限に従うために、任意のバイナリデータ
または非US-ASCII文字セットのテキストデータは、US-ASCIIテキスト
にエンコードする必要がある
エンコード方式の分類
(1) 7bit、8bit、binary
データに対してエンコードが行われていない
(2) quoted-printable
データが7ビットに変換されている
(3) base64
データが7ビットに変換されている
No.22
7bit、8bit、binary
7ビットデータ
RFC821による制限を持つUS-ASCIIテキストである
10進US-ASCIIコードが、0および128以上のオクテットデータは許されない
CRとLFは、行の終端のCRLFシーケンス以外には使用できない
8ビットデータ
10進値が128以上のUS-ASCII文字も許される点を除いて、7ビットデータと同じ
バイナリデータ
US-ASCIIの変換とは無関係に任意のタイプのオクテットを含むことができる
インターネットメールシステム(SMTP)を介した配送において
安全であることが保証されているのは、7ビットデータのみ
8ビットデータやバイナリデータを使ってはならない
8ビットデータやバイナリデータはquoted-printableまたは
base64でエンコードして7ビットに変換する
No.23
quoted-printable
人間が判読できる(US-ASCIIテキスト)形式だが
7ビットデータではないデータに対するエンコード方式
主にヨーロッパやロシアなどの言語を表現するとき、
ほとんどがUS-ASCIIで表現できるため、便利である
日本語に quoted-printable を使用することはまれである
No.24
quoted-printableのエンコードルール
エンコードルール
(1) ビットがビッグエンディアン形式になるように、オリジナルのデータを
オクテットストリームに並べ替える
(2) オリジナルデータ中の改行(CRLF)以外のオクテットは、等号(=)の後に
オクテットの文字コード16進値(0123456789ABCDEF)2文字を置くシーケンス
に変換できる。小文字(abcdef)は使用できない
(3) US-ASCII10進コードが33~60および62~126の範囲の文字は、US-ASCII文字
表現として表現することができる
(4)空白文字(US-ASCII10進コードが9のタブ、および32のスペース)は、行末にな
る場合以外はそのまま残すことができる。行末になる場合は、ルール(2)に従う
(5) オリジナルデータの改行は、CRLFの形式に変換する
(6) 各行は76文字以下に収まるようにする(行末のCRLFは含まない)。オリジナル
データの行が76文字より長い場合は、等号(=)の後にCRLFを置くシーケンス
によって改行することで「ソフト」改行を追加できる
No.25
quoted-printableによるエンコード例
The Quoted-Printable encoding requires that encoded lines be
no more than 76 characters long.
==> RFC2045
等号を16進記法でエンコードする(2)
他の文字はそのまま残す(3)
行末の空白文字はないので、すべての空白文字をそのまま残す(4)
オリジナルテキストと同じ位置に改行を置く(5)
76文字を超える行はないが、練習のためにソフト改行を挿入する
The Quoted-Printable encoding requires =
that encoded lines be
no more than 76 characters long.
=3D=3D> RFC2045
No.26
base64
7bitまたはquoted-printableによるエンコードが向かない
ファイル(主にバイナリデータ)をインターネットメール
システムを経由して送る必要がある場合に使用される
7ビッドデータのまま送信する場合や、7ビットでないテキスト
データをquoted-printableでエンコードして送信する場合に
比べて効率が悪くなる
エンコードされたデータのサイズはオリジナルデータより
33%増大する
No.27
base64のエンコードルール
エンコードルール
(1) ビットがビッグエンディアン形式になるように、オリジナルデータを
オクテットストリームに変換する
(2) エンコードするデータがテキスト形式の場合は、最初に改行をCRLFに変換する
(3) ストリームから3オクテットずつ取り出して、6ビットずつまとめてbase64英数字に
対するインデックスとする
(4) ルール(3)で得たられた4つの6ビットインデックスを変換表により4つの文字に
変換する
(5) エンコードされた情報の各行が、行末の改行(CRLF)を除いて76文字以内に
なるようにする
(6) オリジナルデータの末尾に来た時に、1つまたは2つのオクテットが残ってしまう
場合、エンコードデータの「補充」を行わなければならない
(7) 補充を行うには、まず不完全な6ビットブロックがなくなるまで0のビットを
追加する。得られた6ビットブロックはルール(3)を適用する。さらに、エンコード
データ全体の文字数が4の倍数になるまで、末尾に1つまたは2つの等号(=)を
補充していく
No.28
base64変換表
値 エンコード 値 エンコード 値 エンコード 値 エンコード
0
A
16
Q
32
g
48
w
1
B
17
R
33
h
49
x
2
C
18
S
34
I
50
y
3
D
19
T
35
j
51
z
4
E
20
U
36
k
52
0
5
F
21
V
37
l
53
1
6
G
22
W
38
m
54
2
7
H
23
X
39
n
55
3
8
I
24
Y
40
o
56
4
9
J
25
Z
41
p
57
5
10
K
26
a
42
q
58
6
11
L
27
b
43
r
59
7
12
M
28
c
44
s
60
8
13
N
29
d
45
t
61
9
+
14
O
30
e
46
u
62
/
15
P
31
f
47
v
63
等号(=)は空きブロックの補充に使用する
No.29
base64によるエンコード例
例 “GIF89”をbase64形式にエンコードする
1. オクテットストリームへの変換
0100011101001001010001100011100000111001
2. 先頭から順に6 ビットのブロックに分割
010001 110100 100101 000110 001110 000011 1001
3. 最後のブロックが6 ビットになるまで0のビットを補充
010001 110100 100101 000110 001110 000011 1000100
4. 6 ビットのブロックを64種類の文字に変換
10進表現
文字表現
17
R
52
0
37
l
6
G
14
O
3
D
36
k
D
k
5. 全体の文字数が4の倍数になるまで末尾に等号を補充
R
0
l
G
O
=
6. 結果
R01GODK=
No.30
実装
Sylpheed
(1) X Window System上で動作する
電子メールクライアント & ニュースリーダー
(2) Linux あるいは他の POSIX 準拠な Unix like OS で
実行可能
(3) MIME対応
No.31
ソースコード
compose.c
…
fprintf(fp, "\n--%s\n", compose->boundary);
…
conv_encode_header(filename, sizeof(filename),ainfo->name, 12);
fprintf(fp, "Content-Type: %s;\n"
" name=\"%s\"\n",
ainfo->content_type, filename);
fprintf(fp, "Content-Disposition: attachment;\n"
" filename=\"%s\"\n", filename);
…
fprintf(fp, "Content-Transfer-Encoding: %s\n\n",
procmime_get_encoding_str(ainfo->encoding));
if (ainfo->encoding == ENC_7BIT) {
…
fputs(buf, fp);
…
} else {
…
to64frombits(outbuf, inbuf, B64_LINE_SIZE);
fputs(outbuf, fp);
…
fprintf(fp, "\n--%s--\n", compose->boundary);
No.32
実行結果(1)
No.33
実行結果(2)
Date: Fri, 04 Jan 2002 00:32:16 +0900
From: d_yano <[email protected]>
To: d_yano <[email protected]>
Subject: =?ISO-2022-JP?B?TUlNRRskQiVhJUMlOyE8JTgbKEI=?=
Message-Id: <[email protected]>
Mime-Version: 1.0
Content-Type: multipart/mixed;
boundary="Multipart_Fri__04_Jan_2002_00:32:16_+0900_082a6640"
This is a multi-part message in MIME format.
--Multipart_Fri__04_Jan_2002_00:32:16_+0900_082a6640
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit
MIMEメッセージのテストだろ。
--Multipart_Fri__04_Jan_2002_00:32:16_+0900_082a6640
Content-Type: image/jpeg;
name="=?ISO-2022-JP?B?GyRCMmhBfBsoQi5qcGc=?="
Content-Disposition: attachment;
filename="=?ISO-2022-JP?B?GyRCMmhBfBsoQi5qcGc=?="
Content-Transfer-Encoding: base64
/9j/4AAQSkZJRgABAQEAAQABAAD//gAplceOhk1ha2VyIFByb4Fpjo6XcJTFgWqCxY3skKyCtYLc
…
VuPsLgyMdaQrJxrW77kHHMJmmm02fhpn/Ci1xwcHpP71Lj3fxmiv/9k=
--Multipart_Fri__04_Jan_2002_00:32:16_+0900_082a6640--
No.34