トップ回答者
WebDAV上のフォルダ作成で文字化け

質問
-
Vista側からWebフォルダを開いた状態で、漢字名のフォルダ作成やファイル名
を漢字に変更すると文字化けしてしまいます。文字化けしたファイルはクライアント
側からアクセス不可となります。
漢字名のフォルダやファイル名のコピー等は問題ありません。
Windows Server 2003に対してはこのような問題は起きていません。
どのように対処すればよいのでしょうか。
WebDAV環境
Windows Server 2008 Entrprise (x64) SP1
IIS 7.0 + webdav_x64_rtw.msi
Authentication : Windows Authentication
WebDAV Authoring Rules : All content, Specified Users, Permissin(Read,Source,Write)
Directory Browsing : Enable (All Checked)
Client : Windows Vista ultimate (SP1)
「ネットワークドライブの割り当て」または「IE7の(開く)」からWebフォルダとして開いています。
よろしくお願いします。
2008年11月20日 10:42
回答
-
はじめまして。だどさんと申します。
私も現象を確認しました。
これは WebDAV モジュールの不具合の可能性が高いと思われます。WebDAV のサポートポリシーがどうなっているのか存じませんが、
MS のサポートへ直接問い合わせると良いと思います。詳細は下記に書きますが、IE (またはエクスプローラ) 以外の
(MKCOL ~ MOVE という流れにならない) WebDAV クライアントを
使用することにより、この問題は回避可能と思われます。
概要
====IIS7 の WebDAV モジュールの MOVE メソッドは MBCS を正しく認識しない
調査ログ
========WebDAV ではディレクトリの作成は、MKCOL というメソッドを使います。
例えば abc というディレクトリを作成する場合は次のようにします。
REQUEST: **************
MKCOL /abc HTTP/1.1
Host: localhost
Accept: */*
Authorization: Basic xxxxxRESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 07:55:51 GMT
Content-Length: 0
これにより "abc" というディレクトリが正しく作成されます。
次に、 "テスト" という日本語の名前のディレクトリを作る場合は、"テスト" という文字を UTF-8 エンコードして、さらに URL エンコードし、次のようなリクエストを送ります。
REQUEST: **************
MKCOL /%E3%83%86%E3%82%B9%E3%83%88 HTTP/1.1
Host: localhost
Accept: */*
Authorization: Basic xxxxx
RESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 07:57:59 GMT
Content-Length: 0これで "正しく" テスト という名前のディレクトリが作成されます。
ここまでは問題ありません。
IE をクライアントとした場合の Web フォルダ作成の流れは、一旦異なる名前 (デフォルト "New Folder") のディレクトリを作って、それを別名に変更します。
ディレクトリの名前を変更するときのメソッドは MOVE です。例えば、abc というディレクトリを xyz という名前に変更する場合は次のように、変更後のディレクトリ名を Destination ヘッダで指定します。
REQUEST: **************
MOVE /abc HTTP/1.1
Host: localhost
Overwrite: F
Destination: http://localhost/xyz
Translate: f
Accept: */*
Authorization: Basic xxxxx
RESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 08:02:02 GMT
Content-Length: 0
これで正しく xyz が作成されます。ここで "xyz" という名前のディレクトリを "テスト" という名前に変更する場合は、上記と同様に次のようにします。
REQUEST: **************
MOVE /xyz HTTP/1.1
Host: localhost
Overwrite: F
Destination: http://localhost/%E3%83%86%E3%82%B9%E3%83%88
Translate: f
Accept: */*
Authorization: Basic xxxxx
RESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 08:03:07 GMT
Content-Length: 0
ステータスコードは 201 が返されます。しかし、この結果は文字化けを起こしたディレクトリが作成されます。
回避方法
========上記から、MKCOL による日本語ディレクトリの作成は問題ありません。
しかし MOVE メソッドを実行するときに、文字化けが発生します。このことから、MOVE しないで Web フォルダを作成するクライアントを使用することによって、この問題は回避可能と思われます。
参考
=====参考までに、MultiByteToWideChar 周辺を見れば上の考察の確証が取れると思い、簡単に IIS の動きを見てみました。
とりあえず、この二つにブレークポイントをはって...
0:006> bl
0 e 77025cae 0001 (0001) 0:**** kernel32!MultiByteToWideChar
1 e 7702d198 0001 (0001) 0:**** kernel32!WideCharToMultiByte処理を流します。
0:006> g
Breakpoint 0 hit
eax=00000000 ebx=77025cae ecx=00000000 edx=00000000 esi=01ebf4f4 edi=01c3c350
eip=77025cae esp=01ebf3c0 ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
kernel32!MultiByteToWideChar:
77025cae 8bff mov edi,ediWebDAV からの呼び出しなので確認します。
0:006> kbn 100
# ChildEBP RetAddr Args to Child
00 01ebf3bc 6e952d32 0000fde9 00000008 01ebf430 kernel32!MultiByteToWideChar
WARNING: Stack unwind information not available. Following frames may be wrong.
01 01ebf3ec 6e949a69 01ebf430 0000001c 00000000 webdav!RegisterModule+0x5e97
02 01ebf40c 6e94a2e1 01ebf430 00000000 01c1fe28 webdav+0x9a69
03 01ebf494 6e947d40 01c1f018 01ebf4f4 00000000 webdav+0xa2e1
04 01ebf528 6e94bb7f 01152950 00000100 0115938c webdav+0x7d40
05 01ebf544 70db7035 0115bd18 01c1f070 01c1f01c webdav+0xbb7f
06 01ebf558 70db3696 0115938c 01c1f018 00000000 iiscore!NOTIFICATION_CONTEXT::RequestDoWork+0x128
...
15 01ebf9d0 00000000 741e1e4c 01136eb8 00000000 ntdll!_RtlUserThreadStart+0x1b0:006> da 01ebf430
01ebf430 "/%E3%83%86%E3%82%B9%E3%83%88"これは URL デコードしないままの文字を Unicode に変換しようとしているということです。
0:006> ?0000fde9
Evaluate expression: 65001 = 0000fde9コードページは UTF-8 で問題ありません。
MultiByteToWideChar の結果を見てみます。
0:006> g 6e952d32
eax=0000001c ebx=77025cae ecx=6dfb7879 edx=00000025 esi=01ebf4f4 edi=01c3c350
eip=6e952d32 esp=01ebf3dc ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
webdav!RegisterModule+0x5e97:
6e952d32 8945fc mov dword ptr [ebp-4],eax ss:0023:01ebf3e8=00000000
0:006> dc 01c3c350
01c3c350 0025002f 00330045 00380025 00250033 /.%.E.3.%.8.3.%.
01c3c360 00360038 00450025 00250033 00320038 8.6.%.E.3.%.8.2.
01c3c370 00420025 00250039 00330045 00380025 %.B.9.%.E.3.%.8.
01c3c380 00250033 00380038 00000000 00000000 3.%.8.8.........この後処理を流して出来上がるディレクトリは文字化けをしています。
そこで次に、URL デコードした場合にどうなるか試してみました。
0:006> g
Breakpoint 0 hit
eax=00000000 ebx=77025cae ecx=00000000 edx=00000000 esi=01ebf4f4 edi=01c3c7d0
eip=77025cae esp=01ebf3c0 ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
kernel32!MultiByteToWideChar:
77025cae 8bff mov edi,edi
0:006> kbn
# ChildEBP RetAddr Args to Child
00 01ebf3bc 6e952d32 0000fde9 00000008 01ebf430 kernel32!MultiByteToWideChar
WARNING: Stack unwind information not available. Following frames may be wrong.
01 01ebf3ec 6e949a69 01ebf430 0000001c 00000000 webdav!RegisterModule+0x5e97
02 01ebf40c 6e94a2e1 01ebf430 00000000 01c26b78 webdav+0x9a69
03 01ebf494 6e947d40 01c25d68 01ebf4f4 00000000 webdav+0xa2e1
04 01ebf528 6e94bb7f 01152950 00000100 0115938c webdav+0x7d40
05 01ebf544 70db7035 0115bd18 01c25dc0 01c25d6c webdav+0xbb7f
...
13 01ebf978 77c0e4b6 01136eb8 7cd3a7d1 00000000 kernel32!BaseThreadInitThunk+0xe
0:006> dc 01ebf3bc
01ebf3bc 01ebf4f4 6e952d32 0000fde9 00000008 ....2-.n........
01ebf3cc 01ebf430 0000001c 01c3c7d0 000000b8 0...............
01ebf3dc 01ebf4f4 01c255f5 01c25d00 00000000 .....U...]......
...
0:006> da 01ebf430
01ebf430 "/%E3%83%86%E3%82%B9%E3%83%88"01ebf430 から始まるバッファを URL デコードします。
0:006> eb 01ebf430 2f e3 83 86 e3 82 b9 e3 83 88 00
0:006> dc 01ebf430
01ebf430 8683e32f e3b982e3 45008883 32382533 /..........E3%82
01ebf440 25394225 38253345 38382533 01c26b00 %B9%E3%83%88.k..null 終端なので MultiByteToWideChar の第4引数を -1 にセットしておきます。
0:006> ed 01ebf3d0 ffffffff
結果を見てみます。
0:006> g 6e952d32
eax=00000005 ebx=77025cae ecx=6dfb7879 edx=0000000b esi=01ebf4f4 edi=01c3c7d0
eip=6e952d32 esp=01ebf3dc ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
webdav!RegisterModule+0x5e97:
6e952d32 8945fc mov dword ptr [ebp-4],eax ss:0023:01ebf3e8=00000000
0:006> du 01c3c7d0
01c3c7d0 "/テスト"この後、処理を流すと正常なディレクトリが作成されていることが確認できました。
この結果から、HTTP ヘッダの URL デコードを忘れていることが問題と思われます。
ご参考になれば幸いです。
-----------------------------------------
だどさん http://keicode.com/
2008年11月21日 4:16 -
追記です。
フォーラムで発見した問題 (らきしもの) がモジュールのフィックスまでいけたら、大変素晴らしいことだと思い、US のフォーラムにもポストしてみました。
US IIS Forum Thread:
WebDAV module cannot handle UTF-8 in MOVE methodhttp://forums.iis.net/t/1153253.aspx
さて、どのような話になるでしょうか。
------------------------------------------
だどさん http://keicode.com/
2008年11月21日 15:47 -
こちらの件は、MS に問題を認識してもらえたようで、次の修正に含まれるそうです。
US のフォーラムで回答がありました。
http://forums.iis.net/p/1153253/1889406.aspx
今回の私たちの指摘で修正されたようですね。 IIS の品質向上に一役買ったことになるので良かったですね!
-------------------------------------------
だどさん http://keicode.com/
2009年1月8日 13:38
すべての返信
-
はじめまして。だどさんと申します。
私も現象を確認しました。
これは WebDAV モジュールの不具合の可能性が高いと思われます。WebDAV のサポートポリシーがどうなっているのか存じませんが、
MS のサポートへ直接問い合わせると良いと思います。詳細は下記に書きますが、IE (またはエクスプローラ) 以外の
(MKCOL ~ MOVE という流れにならない) WebDAV クライアントを
使用することにより、この問題は回避可能と思われます。
概要
====IIS7 の WebDAV モジュールの MOVE メソッドは MBCS を正しく認識しない
調査ログ
========WebDAV ではディレクトリの作成は、MKCOL というメソッドを使います。
例えば abc というディレクトリを作成する場合は次のようにします。
REQUEST: **************
MKCOL /abc HTTP/1.1
Host: localhost
Accept: */*
Authorization: Basic xxxxxRESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 07:55:51 GMT
Content-Length: 0
これにより "abc" というディレクトリが正しく作成されます。
次に、 "テスト" という日本語の名前のディレクトリを作る場合は、"テスト" という文字を UTF-8 エンコードして、さらに URL エンコードし、次のようなリクエストを送ります。
REQUEST: **************
MKCOL /%E3%83%86%E3%82%B9%E3%83%88 HTTP/1.1
Host: localhost
Accept: */*
Authorization: Basic xxxxx
RESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 07:57:59 GMT
Content-Length: 0これで "正しく" テスト という名前のディレクトリが作成されます。
ここまでは問題ありません。
IE をクライアントとした場合の Web フォルダ作成の流れは、一旦異なる名前 (デフォルト "New Folder") のディレクトリを作って、それを別名に変更します。
ディレクトリの名前を変更するときのメソッドは MOVE です。例えば、abc というディレクトリを xyz という名前に変更する場合は次のように、変更後のディレクトリ名を Destination ヘッダで指定します。
REQUEST: **************
MOVE /abc HTTP/1.1
Host: localhost
Overwrite: F
Destination: http://localhost/xyz
Translate: f
Accept: */*
Authorization: Basic xxxxx
RESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 08:02:02 GMT
Content-Length: 0
これで正しく xyz が作成されます。ここで "xyz" という名前のディレクトリを "テスト" という名前に変更する場合は、上記と同様に次のようにします。
REQUEST: **************
MOVE /xyz HTTP/1.1
Host: localhost
Overwrite: F
Destination: http://localhost/%E3%83%86%E3%82%B9%E3%83%88
Translate: f
Accept: */*
Authorization: Basic xxxxx
RESPONSE: **************
HTTP/1.1 201 Created
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Fri, 21 Nov 2008 08:03:07 GMT
Content-Length: 0
ステータスコードは 201 が返されます。しかし、この結果は文字化けを起こしたディレクトリが作成されます。
回避方法
========上記から、MKCOL による日本語ディレクトリの作成は問題ありません。
しかし MOVE メソッドを実行するときに、文字化けが発生します。このことから、MOVE しないで Web フォルダを作成するクライアントを使用することによって、この問題は回避可能と思われます。
参考
=====参考までに、MultiByteToWideChar 周辺を見れば上の考察の確証が取れると思い、簡単に IIS の動きを見てみました。
とりあえず、この二つにブレークポイントをはって...
0:006> bl
0 e 77025cae 0001 (0001) 0:**** kernel32!MultiByteToWideChar
1 e 7702d198 0001 (0001) 0:**** kernel32!WideCharToMultiByte処理を流します。
0:006> g
Breakpoint 0 hit
eax=00000000 ebx=77025cae ecx=00000000 edx=00000000 esi=01ebf4f4 edi=01c3c350
eip=77025cae esp=01ebf3c0 ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
kernel32!MultiByteToWideChar:
77025cae 8bff mov edi,ediWebDAV からの呼び出しなので確認します。
0:006> kbn 100
# ChildEBP RetAddr Args to Child
00 01ebf3bc 6e952d32 0000fde9 00000008 01ebf430 kernel32!MultiByteToWideChar
WARNING: Stack unwind information not available. Following frames may be wrong.
01 01ebf3ec 6e949a69 01ebf430 0000001c 00000000 webdav!RegisterModule+0x5e97
02 01ebf40c 6e94a2e1 01ebf430 00000000 01c1fe28 webdav+0x9a69
03 01ebf494 6e947d40 01c1f018 01ebf4f4 00000000 webdav+0xa2e1
04 01ebf528 6e94bb7f 01152950 00000100 0115938c webdav+0x7d40
05 01ebf544 70db7035 0115bd18 01c1f070 01c1f01c webdav+0xbb7f
06 01ebf558 70db3696 0115938c 01c1f018 00000000 iiscore!NOTIFICATION_CONTEXT::RequestDoWork+0x128
...
15 01ebf9d0 00000000 741e1e4c 01136eb8 00000000 ntdll!_RtlUserThreadStart+0x1b0:006> da 01ebf430
01ebf430 "/%E3%83%86%E3%82%B9%E3%83%88"これは URL デコードしないままの文字を Unicode に変換しようとしているということです。
0:006> ?0000fde9
Evaluate expression: 65001 = 0000fde9コードページは UTF-8 で問題ありません。
MultiByteToWideChar の結果を見てみます。
0:006> g 6e952d32
eax=0000001c ebx=77025cae ecx=6dfb7879 edx=00000025 esi=01ebf4f4 edi=01c3c350
eip=6e952d32 esp=01ebf3dc ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
webdav!RegisterModule+0x5e97:
6e952d32 8945fc mov dword ptr [ebp-4],eax ss:0023:01ebf3e8=00000000
0:006> dc 01c3c350
01c3c350 0025002f 00330045 00380025 00250033 /.%.E.3.%.8.3.%.
01c3c360 00360038 00450025 00250033 00320038 8.6.%.E.3.%.8.2.
01c3c370 00420025 00250039 00330045 00380025 %.B.9.%.E.3.%.8.
01c3c380 00250033 00380038 00000000 00000000 3.%.8.8.........この後処理を流して出来上がるディレクトリは文字化けをしています。
そこで次に、URL デコードした場合にどうなるか試してみました。
0:006> g
Breakpoint 0 hit
eax=00000000 ebx=77025cae ecx=00000000 edx=00000000 esi=01ebf4f4 edi=01c3c7d0
eip=77025cae esp=01ebf3c0 ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
kernel32!MultiByteToWideChar:
77025cae 8bff mov edi,edi
0:006> kbn
# ChildEBP RetAddr Args to Child
00 01ebf3bc 6e952d32 0000fde9 00000008 01ebf430 kernel32!MultiByteToWideChar
WARNING: Stack unwind information not available. Following frames may be wrong.
01 01ebf3ec 6e949a69 01ebf430 0000001c 00000000 webdav!RegisterModule+0x5e97
02 01ebf40c 6e94a2e1 01ebf430 00000000 01c26b78 webdav+0x9a69
03 01ebf494 6e947d40 01c25d68 01ebf4f4 00000000 webdav+0xa2e1
04 01ebf528 6e94bb7f 01152950 00000100 0115938c webdav+0x7d40
05 01ebf544 70db7035 0115bd18 01c25dc0 01c25d6c webdav+0xbb7f
...
13 01ebf978 77c0e4b6 01136eb8 7cd3a7d1 00000000 kernel32!BaseThreadInitThunk+0xe
0:006> dc 01ebf3bc
01ebf3bc 01ebf4f4 6e952d32 0000fde9 00000008 ....2-.n........
01ebf3cc 01ebf430 0000001c 01c3c7d0 000000b8 0...............
01ebf3dc 01ebf4f4 01c255f5 01c25d00 00000000 .....U...]......
...
0:006> da 01ebf430
01ebf430 "/%E3%83%86%E3%82%B9%E3%83%88"01ebf430 から始まるバッファを URL デコードします。
0:006> eb 01ebf430 2f e3 83 86 e3 82 b9 e3 83 88 00
0:006> dc 01ebf430
01ebf430 8683e32f e3b982e3 45008883 32382533 /..........E3%82
01ebf440 25394225 38253345 38382533 01c26b00 %B9%E3%83%88.k..null 終端なので MultiByteToWideChar の第4引数を -1 にセットしておきます。
0:006> ed 01ebf3d0 ffffffff
結果を見てみます。
0:006> g 6e952d32
eax=00000005 ebx=77025cae ecx=6dfb7879 edx=0000000b esi=01ebf4f4 edi=01c3c7d0
eip=6e952d32 esp=01ebf3dc ebp=01ebf3ec iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
webdav!RegisterModule+0x5e97:
6e952d32 8945fc mov dword ptr [ebp-4],eax ss:0023:01ebf3e8=00000000
0:006> du 01c3c7d0
01c3c7d0 "/テスト"この後、処理を流すと正常なディレクトリが作成されていることが確認できました。
この結果から、HTTP ヘッダの URL デコードを忘れていることが問題と思われます。
ご参考になれば幸いです。
-----------------------------------------
だどさん http://keicode.com/
2008年11月21日 4:16 -
追記です。
フォーラムで発見した問題 (らきしもの) がモジュールのフィックスまでいけたら、大変素晴らしいことだと思い、US のフォーラムにもポストしてみました。
US IIS Forum Thread:
WebDAV module cannot handle UTF-8 in MOVE methodhttp://forums.iis.net/t/1153253.aspx
さて、どのような話になるでしょうか。
------------------------------------------
だどさん http://keicode.com/
2008年11月21日 15:47 -
こちらの件は、MS に問題を認識してもらえたようで、次の修正に含まれるそうです。
US のフォーラムで回答がありました。
http://forums.iis.net/p/1153253/1889406.aspx
今回の私たちの指摘で修正されたようですね。 IIS の品質向上に一役買ったことになるので良かったですね!
-------------------------------------------
だどさん http://keicode.com/
2009年1月8日 13:38 -
こんにちは、フォーラムオペレーターの鈴木裕子です
だどさん さん、いつも本当に丁寧な回答とさすがのアクション、ありがとうございました!
akisanaki さん、その後いかがでしょうか?ご返信をお待ちしたいところだったのですが、大変貴重な情報ですので、できるだけ早く多くの方にも活用していただきたいと思い、勝手ながら私の方で回答チェックを付けさせていただきました。
もし不適切でしたら、遠慮なくチェックを解除してくださいね!
だどさん さんのご投稿にあるように、今回のご質問はUSのIISフォーラムを通じて、弊社でも問題と認識させていただきました。
修正までお待ちいただくことになる点は恐縮ですが、貴重なご投稿をありがとうございました!
これからもIT技術者の皆様の情報交換の場として、Forumをさらにご活用ください。よろしくお願いします
2009年1月15日 1:19モデレータ