mcrblog

vcpp-ml

2001年06月

30

[vcpp 00054095] アクセス違反のアドレス

お世話になっております。
藤森です。

フックを使用するアプリケーションでまれにアクセス違反が出るのですが
そのアドレスが、0100XXXXと表示されます。
通常だと0040XXXXというように出るのでおそらくフックプロシージャでの
エラーだと思うのですが、場所を特定できずに困っています。
このような、アドレスから問題の個所を探すことができるでしょうか?
ご存知の方がおりましたら、教えてください。

宜しくお願い致します。
29

[vcpp 00054094] Re: WININETでのHTTP POSTについて

青柳です。

すいませんが、おまけだけに反応します(本論の方は私はわかり
ません)。

> 【おまけ】
> ついでに気になっていることをいくつか質問しておこう(^^;

> HTTP1.1における100番台のステータスコードのハンドリングはAPI|MFCが勝手
> に行ってくれるのでしょうか?
> これがどのような場合に返却されるのか今一つわかっていません。
> #ProxyでConnection:Keep-aliveにした場合?
> テストしている環境ではこれを返答させることができておらず、プロトコル上
> 載ってきたパターンを見たことがないためどのように振舞えばよいのかわかり
> ません。クラス仕様的には1リクエスト1リプライでしか処理できなさそうに見
> えます。

100って continue とかですよね?
HttpSendRequest API(MFC ではなく WinInet API)を使って
POST させたときに 100 が返ってきたことがあります。ただし、
これはパケットを覗いていたから気付きましたが、アプリでは
気にする必要はありませんでした。WinInet が自動的に処理し
てくれているようです。

なお、IIS 5.0 の ASP なページは比較的しょっちゅう 100 を
返してくるようです。

-- 
青柳 臣一 (Shinichi Aoyagi)
a...@osk.3web.ne.jp
http://www.threeweb.ad.jp/~aoyagi/
29

[vcpp 00054094] Re: WININETでのHTTP POSTについて

青柳です。

すいませんが、おまけだけに反応します(本論の方は私はわかり
ません)。

> 【おまけ】
> ついでに気になっていることをいくつか質問しておこう(^^;

> HTTP1.1における100番台のステータスコードのハンドリングはAPI|MFCが勝手
> に行ってくれるのでしょうか?
> これがどのような場合に返却されるのか今一つわかっていません。
> #ProxyでConnection:Keep-aliveにした場合?
> テストしている環境ではこれを返答させることができておらず、プロトコル上
> 載ってきたパターンを見たことがないためどのように振舞えばよいのかわかり
> ません。クラス仕様的には1リクエスト1リプライでしか処理できなさそうに見
> えます。

100って continue とかですよね?
HttpSendRequest API(MFC ではなく WinInet API)を使って
POST させたときに 100 が返ってきたことがあります。ただし、
これはパケットを覗いていたから気付きましたが、アプリでは
気にする必要はありませんでした。WinInet が自動的に処理し
てくれているようです。

なお、IIS 5.0 の ASP なページは比較的しょっちゅう 100 を
返してくるようです。

-- 
青柳 臣一 (Shinichi Aoyagi)
a...@osk.3web.ne.jp
http://www.threeweb.ad.jp/~aoyagi/
29

[vcpp 00054093] WININETでのHTTP POSTについて

小林と申します。
WININET(CInternetxxx)を用いたHttpについての質問です。

【現象】
WinInet API(正確にはMFCのCHttpほげほげクラス)を用いてWebサーバと
データの送受信をするプログラムを書いているのですが、Proxy経由の
POST時の動作で認証が入った場合にうまく動作してくれません。

具体的にはクライアント-Proxy間でPOSTのヘッダを受けてすぐProxyが
リプライを返しており、クライアント側はこれを読まずに残りのボディを
送信しようとした結果、Proxyからコネクションを切られてしまいます。

クライアントからのリクエスト発行順序としては大雑把に

pServer = pSession->GetHttpConnection(server, port)
//プロクシの指定など
while(1) {
pFile = pServer->OpenRequest(HTTP_VERB_POST, uri, ...);
//ヘッダ付加など
// (1)
try {
pFile->SendRequestEx(content-length);
// (2)
//データを読んでpFile->Write();繰り返し (A)
pFile->EndRequest();
} catch(CInternetException *pEx) {
//SSL関係,FORCE_RETRY例外捕捉
// (3)
}
pFile->QueryInfoStatusCode(dwRet);
if (dwRet == HTTP_STATUS_DENIED)
{
//サーバ認証情報設定

} else if(dwRet == HTTP_STATUS_PROXY_AUTH_REQ) {
//Proxy認証情報設定
} else {
break;
}
}

という流れで行っています。
認証情報はあらかじめ設定せず、SendRequestの結果でSetOptionして
Authorizationヘッダを生成させて再リクエストという形ですね(あらかじめ設
定してあってもAPI内部で同様に振舞うようですが)。
このとき、Proxy-Authorization:ヘッダが必要なProxyを介するときに、(A)
の部分でERROR_INTERNET_CONNECTION_ABORTEDによる例外が発生しています。

RFC2616のSec8.2.2によると
リクエストボディを持つ要求を送るクライアントは
・リクエスト送信中エラーステータスを監視すべきである。
・エラーステータスを受信した場合すぐ送信をとめるべきである。
・Content-Lengthを送信した場合は、接続をきらなければならない。

Proxy-Authenticate: を貰わないと認証手順がわからず、
そのためにBodyを送りきらなきゃいけないというのは無駄すぎなので
こうあるべきだとは思うのですが、ではそのように振舞おうとすると
SendRequestExからEndRequestまでの間でQueryInfoStatusCodeが発行
できればよいのですが、
・(2)でQueryInfoStatusCodeを発行->APIエラー
・(3)の例外捕捉時にステータス確認->APIエラー
・(3)でEndRequest()後ステータス確認->EndRequest()で例外

データ(90kb程度)をあらかじめメモリ展開し、SendRequestEx-EndRequestを
SendRequestに変更したところ、15分ほど待たされた挙句に
ERROR_INTERNET_CONNECTION_ABORTEDによる例外が発生しました。
#RFC2616 8.2.4 に従ってリトライしていた?

非同期モードというのもあるため、こちらならできるかと、APIから作成
して見ました(MFCは対応していない)が、EndRequest発行まではデータの読
み出しができないのは変わらないようでした。
InternetGetLastResponseInfo()も試してみましたが、こちらは
DWORD dwerr;
char buff[4096];
DWORD len= 4096;
InternetGetLastResponseInfo(&dwerr, buff, &len);
のように使っているのですが、Len=0しか帰ってきません。

リクエスト中にリプライを受信する方法についてはほぼお手上げの状態になっ
ています。

1セッションで複数リクエストを行うことから、毎回*Authenticate:を受けて
*Authorization:をつけたりクエストを再発行するというのも無駄な気もしま
すし、アプリケーションの中ではGETがまず発生しますので発行した
*Authorization:ヘッダを保存してしまって2回目以降は直接リクエストヘッダ
に付加してやるというのも1つの手かと思うのですが、

InternetQueryInfoのフラグはあるにも関わらず、実際発行しても 
取得できず、RAW_HEADERSを確認すると、該当ヘッダは削除されているとい
う状態です。
#まあ、とれたらとれたで問題のような気もします。

という形で、*Authorization:ヘッダ自体取得ができていません。

BASIC認証ヘッダくらいなら自前で生成できるのですが、これは認証方式が
BASICに固定されてしまい、WWW-Authenticate:NTLMしか許されないような場合
に利用できなくなるのが気になります。

【質問事項】

1.POST時のエラーステータスメッセージのハンドリングを行う
  方法はないでしょうか。より正確には、リクエスト中にレスポンスを監視
  し、読み出す方法を期待しています。
2.その他WININET APIにてPOSTを扱う時の情報はないでしょうか。
3.リクエスト-リプライが完了したときそのProxy-Authorization:ヘッダを
  取得できるのであれば。その方法を教えてください。
4.その他現象を回避する妙案があればご教授願います。
5.本論からずれますが、Content-Lengthが指定されたPOSTにてBODYを
  継続して送信された場合に接続を閉じるProxyの動作は仕様として
  正しいのでしょうか。DoS対策のため必要な気もしますが、RFC上は
 クライアントから切ることを期待しているように読めました。

【環境】
OS WindowsNT4.0SP6
IE 5.0.2314.1003
VC6 SP4
Proxy Squid 2.3.STABLE2(らしい・・・ヘッダ情報から)
Delegate 7.1.1でも同じ(CONNECTION_RESETでしたが)でした。

【おまけ】
ついでに気になっていることをいくつか質問しておこう(^^;

HTTP1.1における100番台のステータスコードのハンドリングはAPI|MFCが勝手
に行ってくれるのでしょうか?
これがどのような場合に返却されるのか今一つわかっていません。
#ProxyでConnection:Keep-aliveにした場合?
テストしている環境ではこれを返答させることができておらず、プロトコル上
載ってきたパターンを見たことがないためどのように振舞えばよいのかわかり
ません。クラス仕様的には1リクエスト1リプライでしか処理できなさそうに見
えます。
-- 
Norihiro Kobayashi mailto:n...@yha.att.ne.jp
29

[vcpp 00054093] WININETでのHTTP POSTについて

小林と申します。
WININET(CInternetxxx)を用いたHttpについての質問です。

【現象】
WinInet API(正確にはMFCのCHttpほげほげクラス)を用いてWebサーバと
データの送受信をするプログラムを書いているのですが、Proxy経由の
POST時の動作で認証が入った場合にうまく動作してくれません。

具体的にはクライアント-Proxy間でPOSTのヘッダを受けてすぐProxyが
リプライを返しており、クライアント側はこれを読まずに残りのボディを
送信しようとした結果、Proxyからコネクションを切られてしまいます。

クライアントからのリクエスト発行順序としては大雑把に

pServer = pSession->GetHttpConnection(server, port)
//プロクシの指定など
while(1) {
pFile = pServer->OpenRequest(HTTP_VERB_POST, uri, ...);
//ヘッダ付加など
// (1)
try {
pFile->SendRequestEx(content-length);
// (2)
//データを読んでpFile->Write();繰り返し (A)
pFile->EndRequest();
} catch(CInternetException *pEx) {
//SSL関係,FORCE_RETRY例外捕捉
// (3)
}
pFile->QueryInfoStatusCode(dwRet);
if (dwRet == HTTP_STATUS_DENIED)
{
//サーバ認証情報設定

} else if(dwRet == HTTP_STATUS_PROXY_AUTH_REQ) {
//Proxy認証情報設定
} else {
break;
}
}

という流れで行っています。
認証情報はあらかじめ設定せず、SendRequestの結果でSetOptionして
Authorizationヘッダを生成させて再リクエストという形ですね(あらかじめ設
定してあってもAPI内部で同様に振舞うようですが)。
このとき、Proxy-Authorization:ヘッダが必要なProxyを介するときに、(A)
の部分でERROR_INTERNET_CONNECTION_ABORTEDによる例外が発生しています。

RFC2616のSec8.2.2によると
リクエストボディを持つ要求を送るクライアントは
・リクエスト送信中エラーステータスを監視すべきである。
・エラーステータスを受信した場合すぐ送信をとめるべきである。
・Content-Lengthを送信した場合は、接続をきらなければならない。

Proxy-Authenticate: を貰わないと認証手順がわからず、
そのためにBodyを送りきらなきゃいけないというのは無駄すぎなので
こうあるべきだとは思うのですが、ではそのように振舞おうとすると
SendRequestExからEndRequestまでの間でQueryInfoStatusCodeが発行
できればよいのですが、
・(2)でQueryInfoStatusCodeを発行->APIエラー
・(3)の例外捕捉時にステータス確認->APIエラー
・(3)でEndRequest()後ステータス確認->EndRequest()で例外

データ(90kb程度)をあらかじめメモリ展開し、SendRequestEx-EndRequestを
SendRequestに変更したところ、15分ほど待たされた挙句に
ERROR_INTERNET_CONNECTION_ABORTEDによる例外が発生しました。
#RFC2616 8.2.4 に従ってリトライしていた?

非同期モードというのもあるため、こちらならできるかと、APIから作成
して見ました(MFCは対応していない)が、EndRequest発行まではデータの読
み出しができないのは変わらないようでした。
InternetGetLastResponseInfo()も試してみましたが、こちらは
DWORD dwerr;
char buff[4096];
DWORD len= 4096;
InternetGetLastResponseInfo(&dwerr, buff, &len);
のように使っているのですが、Len=0しか帰ってきません。

リクエスト中にリプライを受信する方法についてはほぼお手上げの状態になっ
ています。

1セッションで複数リクエストを行うことから、毎回*Authenticate:を受けて
*Authorization:をつけたりクエストを再発行するというのも無駄な気もしま
すし、アプリケーションの中ではGETがまず発生しますので発行した
*Authorization:ヘッダを保存してしまって2回目以降は直接リクエストヘッダ
に付加してやるというのも1つの手かと思うのですが、

InternetQueryInfoのフラグはあるにも関わらず、実際発行しても 
取得できず、RAW_HEADERSを確認すると、該当ヘッダは削除されているとい
う状態です。
#まあ、とれたらとれたで問題のような気もします。

という形で、*Authorization:ヘッダ自体取得ができていません。

BASIC認証ヘッダくらいなら自前で生成できるのですが、これは認証方式が
BASICに固定されてしまい、WWW-Authenticate:NTLMしか許されないような場合
に利用できなくなるのが気になります。

【質問事項】

1.POST時のエラーステータスメッセージのハンドリングを行う
  方法はないでしょうか。より正確には、リクエスト中にレスポンスを監視
  し、読み出す方法を期待しています。
2.その他WININET APIにてPOSTを扱う時の情報はないでしょうか。
3.リクエスト-リプライが完了したときそのProxy-Authorization:ヘッダを
  取得できるのであれば。その方法を教えてください。
4.その他現象を回避する妙案があればご教授願います。
5.本論からずれますが、Content-Lengthが指定されたPOSTにてBODYを
  継続して送信された場合に接続を閉じるProxyの動作は仕様として
  正しいのでしょうか。DoS対策のため必要な気もしますが、RFC上は
 クライアントから切ることを期待しているように読めました。

【環境】
OS WindowsNT4.0SP6
IE 5.0.2314.1003
VC6 SP4
Proxy Squid 2.3.STABLE2(らしい・・・ヘッダ情報から)
Delegate 7.1.1でも同じ(CONNECTION_RESETでしたが)でした。

【おまけ】
ついでに気になっていることをいくつか質問しておこう(^^;

HTTP1.1における100番台のステータスコードのハンドリングはAPI|MFCが勝手
に行ってくれるのでしょうか?
これがどのような場合に返却されるのか今一つわかっていません。
#ProxyでConnection:Keep-aliveにした場合?
テストしている環境ではこれを返答させることができておらず、プロトコル上
載ってきたパターンを見たことがないためどのように振舞えばよいのかわかり
ません。クラス仕様的には1リクエスト1リプライでしか処理できなさそうに見
えます。
-- 
Norihiro Kobayashi mailto:n...@yha.att.ne.jp
記事検索
Amazon.co.jp
  • ライブドアブログ