#author("2023-01-18T17:48:00+09:00","","")
#author("2023-01-22T21:09:57+09:00","","")
* [UTF-8] UTF-8に移行したサイトに、移行前のページ名(URL)に対するアクセスがあった場合のケア [#ned71a9e]

- 元タイトル: EUC-JP -> UTF-8移行後のページ名について

- ページ: [[BugTrack]]
- 投稿者: [[okkez]]
- 優先順位: 低
- 状態: 完了
- カテゴリー: プラグイン
- 投稿日: 2006-09-22 (金) 01:14:26
- バージョン: 1.4.7
- リリース予定バージョン: 1.5.4

** メッセージ [#a900a439]
EUC-JP -> UTF-8に移行した場合、旧ページ名((日本語を含む))へのアクセスが悲しいことになります。


PukiWiki 1.5.4 での対策:

PageURIHandler を使ってリダイレクトを行う。

pukiwiki.ini.php:

 // Page-URI mapping handler ( See https:// pukiwiki.osdn.jp/?PukiWiki/PageURI )
 class EucjpUtf8RedirectPageURIHandler extends PukiWikiStandardPageURIHandler {
        function filter_raw_query_string($query_string) {
                if (! $query_string) {
                        return $query_string;
                }
                if (strpos($query_string, '&') !== FALSE) {
                        return $query_string;
                }
                if (strpos($query_string, '=') !== FALSE) {
                        return $query_string;
                }
                if (strpos($query_string, '%') === FALSE) {
                        return $query_string;
                }
                $page = rawurldecode($query_string);
                if (mb_check_encoding($page, 'UTF-8')) {
                        return $query_string;
                }
                if (! mb_check_encoding($page, 'CP51932')) {
                        return $query_string;
                }
                $utf8_page = mb_convert_encoding($page, 'UTF-8', 'CP51932');
                if (!$utf8_page) {
                        return $query_string;
                }
                $location = get_page_uri($utf8_page, PKWK_URI_ROOT);
                header('HTTP/1.0 302 Found');
                header('Location: ' . $location);
                exit;
        }
 }
 $page_uri_handler = new EucjpUtf8RedirectPageURIHandler();


このコードを pukiwiki.ini.php の $page_uri_hanlder がある行と置き換えてください。

以下の情報は、PukiWiki 1.5.4より前の過去の議論と、動作の説明です。

----

とりあえず悲しさを軽減できるパッチを作ったので参考までにどうぞ。 ([[okkez]])

 Index: read.inc.php
 ===================================================================
 --- read.inc.php	(revision 225)
 +++ read.inc.php	(working copy)
 @@ -25,7 +25,15 @@
  
  	} else {
  		// 無効なページ名
 +		if ('EUC-JP' === mb_detect_encoding($page)) {
 +			$page = mb_convert_encoding($page, 'UTF-8', 'EUC-JP');
 +			$body = make_pagelink($page);
 +			return array(
 +				'msg'=>'maybe this page?',
 +				'body'=>$body
 +			);
 +		}
  		return array(
  			'msg'=>$_title_invalidwn,
  			'body'=>str_replace('$1', htmlspecialchars($page),

*** PukiWiki 1.5.4 での対策 [#ud3d0591]

EUC-JPの日本語文字のうちそのバイナリ列をUTF-8文字として解釈できるのは以下の930文字

 与丐丕丙両个丱丶丹丼丿乂乃之乏乖乘乢亂亅了予亊于亞亟亠亡亢亮亰亳亶仂仄仆仍从仏他
 仗任伐伴但佑余佞併侫侶促俗俵側傍傳僂僉僊働僖僚僞僣僥僭僮僵價儁儂儉儔儕儖儚儡優儷
 儺儻儼儿兀兌兒兔兢八六兵其典冥凌函分判則剖劉劬劭労劵劼勁勅勇勍動勗務勞勠勣勦勳勵
 勸勹匆匈匍匏匐匕匚匣匯匱匳匸匹匿區半卒単即友反叩同名吻呂味命咤咫咯咼咾哂哘哢哥哦
 哭哮哲哺哽唏唔售唯唳唸唹啀啅啌啖啗啜啝啣喀喊喙嗇嘆噴噺嚢圈國圍圓圖團圜圦圷圸圻址
 坊坎坏坡坦坩坿垈垉垓垠垤垪垰垳埀埃埆埒埔埜堂塀塙填墳夕多夢天奪奮奸妁如妊妍妙妛妝
 妣妨妲姆姙姚姜姨姫娉娑娘娚娜娟娥娵娶婀婁婉婢婪婬婿媚媛媼媾嫂嫋存孫孱宥密寧尊導尿
 屏屐展属屬屮屶屹岌岑岔岫岬岶岷岻岼岾峅峇峙峠峩峪峭峺峽崋崕崗嵜嶌巳巽帖帳帽幡幣平
 年幽庁店廊廖廚廛廝廡廢廣廨廩廬廰廱廳廴廸廼廾弃弄弉弋弌弍弑弔弖弗弩弭弯張弸弼彁彈
 彌彎彜彝彦彪彫律徴徹必忍忘忙忰念息悄悋悒悖悗悛悠悧悩悴悵悸悽惆惓惘惠惡惱惴惶惷惺
 惻愀愃愆愍愎愕愡慍慮憂憤憧懲戞戡截戮戰戲戳房扁扎払扛扞扠扣扨扮扼找抂抃抉抒抓抔抖
 抜抬抻担拆拏拑拔拗拿挑捉捗捻掠探揃揖損摘撚撞撤撻擂擅擇擒擔擘據擠擡擢擣擧擯擱擲擴
 擶擺擽攀攅攘攜攣攤攫攬攴攵攷敵文旅族旦昿暢暴暸曄曖曚曠曦曩曰曵曷有朏朕朖朗望朝朞
 朦朧未朮朶朷朸朿杁杆村杙杞束杠杣杤杰枉柊某柚桧棆棔棕棗棚棠棣棧棯棹椄椋椒椚椡椣椥
 椨椪椰椶椹椽楔楙楜楫楮楴楷楸楹楼楾榔標樽檗檪檬檳檸檻櫂櫃櫑櫓櫚櫞櫟櫨櫪櫺櫻欅欒欖
 欟欷欸欹歃歇歉歎歐民氷沸沺法泙泛泡泥泪泯洌洒洙洞洟洫洳洵洶洸洽流浙浚浣浤浪浹涅涌
 涎涓涕涵淇淡淵淹添渊渕測湊湛湧溌溜溺滴滷漂漏漓漫漾潘潛潦潭潮潯潸潺潼澀澁澂澆澎澑
 澡澣澤澪澳澹濂濃濆濔濕濘濟濡濤濬濳炉炭烹焚無熱燃牒牟牢物狸狼猫猶猷率琉瓢甜由甸町
 畑留畠畢略疋痢発百的盜直眠眺瞳矛短砲硫硲祐祢票禄福禰稔稗立竜童竪端竸笛筆筈筏箕箪
 箱箸篭粉粍粒粘糞納紐紛続綻縫纏罰老耽聞聴聾肇肋肌肘胞胴能脈脱脳脹腸腹膝膿臓舉舒芳
 菱萄萌葎董葱蓑蓬蓮蔓蔵蕩藤蘖蘗虜蛤蜂蜜蝋蝶融衍表袖裏裕裡複褒覆討訪評認誘誰調諜諭
 謄謬谷豆豊豫豹貼賂賊贈超足路跳踏転輸轍辧辰辿迭逃透速造連逼遊道達遜適邑邦邸郎郵鄭
 醗里釘鉄鉢銅銚鋒錬録鏑鐙長閥闘陶陸隆隼雄離雰霧露霸韮頂頭顛飭飮飽騰髪髭鬱魅魯鮒鱈
 鳥鳩鳳鴇鵡鵬麓鼎鼻龍

これ以外の文字が1文字でも含まれているページであれば、 mb_check_encoding($eucjp_page, 'UTF-8') が FALSE になる。

さらに、mb_check_encoding($eucjp_page, 'CP51932') がTRUEなものを UTF-8 変換してリダイレクトすれば、
旧URLにアクセスした場合でもUTF-8変換後の同盟ページにアクセスできる

救えない (リダイレクトされない) のはUTF-8として解釈しても問題ない930文字のみで構成されたページ名。
これは十分少ないと推測できる。




調査用コード:

 for ($i = 127; $i <= 65536; $i++) {
     $c = IntlChar::chr($i);
     $c_eucjp = mb_convert_encoding($c, 'CP51932', 'UTF-8');
     $c_utf8 = mb_convert_encoding($c_eucjp, 'UTF-8', 'CP51932');
     if ($c === $c_utf8) {
         if (mb_check_encoding($c_eucjp, 'UTF-8')) {
             echo $c;
         }
     }
 }

PageURIHandler を使って対策

pukiwiki.ini.php:

 // Page-URI mapping handler ( See https:// pukiwiki.osdn.jp/?PukiWiki/PageURI )
 class EucjpUtf8RedirectPageURIHandler extends PukiWikiStandardPageURIHandler {
        function filter_raw_query_string($query_string) {
                if (! $query_string) {
                        return $query_string;
                }
                if (strpos($query_string, '&') !== FALSE) {
                        return $query_string;
                }
                if (strpos($query_string, '=') !== FALSE) {
                        return $query_string;
                }
                if (strpos($query_string, '%') === FALSE) {
                        return $query_string;
                }
                $page = rawurldecode($query_string);
                if (mb_check_encoding($page, 'UTF-8')) {
                        return $query_string;
                }
                if (! mb_check_encoding($page, 'CP51932')) {
                        return $query_string;
                }
                $utf8_page = mb_convert_encoding($page, 'UTF-8', 'CP51932');
                if (!$utf8_page) {
                        return $query_string;
                }
                $location = get_page_uri($utf8_page, PKWK_URI_ROOT);
                header('HTTP/1.0 302 Found');
                header('Location: ' . $location);
                exit;
        }
 }
 $page_uri_handler = new EucjpUtf8RedirectPageURIHandler();

UTF-8としてinvalidなページ名のリクエストが来たら、リクエストをEUC-JP(CP51932)とみなしてUTF-8に変換してリダイレクトする。本体コードに手を入れずに対応が可能。

詳細ロジック:

- (1) クエリ文字列中に '&' や '=' が入っていたらリダイレクトしない (プラグイン呼び出し ではリダイレクトしない)
- (2) クエリ文字列中に '%' がなければリダイレクトしない (日本語文字列がなければリダイレクトしない)
- (3) クエリ文字列の rawurldecode() 結果がUTF-8として正しければリダイレクトしない
-- UTF-8バイナリとして正しいURLであれば新URLでのアクセスとみなす
- (4) クエリ文字列の rawurldecode() 結果をEUC-JP → UTF-8 変換結果が文字列になっていれば、リダイレクトを行う
-- 旧 EUC-JP のURLとみなす


--------
- コメントありがとうございます。重要度と影響範囲を判断できるような状況添えていただければ助かります。例:どのユーザーでも必ず起こるのか、何か適切な手順を踏まなかった時に発生するのか、本来は絶対に起こらないのか。 -- [[henoheno]] &new{2006-09-24 (日) 14:23:12};
-- [[okkez:memo/改造/UTF-8化#n5876a19]] EUC-JP 時代のページ名にアクセスされてもとりあえずUTF-8に変換したリンクを表示するパッチ の件ですね。少しタイトルを修正します。 -- [[henoheno]] &new{2006-09-24 (日) 14:26:04};
-- この件は、元々EUC-JPで公開していたサイトや、相手方がInterWikiの設定を間違えている時にしか発生しないアクセスをケアするためのものです。そのため、上記パッチはEUC-JPのサイト向けのものではないようです。その旨のコメントか、if文がいりそうです。 -- [[henoheno]] &new{2006-09-24 (日) 14:57:45};
-- 汎用化する場合: 上記パッチは UTF-8 化したサイトに対する EUC-JP のケアですが、EUC-JPのサイトにUTF-8化したページ名によるアクセス(InterWikiの設定を間違えている)があった時でも、同じアイデアでフォローできる可能性があると思われます。また、上の例では定数 SOURCE_ENCODING の値が UTF-8 でない時は無効にするのが良さそうですね。 -- [[henoheno]] &new{2006-09-24 (日) 15:01:09};
--- 本家に取り込む場合はそのようにするべきだと思います。-- [[okkez]] &new{2006-09-24 (日) 19:38:17};
- official/devからのアクセスがきっかけになった予感が。 -- [[henoheno]] &new{2006-09-24 (日) 15:04:19};
-- 実はofficial/devはInterWikiを以前、設定しなおしたので問題なかったのです。アクセスログを確認したところ結構色々な人のページでInterWikiを使わずにEUC-JP時代のURIを直接記述しているケースがありました。全てのサイトを修正して回ったりは流石にできないのでこんなパッチを作りました。 -- [[okkez]] &new{2006-09-24 (日) 19:38:17};
-  前後の状況が解ったところで、対応の適切さの件。okkezさんの所に "本当は、変換後のページが存在したらリダイレクトさせたい" とある通りで、  HTTP Locationヘッダで飛ばす方法もあるかもしれませんね。また、(1)指定されたページはないが (2)推測に基づいた別のページならある 時に発動させるべきものなので、そのページが本当に存在するのか確認を入れるのが良さそうです。 -- [[henoheno]] &new{2006-09-24 (日) 15:09:54};
-- リダイレクトさせる場合についてはその通りですね。 -- [[okkez]] &new{2006-09-24 (日) 19:38:17};
-- 各種コメントありがとうございます。あれから少し考えたのですが、ノータイムでLocaitonヘッダを出すのは、文字コード識別関数を信用しすぎで危ないので、やはり事前に移動先のページの存在確認を行った方が良さそうです。 -- [[henoheno]] &new{2006-09-24 (日) 19:47:48};
-- ページが存在しない場合でも、validなページ名の場合は移動させてもいいんじゃないでしょうか。存在しないページ名の場合は単に新規作成になるだけですし。ただし文字コード変換後invalidなページ名になる場合には移動させるとマズイと思います。 -- [[okkez]] &new{2006-09-24 (日) 20:26:29};
- [[開発日記/2015-01-03]]: UTF-8版の利用を推奨、[[BugTrack2/186]]: UTF-8版関係のまとめ --  &new{2016-01-18 (月) 21:58:25};
- PukiWiki 1.5.4 のページURLカスタマイズのPageURIHandlerを応用して、EUC-JPの時のURLへのリクエストを救うことができます。状態を完了としました -- [[umorigu]] &new{2021-12-10 (金) 22:47:13};
-- 「EUC-JPの日本語文字のうちそのバイナリ列をUTF-8文字として解釈できるのは以下の930文字」 思ったより多い -- [[umorigu]] &new{2021-12-10 (金) 22:48:22};
- このサイト (PukiWiki-dev) も 1.5.4 にバージョンアップを行い、PageURIHandler ( EucjpUtf8RedirectPageURIHandler ) を使った EUC-JP→ UTF-8 URLリダイレクトに切り替えました -- [[umorigu]] &new{2021-12-11 (土) 16:41:10};
- すみません、いろいろコードが書いてありますが、最終的にどれをどうすればよいのでしょうか? -- [[harrek]] &new{2023-01-16 (月) 15:12:08};
- Pukiwiki 1.5.4 であれば自動的に適用されているのではないかと思われます。 -- [[ぬぺぺ]] &new{2023-01-17 (火) 17:45:41};
- 適当に開いてた日本語ページ名のURLをエンコードしてURLにしてみましたが、ちゃんと効いてますね。UTF-8: https&#58;//pukiwiki.osdn.jp/dev/?%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3/%E9%96%8B%E7%99%BA%E8%80%85%E5%90%91%E3%81%91&br;EUC-JP: https&#58;//pukiwiki.osdn.jp/dev/?%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3/%B3%AB%C8%AF%BC%D4%B8%FE%A4%B1 -- [[ぬぺぺ]] &new{2023-01-17 (火) 17:52:18};
- 『いろいろコードが書いてありますが、最終的にどれをどうすればよいのでしょうか? 』 → 一番上の「PukiWiki 1.5.4 での対策:」の直後のコードを pukiwiki.ini.php の $page_uri_handler のところに書いてください。EUC-JPで運用していたサイトをUTF-8に移行した際に使うものなので、自動適用ではありません -- [[umorigu]] &new{2023-01-17 (火) 19:59:53};
-- 例えばこういうURLです: https:// pukiwiki.osdn.jp/dev/?%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3/%B3%AB%C8%AF%BC%D4%B8%FE%A4%B1 -- [[umorigu]] &new{2023-01-17 (火) 20:02:50};
- dev限定だったんですね。失礼しました。ありがとうございます。 -- [[ぬぺぺ]] &new{2023-01-18 (水) 17:48:00};
- ありがとうございます。試してみます。 -- [[harrek]] &new{2023-01-22 (日) 21:09:57};

#comment

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.175 sec.

SourceForge