- - PR -
Base64でエンコードしたパラメータの受け渡しについて
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2004-03-31 09:51
Javaサーブレット+JSPでWebアプリケーションを構築しています。
WebサーバーはWeblogicのWebサーバーです。 1.JSPへ次画面へ引き継ぐ情報として、Base64形式でエンコードしたバイト文字列を書き出し、 2.サブミットした時にパラメータとしてRequestを送信しています。 3.サーブレット側で受け取った文字列をデコードする際に、 余分な文字が混入しておりエラーとなっています。 画面に書き出す際に余分な文字が入ったのか、 送信時に余分な文字が入ったのか、 Webサーバーが原因なのかわからなく、手の打ちように困っています。 下の文字列サンプルで、"index"パラメータが、Base64エンコード文字列です。 サーブレットで受け取った際に、最後の・・・CxNwAuze8rKgAAAA=の後に ランダムに3文字〜10文字くらいまでの余分な文字が付いており デコード時にエラーになります。(???で化けているものもあります) 現在考えている原因はどれも根拠はないのですが・・・ ・ユーザーの使用しているブラウザの仕様で、サブミット時に文字列が混入する ・Webサーバーの不具合 ・JSP書き出し文字列の書き方(JSESSION等の使い方) どなたかヒントとか、推測だけでもよいのでアイデアをお願いします。 【文字列のサンプル】 HREF=JavaScript:hoge_script("/hoge_servlet;jsessionid=AqL3RT903u6bXFtfOHurisb1101wzo1cvmTo2r54q6t2Bmr5TovB!-1503792740!-1407516405!8080!-1!680293395!-1407516404!8080!-1?index=H4sIAAAAAAAAAFvzloG1uIhBLzk/Vy8xOTk1r6S0KFUvqwAokJSYU6JXmqlXWpKZo-eZl5Ja4ZyfV5KYmZdapLHlxoGa3-c3MTEweTKwZeWXpqfmeTKwZicC6YoiBn2cpoGMckosTnUqLQaaU1zsn5SVmlxSlL6Q9eX3KSVMDIxRDFxJ-X6lOTluOYnpFQUMQCACxNwAuze8rKgAAAA=","hoge_mode") 【JavaScript】 function hoge_script(url, mode) { if (flag) { window.alert(message); resetFlag(); return; } else { document.form.action = url; document.form.MODE.value = mode; document.form.submit(); flag = true; return; } } | ||||
|
投稿日時: 2004-03-31 11:34
具体的にどんな文字列がついているんですか?いくつか教えてください。 あと、普通、FORM で POST するんだったら、action の後ろに勝手にパラメータを つけるんじゃなくて、hidden 項目の value にセットすると思うんですけど。 | ||||
|
投稿日時: 2004-03-31 14:35
>具体的にどんな文字列がついているんですか?いくつか教えてください。
はい。以下のようなものになります。 ???、YgW、></、iOQ、AME、t2?、Fla、rkI、=、!-1、H:? 3文字が多いです。 あと、普通、FORM で POST するんだったら、action の後ろに勝手にパラメータを つけるんじゃなくて、hidden 項目の value にセットすると思うんですけど。 作り的におかしいかも知れませんが、FORMでもPOSTしつつ、 書いているようにURLでもパラメータを渡しています。 画面内に同じようなリンクを作成し、クリックされたリンクによって 渡すパラメータを変えたいためです。 以上、よろしくお願いします。 | ||||
|
投稿日時: 2004-04-01 09:31
追記です。
障害が発生している中にMAC使用のユーザーがいたという事がわかりました。 全てのエラーがMACかどうかはわからないのですが、 可能性としてMACだとこういう事が起こるとか、どなたか事例を知っている方いませんか? Help me〜 | ||||
|
投稿日時: 2004-04-01 10:21
どの程度の障害解析、問題の切り分けをしているのかがさっぱり見えないんですが。
・再現性はあるか ・他にPOSTされるパラメータをすべてなくしてやってみたか ・問題のURLを直接入力してアクセスした場合の結果はどうなるか などなど。こういう障害系の質問をする場合は、 ・読み手に再現させる ・再現させなくてもわかるぐらいの詳細な情報を提示する のどちらかをしないと。 | ||||
|
投稿日時: 2004-04-01 12:48
# 勘違いでしたらすみません。
昔、似たようなことをやったときは、Base64 の文字セット(後ろのほう)を変更した記憶があります。 「Base64 の文字セット」は「HTTP でエスケープなしで送信可能な文字セット」に完全に含まれているか確認してみてください。 | ||||
|
投稿日時: 2004-04-01 17:39
ふーばーさん、びじばしさん、回答ありがとうございます。
不足している情報を書き足します。 >・再現性はあるか 特定のユーザーで再現しているようですが、(ユーザーID等を取っている事から判る) 開発環境での再現はしていません。 開発環境でテストしているノード環境はWindows2000+IE6.0、IE5.5、NN4.7 システム全体の作りとして、パラメータをBase64でやり取りしており 他の画面でも同様にBase64を使用していたりするのですが、 FormのパラメータからPOSTしている部分では発生しておらず、 Base64を前掲のようにURLに埋め込んで送っている箇所でのみ発生しています。 >・他にPOSTされるパラメータをすべてなくしてやってみたか 手元の環境で再現していないので、試しておりません。 >・問題のURLを直接入力してアクセスした場合の結果はどうなるか 直接入力すると、Base64に到達するまえにリファラーチェックしてはじいてしまいますので それ用のエラー画面に遷移させています。 >「Base64 の文字セット」は「HTTP でエスケープなしで送信可能な文字セット」に完全に含まれているか確認してみてください。 早速チェックしてみました。↓Base64文字列を書きます。 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/= しかし私には問題なさそうに見えます・・・ URLエンコードする際に、送信バイトデータとの文字コードの不一致により デコードする際にちゃんとデコードできない事とかってはずれてますでしょうか? 以下、Base64のエンコード、デコードのソースを書いておきます。 public class Base64 { /** BASE64文字(0から63)のコードキャラクタ(padding文字も含む)を順に代入した文字配列 **/ private static final char[] alphabet ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/=".toCharArray(); /** 0から63までの数字に変換されたBase64方式の文字を代入するための配列 **/ private static byte[] codes = new byte[256]; static { for (int i = 0 ; i < 256; i++) { codes[i] = -1; } for (int i = 'A'; i <= 'Z'; i++) { codes[i] = (byte)(i - 'A'); } for (int i = 'a'; i <= 'z'; i++) { codes[i] = (byte)(26 + i - 'a'); } for (int i = '0'; i <= '9'; i++) { codes[i] = (byte)(52 + i - '0'); } codes['-'] = 62; codes['/'] = 63; } public static char[] encodeFromByteToChar (byte[] data) { String METHOD = "encodeFromByteToChar(byte[])"; char[] out = new char[((data.length + 2) / 3) * 4]; for (int i = 0, index = 0; i < data.length; i += 3, index += 4) { boolean quad = false; boolean trip = false; int val = (0xFF & (int) data[i]); val <<= 8; if ((i+1) < data.length) { val |= (0xFF & (int) data[i+1]); trip = true; } val <<= 8; if ((i+2) < data.length) { val |= (0xFF & (int) data[i+2]); quad = true; } out[index+3] = alphabet[(quad? (val & 0x3F): 64)]; val >>= 6; out[index+2] = alphabet[(trip? (val & 0x3F): 64)]; val >>= 6; out[index+1] = alphabet[val & 0x3F]; val >>= 6; out[index+0] = alphabet[val & 0x3F]; } // end of for statement return out; }// end of encodeFromByteToChar public static byte[] decodeFromCharToByte (char[] data) { String METHOD = "decodeFromCharToByte(byte[])"; int len = ((data.length + 3) / 4) * 3; if (data.length > 0 && data[data.length-1] == '=') { --len; } if (data.length > 1 && data[data.length-2] == '=') { --len; } byte[] out = new byte[len]; int shift = 0; // accumに格納されている余分なビット int accum = 0; // 余分なビット int index = 0; for (int ix = 0; ix < data.length; ix++){ int value = codes[ data[ix] & 0xFF ]; if ( value >= 0 ) { accum <<= 6; shift += 6; accum |= value; if ( shift >= 8 ) { shift -= 8; out[index++] = (byte) ((accum >> shift) & 0xff); } } } if (index != out.length) { // ここでExceptionをThrowしてます。 } return out; } } | ||||
|
投稿日時: 2004-04-01 17:46
>>「Base64 の文字セット」は「HTTP でエスケープなしで送信可能な文字セット」>に完全に含まれているか確認してみてください。
>早速チェックしてみました。↓Base64文字列を書きます。 >ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/= >しかし私には問題なさそうに見えます・・・ 問題あるのでは? / とか = が含まれていたらまずいです。(RFC番号忘れましたが、使用できる文字には 制限があります。調べてみてください。) 影響がない他の文字(って何???)に変えるべきではないでしょうか。 | ||||
