プロが教えるわが家の防犯対策術!

winnetを使ってPOST形式でサーバにパラメータを渡そうとしていますが、パラメータが渡せずに困っています。
HttpOpenRequestかHttpSendRequestがおかしいと思うのですが、自分では見当がつきません。
よければ何処に問題があるのか教えてください。

環境:vc++2005

int DoHttpRequest( void )
{
HINTERNET hInet, hSession, hRequest;
DWORD dwTotal = 0;
wchar_t param[] = L"type=1";
wchar_t header[] = L"Content-Type: application/x-www-form-urlencoded";
wchar_t accept[] = L"Accept: */*"; // 使ってない
BOOL flag;

Console::WriteLine( "Http接続START" );

//インターネット(WinInet)初期化
hInet = InternetOpen( NULL,
INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, 0);
if (hInet == NULL) {
Console::WriteLine( "エラー1" );
return -1;
}

// サーバへ接続
hSession = InternetConnect( hInet, L"192.168.11.25", 9999,
NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
if( hSession == NULL ) {
Console::WriteLine( "エラー2" );
InternetCloseHandle(hInet);
return -1;
}

//HTTPセッションの開始, 指定のURLオープン
hRequest = HttpOpenRequest( hSession, L"POST", L"/sample/service.php",
NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0 );
if (hRequest == NULL) {
Console::WriteLine( "エラー3" );
InternetCloseHandle(hSession);
InternetCloseHandle(hInet);
return -1;
}

// 送信
flag = HttpSendRequest( hRequest, header, wcslen( header ), param, wcslen( param ));
if( flag == FALSE ) {
Console::WriteLine( "エラー4" );
InternetCloseHandle(hRequest);
InternetCloseHandle(hSession);
InternetCloseHandle(hInet);
return -1;
}

//インターネットハンドルの解放
InternetCloseHandle( hRequest );
InternetCloseHandle( hSession );
InternetCloseHandle( hInet );

Console::WriteLine( "Http接続END" );

return 0;
}

A 回答 (2件)

なるほど、第2引数と第4引数で指定されたものはそのように出力されるのですか…。


第2引数では追加のリクエストヘッダ(複数の場合はおそらく\r\nで結合して)を、第4引数ではHTTPBodyに相当するものを…ですか。

MSDNによると…
第3引数は
>dwHeadersLength
>[in] Size of the additional headers, in TCHARs. If this parameter is -1L and lpszHeaders is not NULL, the function assumes that lpszHeaders is zero-terminated (ASCIIZ), and the length is calculated. See Remarks for specifics.
ということでTCHAR単位で、第5引数は
>dwOptionalLength
>[in] Size of the optional data, in bytes. This parameter can be zero if there is no optional data to send.
ということでByte単位で渡す必要があるようです。

sizeof( param )
では、param[]には'\0'も含まれるので14になったようです。
wchar_t配列ではなく、charの配列でstrlen()でよいのではないでしょうか?
    • good
    • 0
この回答へのお礼

返信ありがとうございます。
おかげで解決することができました。

最終的に以下の変更でパラメータを渡すことができました。
>char param[] = "type=1";
>wchar_t header[] = L"Content-Type: application/x-www-form-urlencoded";// char型だと12150エラー発生
>flag = HttpSendRequest( hRequest, header, wcslen( header ), param, strlen( param ));

ヘッダーは以下のようになっていました。
>POST /sample/service.php HTTP/1.1
>Content-Type: application/x-www-form-urlencoded
>Host: 192.168.11.25:9999
>Content-Length: 6
>Cache-Control: no-cache
>
>type=1

ありがとうございました。

お礼日時:2008/09/19 15:12

とりあえず、WireSharkなどでどのように送られいるか確認してみてはどうでしょう?



WinInet系のAPIは使ったことないのですが…
>wchar_t param[] = L"type=1";
>wchar_t header[] = L"Content-Type: application/x-​www-form-urlencoded";
>flag = HttpSendRequest( hRequest, header, wcslen( header ), param, wcslen( param ));
だと、POSTリクエストには
Content-Type: application/x-​www-form-urlencoded: type=1
と送られているような気がするのですが…。
header[]に記述されている分がリクエストヘッダの名前("Host:"とか"User-Agent:"とか)で、param[]に記述されているのがそのパラメータ…とか。

複数のリクエストヘッダの場合はどうなるんでしょうかね?
# \r\nで連結…なんでしょうか。

この回答への補足

WireSharkでパケットを確認してみたところ、ヘッダがおかしい事は確認できました。
少し調べてみましたがまだ解決には至ってません。
調べた分を以下に記載させてもらいます。

>flag = HttpSendRequest( hRequest, header, wcslen( header ), param, wcslen( param ));
この時のヘッダは以下でした。
>POST /sample/service.php HTTP/1.1
>Content-Type: application/x-www-form-urlencoded
>Host: 192.168.11.25:9999
>Content-Length: 6
>Cache-Control: no-cache
>
>typ

HttpSendRequestの第5引数をsizeofにするとヘッダーはちゃんとしたように見えました。
>flag = HttpSendRequest( hRequest, header, wcslen( header ), param, sizeof( param ));
この時は以下でした。
>POST /sample/service.php HTTP/1.1
>Content-Type: application/x-www-form-urlencoded
>Host: 192.168.11.25:9999
>Content-Length: 14
>Cache-Control: no-cache
>
>type=1

FORMからPOSTする分はちゃんと受け取るのでphpの方は正しいと思っています。
phpの受信コードは以下です。
>$_type = $_POST['type'];

何かありましたらまた返信を頂けると助かります

補足日時:2008/09/18 11:36
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!