Archive for the ‘ネットワーキング’ Category

URL の最大長は何文字?

土曜日, 6月 23rd, 2007

ユーザーエージェントおよびサーバの実装に依存します。スキーム、ホスト名を含めて、255 バイト以下は安全です。メジャーなブラウザとサーバに限定すれば、2000 バイト程度までは使えるでしょう。

  1. SGML では 1024 文字
    HTML のスーパーセットである SGML では、LITLEN=1024 文字とされています。
    RFC2070 | URL の長さの制限って | HTML 4のSGML宣言
  2. HTML 4.01 では 65536 文字
    HTML 4.01 では LITLEN=65536 文字です。
  3. HTTP では未定義、255 バイト以下を推奨
    RFC2616 (HTTP/1.1) には、URL の長さに関する規定はありません。ただし、

    Note: Servers ought to be cautious about depending on URI lengths above 255 bytes, because some older client or プロキシ(proxy) implementations might not properly support these lengths.

    と、255 バイト以下が推奨されています。

  4. Internet Explorer は 2083 バイト
    URL の最大長が 2083 バイトです。
    「URL に使用可能な文字数は最大 2,083 文字」
    IE3.02 のころは 1KB 程度だったようです。
  5. Mozilla/Firefox は事実上無制限
    少なくとも 2MB (200 万文字)は送信可能なことを確認しました(後述)。ソースコードは未確認ですが、事実上無制限と考えてよいでしょう。
    ただし、あまりに長い URL は、アドレスバーが表示されなくなる、極端に動作が遅くなる、などの不具合があります。
  6. その他のブラウザ (Opera, NetFront など)
    未確認
  7. Apache は 8177 バイト
    Apache HTTP server では、HTTP リクエスト行の長さが LimitRequestLine を超えると、414 Request-URI Too Large エラーを返します。
    LimitRequestLine のデフォルト値は 8190 バイトです。Apache 2.0 では 0 からDEFAULT_LIMIT_REQUEST_LINE (=8190)の間で設定可能です。Apache 2.2 では任意の値にセットできます。
    通常のリクエスト行は
    GET <url> HTTP/1.1
    ですから、url 部分の最大長は 8177 バイトということになります。
  8. 実験

    <html>
    <form action=”show.php”>
    <textarea name=”t” ></textarea>
    <input type=”submit”>
    </form>
    </html>

    のようなフォームでデータを送信してみました。

    Internet Explorer 6 + Apache 2.0 の場合
    2083 バイトまでは送信可能です。それ以上は submit ボタンを押しても送信しなくなります。

    Firefox 1.5 + Apache 2.0 の場合
    8177 バイトまでは送信可能です。それ以上は 414 Request-URI Too Large になります。

    Firefox 1.5 + Apache 2.2 の場合
    LimitRequestLine 十分大きく設定すれば、十分長い URL を送信できます(2MB まで確認)。

  9. 備考
    サーバのファイルシステムの最大文字長や、ドメインの長さなど、他の要因で制限される場合もあります。
    ext2 のファイル名は 255 バイトまで
    ドメイン名は 255 オクテットまで (RFC1034)

proftpd chroot jail

土曜日, 6月 23rd, 2007

Q: proftpd で、

  • グループ vm または virtual に属するメンバーは chroot jail する。
  • ただし、users グループに属するメンバーは chroot jail しない。

とするための設定方法は?

A:
(1) 間違った設定方法

DefaultRoot ~ virtual,vm,!users

これだと、virtual AND vm AND (NOT users) という意味になる。

(2) 正しい設定方法

DefaultRoot ~ vm, !users
DefaultRoot~ virtual, !users

つまり、
 (vm OR virtual) AND (NOT users)
という論理式を、
(vm AND (NOT users)) OR (virtual AND (NOT users))
と展開するわけである。

上記 2 つを実際にやってみると:

=======================================
users   vm      virtual (1)     (2)
---------------------------------------
-       -       -       -       -
-       -       yes     -       yes
-       yes     -       -       yes
-       yes     yes     yes     yes
yes     -       -       -       -
yes     -       yes     -       -
yes     yes     -       -       -
yes     yes     yes     -       -
---------------------------------------

参照:

巨大なデータを扱う Web アプリケーション

土曜日, 6月 23rd, 2007

あるお客様から、数百 MB のファイルをアップロードする Web アプリケーションをつくりたいのだが、という相談を受けました。
CGI なり PHP なりでアップローダーをつくることは難しくありませんが、気になるのが「http でそんな大きなファイルをエラーなく送れるのだろうか?」ということです。

まず、インターネットにおける物理層のビットエラーレートはどのくらいなのでしょうか?

最新ネットワーク

 NTTのデータ通信サービスの誤り率は,回線交換サービスで10-5パケット交換網でも10-10程度と言われています.前者では1MBのデータ中に10Bの誤りが,後者でも10GB中に1Bの誤りデータが紛れ込んでいます.そこで,データ通信にはいたるところに「誤り検出」や「誤り訂正」機能が入れ込まれています.

もちろんインターネットにはさまざまな回線があり、 一概には言えませんが、まあおおむねこんなものでしょう。

上記の「誤り検出」のため、Ethernet パケット、IP パケット、TCP パケットにはそれぞれ CRC が含まれています(CRC はパリティやチェックサムよりもバーストエラーに強く、ハードウェアで実装することが可能だからでしょう)。参照: プロトコル別パケット構成

では、CRC によってどのくらいのエラーが検出できるのか?

 ファイルのCRC編-その1

この確率は各ビットが半々の確率で都合いい方に誤るとして単純に(1/2)kである。よって、
5bitの誤りは1-(1/2)5=31/32
6bitの誤りは1-(1/2)6=63/64
7bitの誤りは1-(1/2)7=127/128
・・・以下同様の確率で検出できる。

一般に TCP は信頼性のあるストリーム伝送であるとされていますが、それはロストパケットの再送機能などのことです。1bit の誤りもなく大量のデータを送受信するには、これでもまだ足りません。10^-10 でもまだ不安、10^-15  で安心という感じでしょうか。

というわけで、TCP よりも上位のレイヤーでの integrity check が必要になります。

さて、ftp や http の場合、それらのプロトコル自体には、エラー検出や自動的な部分再送による訂正といった機能はありません。なんとなく http よりも ftp のほうが信頼性が高いような印象がありますが(たとえば Vector では、ソフトウェアのダウンロードに ftp と http が用意されており、ftp でのダウンロードが標準とされています)RFC959 ファイル転送プロトコル を読む限り、どうやらそれは気のせいのようです(アプリケーションが独自に対応していることはあります)。
一方、bittorrent や Winny では、ファイルのハッシュを照合することによって、データの整合性を確認します。また、ssh では、通信内容の暗号化に加えて、hmac-md5 などによってデータの改ざんを検出します。
参照: エンドツーエンド原理(ダムネットワークと賢い端末)

ということは、SSL でも MAC を使っているので、http:// のかわりに https:// にするだけで、通信の信頼性が高まるのでしょうか? 低品質の回線で数十 GB のファイルを https:// でやりとりして…のような状況でないと違いがわからないかもしれませんが。さて…?

アップローダーでの対策というと、クライアント側で計算したチェックサムをサーバー側で検算するなどが考えられますが、JavaScript ではセキュリティ上の制約からローカルファイルにアクセスできません。Ajax でプログレスバーを表示するくらいがせいぜいです。ActiveX の FileSystemObject や Flash 8 、コード署名した Java Appletであれば可能なようですが…。

おまけ: 各種メディアのエラーレートについて。