その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

RFC2045におけるContent-TypeのBNFに関して

(BNFの読み方を間違えているかもしれません.その際はご指摘お願いします)

[追記]
id:nobuokaさんのブログが非常に参考になるので,併せて御覧ください.
HTTP の media type の記述中に空白文字を入れても良いのかどうか
[追記ここまで]

さて,RFC2045にて示されているContent-TypeのBNFは以下のとおりです.

content := "Content-Type" ":" type "/" subtype
           *(";" parameter)
           ; Matching of media type and subtype
           ; is ALWAYS case-insensitive.

type := discrete-type / composite-type

discrete-type := "text" / "image" / "audio" / "video" /
                 "application" / extension-token

composite-type := "message" / "multipart" / extension-token

extension-token := ietf-token / x-token

ietf-token := <An extension token defined by a
               standards-track RFC and registered
               with IANA.>

x-token := <The two characters "X-" or "x-" followed, with
            no intervening white space, by any token>

subtype := extension-token / iana-token

iana-token := <A publicly-defined extension token. Tokens
               of this form must be registered with IANA
               as specified in RFC 2048.>

parameter := attribute "=" value

attribute := token
             ; Matching of attributes
             ; is ALWAYS case-insensitive.

value := token / quoted-string

token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
            or tspecials>

tspecials :=  "(" / ")" / "<" / ">" / "@" /
              "," / ";" / ":" / "\" / <">
              "/" / "[" / "]" / "?" / "="
              ; Must be in quoted-string,
              ; to use within parameter values

これを雑な感じに解釈すると,text/html;charset=UTF-8;foo=barみたいなContent-Typeになると思います.まあよく見るContent-Typeですね.

ただ,ブラウザによってこのContent-Typeのルールが微妙に異なっていて,なんじゃあこりゃあという感じになったので備忘録的にまとめます.

なお,動作確認に用いたブラウザは

です.その他については確認していません.

確証は無いので参考程度に留めて頂ければと思います.

1. parameterのセミコロン区切りの部分に空白を入れても動く (Firefox, Chrome, Safari, IEで動く)

text/html ; charset=UTF-8 ; foo=barのようにしても動きます.
これはよく見かけるからなんとなく良さそうですが,BNF的に正しいのかどうか.まあ,検証に用いたブラウザ全てで動いたのでまあ良いのかしら……

2. attributeとvalueをイコールで結んでいる部分に空白を入れても動く (FirefoxChrome, IEで動く)

text/html;charset = UTF-8;foo = barという風にしても動きます.これは変な挙動な感じがする.現にSafariでは動いていない.

3. typeとsubtypeを隔てているスラッシュに空白を入れても動く (FirefoxChromeで動く)

text / html;charset=UTF-8;foo=barという風に書いても動きます.これは気持ち悪いですね.

4. type/subtypeの部分を任意の場所にぶっ込んでも動く (FirefoxChromeで動く)

charset=UTF-8;foo=bar;text/htmlという風にしても動きます (この例だとtext/htmlが末尾に置かれている).
これは多分,挙動として一番おかしい.BNFがガン無視されている.
もちろんcharset=UTF-8;text/html;foo=barと書いても動いてしまう.どこにtype/subtypeを書いても動く!!!
FirefoxChromeが頑張りすぎている気が……

結論

変なContent-Typeを書くな!!!!