SuperSwikiからのプロジェクト起動処理

http://d.hatena.ne.jp/korakurider/20050830/p1 で、SqL05がSuperSwiki上のプロジェクトを開けない問題が判明しました。これをもう少し調べました。(環境がないので、Windows上だけしか調べていません)

判明している現象

SuperSwiki上の日本語名(ascii以外の文字を使っている)プロジェクトを開こうとするとエラーになります。

  • ブラウザプラグインとして、HTMLページに埋め込まれたプロジェクトを開く場合
  • (新たに見つかった問題)ナビゲータの「探す」で、サーバー上のプロジェクトを選択して開く場合

直接の原因と回避策

Nihongo7までのバージョンのSqueakでSuperSwikiに投稿された日本語名のプロジェクトは、シフトJISコードでパーセントエンコーディングされたファイル名になっています。したがって、埋め込まれたHTMLページ中のアンカーは、パーセントエンコード済みファイル名へのリンクになっています。
例えばSqueakがブラウザプラグインとして起動される場合、この「シフトJISでパーセントエンコード済みファイル名へのURL」が渡されており、それが ProjectLauncherにスクリプト名として引き渡されています。
その後、PluginHTTPDownloadRequest>>for:in: (HTTPDownloadRequestの実装を継承)で、リソースのURLを登録する際、HTTPDownloadRequest>>httpEncodeSafelyが呼ばれます。以下はその処理の内容です:

httpEncodeSafely: aUrl
	"Encode the url but skip $/ and $:."
	| unescaped |
	unescaped _ aUrl unescapePercents.
	^ unescaped encodeForHTTPWithTextEncoding: 'utf-8'
		conditionBlock: [:c | c isSafeForHTTP or: [c = $/ or: [c = $:]]].

やっていること:

  • 最初のステップで String>>unescapePercents は、特定の文字コード(私のパッチをあてたあとは、utf8)でエンコードされていることを前提に、パーセントエンコードを解除しています。
  • 次のステップで、String>>encodeForHTTPWithTextEncoding:conditionBlock: で、再度utf8でパーセントエンコードします。

起きていること

  • 最初のステップにシフトJISエンコードされたaUrlを渡しているため、化けてしまいます。
  • パーセントエンコーディングで使用する文字コードは、RFCの規定上では個々のHTTPサーバーインスタンスに依存することになっています(つまり規定がない)。仮に最初のステップの変換が正しく行われていたとしても、SuperSwikiサーバーにとっては、元々のシフトJISベースのURLと、UTF8ベースのURLは別のリソースということになってしまいます。

回避策:
そもそも PluginHTTPDownloadRequest>>for:in: で、HTTPDownloadRequest>>httpEncodeSafelyを呼ばないようにしてしまうと、Squeakland.jp上の日本語名のプロジェクトを開けるようになりました。
またそのままのコードで、日本語名のローカルファイルのプロジェクトも起動できています。

考察

オリジナルのコードでは、前回の書き込み分も含め、起動するよう指定されたプロジェクトのURLは、実際にそれを開くまでに以下の変換が行われていました。

全体の処理の流れだけ見ると、パーセントエンコーディングあり/なしが意味的に等価なものであると決め付けて、中で勝手にコーディング・デコード処理を行ってるように思われます。この前提が間違っているように思われるのです。

そもそも、以下のように動かなければならないような気がします。

  • 既存のプロジェクトを開く場合、指定されたURLを変換することなくそのまま使用する
  • プロジェクトを保存する場合のみ、サーバー側が受け付ける適切なコードでパーセントエンコードして保存する。(何のコードを使うかの懸案は残ります)

残る課題

  • ローカルファイル名が元々パーセントエンコードされたものだったら、今のロジックだと開けないような気がする(未テスト)。
  • プロジェクト保存処理のテスト。
  • SuperSwikiに保存する際のパーセントエンコード文字コードの決定(シフトJIS or utf8)
  • 上記の修正をかけたイメージで、日本語フォント未ロードで現在ロケールが英語の状態で、Squeakland.jp上の日本語名のプロジェクトを開いた時、フォントの自動ロードが走らず文字が化けるものがありました。(走るものとはそうでないものがある)SqL05でロケール設定をシステムが解釈するしかたが微妙に変化したことで、Nihongoシリーズの過去バージョンで作ったプロジェクトを読む際の動作にもう一工夫が必要になっている感じです。
  • いずれにせよ、ちゃんとテストケースを洗い出さないといけないみたい。

最大の懸案

局所的な変更ならまだいいですが、こんな広い範囲にわたる変更の正当性を、英語で、皆さんに説明して理解してもらい、accept/commitしてもらうのは難儀ですな。長い説明だと皆さんあまり読んでくれてないようだし。さあどうしよう??