たはらさんとこで話題になってるメールヘッダの改行に関する話。メーリングリストの議論と錯綜していて、さらにあっちにコメントを追加するとわけわかんなくなると思うので、こっちに書きます。たぶんいろんなところで議論されてきたことなのだろうけど…。
まず RFC 2822 の該当部分 2.2.3 Long Header Fields を翻訳してみる。
各ヘッダフィールドはフィールド名、コロン、フィールドボディで構成される単一の論理行です。しかし1行あたり998文字、または78文字という制限が設けられているため、ヘッダフィールドの一部であるフィールドボディを複数の行に分割してもいいことにしています。このような行分割をフォルディングと呼びます。
この規格ではルールとして、(単なる空白文字ではない)フォルディングの空白文字を許可します。つまりどの空白文字の前にも CRLF を挿入して良いものとします。
たとえば次のようなヘッダフィールドがあったとします。
Subject: This is a test
これは次のようにも書くことができます。
Subject: This is a test
ざっと読んでも意味わかりにくいけど、「改行したら先頭に1文字空白を入れる」なんてどこにも書かれてないよね。これ、英文(またはそれに準ずる言語)が前提になっているので、日本人にとってわかりにくいのだと思う。
普通の英文で改行ってのはこう書くのね。is の前に空白が入らないことに注意。
This is a test
けど、改行なしで普通に書くとき、空白を挿入する決まりになってる。こんなふうに is の前に空白を入れることになる。
This is a test
つまり改行するかしないかで、空白を取ったり入れたりという操作があるわけ。語の区切りで改行するときは空白を取るのね。で、RFC 2822 に述べられている「フォルディングの空白文字を許可します」の意味は「改行するときいちいち空白を取らないで、そのままにしといてちょうだい。つなげるときは空白を追加せずに、そのままつなぐようにするから」ということなんでしょ。
この規格に従うと、英文の場合常に単語の区切りで改行するから、2行目以降は必ず空白で始まることになる。こんな感じ。
Subject: This is a test
日本語のような「単語を空白で区切らない言語」の存在を知らず、「2行目以降は必ず空白」ってとこだけに注目したプログラマが書いたメーラを使うと、結果的に「継続行の行頭には空白入れないとヘッダの処理が変になる」となるのだと思う。日本人のプログラマも、既存のメーラの仕様がそうなってしまっているから、仕方なく「継続行の行頭は空白」ってことにしてるんじゃないの?違う?
Posted by yasusii at 09:06 PM
そう、そう、そこが引っかかったんです<空白だけに着目したプログラマ
foldingのために余計なスペースを入れる件は、(MIME header encodingに悩まされる)マルチバイト圏だけの問題じゃなかったんですね。なるほど…
Posted by たかの at June 01, 2003 01:44 PM | #
なんか話ごちゃごちゃしてきたけど、変なのは私の書いた 「2行目以降は必ず空白」ってとこだけに注目したプログラマが書いたメーラを使うと、結果的に「継続行の行頭には空白入れないとヘッダの処理が変になる」となるのだと思う。 の部分ですね。その前に自分で「2行目以降は必ず空白で始まることになる」って、書いてるんだから。 正しくは RFC 822(2822) においてフォルディングは「空白の直前に CRLF を挿入」するという決まりになっている。これにより形式上のルールとしては2行目以降の行頭は必ず空白で始まることになる。しかしフォルディングしたい行の中に必ず空白があるとは限らない。現実のアプリケーションでは行中に空白がなくてもフォルディングしたい場面があるのだが、スペース挿入に関する規定が rfc に書かれていないため、各実装で仕方なく独自のルールで空白を挿入することになる。 ですよね。 試しにもうひとつこんなサブジェクトを使ってメールを送信してみました。 Subcject: Subcject:Subcject:Subcject:Subcject:Subcject:(延々と続く) Mozilla Mail では一定の長さを越えるとコロンの後でフォルディングされました。受信側のメーラによってはアンフォルディングの際、サブジェクトに本来なかった空白が現われる結果となります。
Posted by yasusii at May 31, 2003 10:05 PM | #
なんかポロポロ思いつきで追加するのはよくないですね、汚しちゃってすみません。 日本語文字列が短い複数のMIME token…じゃなくってatomだそうですが…に分割される理由は、2822じゃなくって2047を読んだほうがよいかもです。 http://www.mars.dti.ne.jp/~torao/rfc/rfc2047-ja.txt
http://www02.so-net.ne.jp/~hat/mailer/rfc.ja.html
Posted by たかの at May 31, 2003 03:25 PM | #
ではMIME tokenとなるべきUS-ASCII以外の2バイトcharの場合はどうするんでしょうか? というか、どうするのを正「とすべきだった」んでしょうか?
少なくとも、日本の現状では私の書いた通りだという認識でいます。
Posted by たかの at May 31, 2003 12:49 PM | #
# 新しいコメントが上に来るのは読みにくいですね。あとで直します。 rfc 822 にも 1文字「以上の」スペースを冒頭につけるとは書かれていませんよ。 3.1.1. LONG HEADER FIELDS The general rule is that wherever there may be linear-white-space (NOT simply LWSP-chars), a CRLF immediately followed by AT LEAST one LWSP-char may instead be inserted. 「1個以上の空白文字の直前に CRLF を入れても良い」としか書かれてません。 英文ならこれだけのルールで行頭は必ず空白になるんですよ。なぜなら CRLF は空白の直前にしか入れられないんですから。じゃあ空白がないときは?途中に空白がない場合はいくら長くても改行できないんです。それが英文の決まりです(ハイフネーションは除く)。たとえばこんなヘッダ Subject: longlonglonglonglonglonglonglonglonglong(以下延々と続く)
Mew と Mozilla Mail で試してみたところ、予想通りどちらもフォルディングされずにそのままで送信されました。
Posted by yasusii at May 30, 2003 10:29 PM | #
さらにまちがい…。FSWじゃなくってFWS、obs-FSWじゃなくってobs-FWSです。とほほー。
Posted by たかの at May 30, 2003 03:36 PM | #
いけね、2822ではWSPキャラクタじゃなくってwhite spaceで割れって書かれてるんですね。訂正訂正。 で、続きですが、このへんのルール(とくにunfoldingについて)、日本語のメーラ作者も悩んでいたはずです。本来はスペースはスペースとして扱うべきなんだけど、MIME分割のために分けたくないものを分けているケースもあり、杓子定規にスペースとして扱うのはヤだなぁと。
以前自分が実装したときには、Bエンコード(not Base64)ISO-2022-JPなMIME tokenの場合にだけ、white spaceを省くっちゅー、かなりトリッキーなことをしていたような記憶があります。
Posted by たかの at May 30, 2003 03:34 PM | #
いやこれ、いわたさん勘違いしてませんか。どっちにしても一つ以上のスペースは必須ですよ。 「してもよい(may)」がかかってくるのは、ヘッダとは”word-char:”で示される単一行であるべきだとされているけれども、文字数制限に引っかかるので分割「してもよい」という意味です。 で、旧RFC822では1文字「以上の」スペースを冒頭につけることになっていて、何文字入れてもよかったんです。これは2822ではobs-FSWとして「古い仕様だけど、そうやってもよい」となっています。 2822ではハッキリとFSWは1文字「だけ」入れるのだと定義しているんです。
もとより、もし分割時にスペースが全く無くてもよかったら、本当のヘッダとfoldされた続きとの識別ができなくなってしまいます。まぁ「がんばればできなくもない」と言われればそうなんですが、RFCで規定されるプロトコル類が「リソースの少ないハードウェアでも実装しやすいことを目指している」ことを考えれば、わざわざ識別しづらい仕様に改悪するのは不自然です。
Posted by たかの at May 30, 2003 03:24 PM | #