# CTCP PUSHURL

IRCのCTCPにPUSHURLコマンドを追加する提案です。

この提案は現在のDCC SENDに感じた問題への対応として書きました。 DCC SENDとの互換性を保った形では認証やリジューム等のネゴシエーションに限界があるため、 新しいCTCPリクエストという形になりました。

送信側は簡易HTTPサーバを実装する場合もありますが、 受信側の対応はかなり簡単にすませることも可能です。

### 仕様

CTCP PUSHURL リクエストは特定のURLを受信側に通知し、何らかの動作を促します。 また、ダウンロードを促す場合は保存するファイル名についての情報を補います。

対応するCTCPリプライ/レスポンスはありません。

リクエストには以下のパラメータが続きます。

引数1
  推奨する扱いを示します。

  DOWNLOAD | ダウンローダで開く
  BROWSE | ブラウザで開く
  STREAM | winamp,MediaPlayer,readPlayer等のストリーミング再生が可能なプレイヤーで開く

  DOWNLOAD以外は引数は2までです。 DOWNLOADだった場合は引数は4つで、送信側が省略できるものはありません。

引数2
  対象のURLを示します。 受信したクライアントはここに悪意のある指定が行われていないか確認するべきです。

  scheme://id:pass@host:port/path?param=key&#markey 等の指定を読める必要があります。 hostの前の@、末尾の#markeyはURLの一部ではありませんが、それでも扱えるようにしなければなりません。 また、スキームは http とは限りません。

引数3
  対象のファイル名の文字セット名です。 文字セット名はRFC 2278: IANA Charset Registration Proceduresの 規則に準拠します。一覧はIANA Charset Registryにあります。

  受信側は知らない文字セット名を受け取った場合に以後の引数のパースを中断して、 なにか代用になる無害な名前を作成するかもしれません。

  送信側はなるべく普段メッセージを送信するのに使用しているものと同じ 文字セットを選択するようにしてください。

引数4
  対象のファイル名を引数3の文字セットで表現します。これはベース名で、フォルダやディレクトリやボリューム名を含みません。 受信したクライアントはここに悪意のある指定がないか確認するべきです。

  ファイル名は以下のような理由で用意されました。

  - URL内部のpathには文字コード名の指定がない
  - ダウンローダによってはURL内部の文字コード名を特定の文字コードでしか扱えない

### 受信側の実装

最も悪い対応は、無条件にそのURLを開くことです。 悪意のあるURLを脆弱なブラウザで開くべきではありません。

許容できる最低限の対応は「受け取ったCTCPをクリップボードへのコピーが可能な場所に表示すること」です。 ユーザはURLをコピーして後は自分のブラウザやダウンローダで処理するでしょう。 いまどきのIRCクライアントならクリッカブルURLはすでに持っているのでユーザ側の手間はあまりありません。

ただしこの場合はPUSHURLコマンドの目的、何らかの動作を促すことは実現できていません。 示されたリソースは後からでも参照できるとは限らないため、ユーザはメッセージを見落とした場合に不便を感じるかもしれません。

好ましい対応の一つは受信について何らかの方法でユーザに通知して対応を選択させることです。 これはユーザインタフェース的にはDCC SENDへの対応とほぼ同じですが、 クライアント自身がURLで示されたリソースを受信するのではなく、 外部のブラウザやダウンローダを利用することが可能です。 ただしクライアント単体で受信処理が完結することを好むユーザもいるでしょう。

HEADリクエストを発行してリソースについての情報を取得することは有用かもしれません。 またURLがlocalhostや内外のホストのポート21,22,23,25等を示していた場合にはそれを捨てるのも有用でしょう。 ただし本来はこれらはブラウザやダウンローダやプロクシが行うべき領分です。

### 送信側の実装

すでにあるURLを通知するだけの場合、 コマンド文字列を組み立ててCTCPリクエストを出してください。 返事を待つ必要は特にありません。

DCC SENDの変わりにこのコマンドを使う場合、 簡易HTTPサーバを内蔵するか他のHTTPサーバと連携することになります。

送信側が簡易HTTPを内蔵するのにかかるコストですが、 たとえばURLを http://nick:OTP@host:port/request_id のようなURLにして、 実際にはrequest_idをキーにして内部で決めたファイルを送信する、 という実装なら、DCC送信と比べた場合のコストはそれほど多くないと思います。 差はHTTPヘッダのパースだけでしょう。

CTCP PUSHURLは全く普及していないので、URLを通知するのに普通のプライベートメッセージを使うオプションは有用かもしれません。

### 利点

- 認証を自由に設定できます。
- クライアント側からリジュームを起こす場合にIRCメッセージをやり取りする手間がありません。
- DCC SENDと比べた場合、NATの設定がラクです。たいていのDSL向けルータはHTTPのSNAT機能を持っています。
- 外部のHTTPを理解できるソフトウェアに処理をまかせることができます。もちろん自前で受信するのも可能です。
- HTTPのために書かれたコードは豊富に出回っているので、それらを再利用すれば実装にかかるコストはかなり軽減できます。