HTTP POSTリクエストを使用して、ゲームのWebサイトにファイルを送信しようとしています。 HTMLページ上のフォームを使用してファイルを送信すると、正常に動作します。しかし、私はゲーム内で同じことをシミュレートすることができませんでした。リクエストが成功したことを示すレスポンスコード200を受け取っていますが、アップロードスクリプトはGETリクエストを受け取ったことを示し、$ _FILESおよび$ _POST配列は空です。 HTMLフォームのPOSTとWiresharkのゲームのPOSTの両方の出力を見てきましたが、両者の意味のある違いは検出できませんでした。 (もし私がHTMLフォームのPOSTメソッドを正確に複製する方法を知っていたら、それは可能だと思いますが、それは可能だとは思いません)HTTP POST要求が正常に動作しない
とにかく、ここに私が送るコードがあります。ありがとう!
HINTERNET hInternet;
HINTERNET hConnect;
HINTERNET hRequest;
INTERNET_BUFFERS Buffers;
DWORD dwBytesWritten;
DWORD dwNumBytesToWrite;
char szBoundary[32];
char szContentTypeHeader[64];
char szFileHeader[256];
char szFileFooter[4];
char szBodyFooter[32];
ULONG ulTotalBytesWritten;
ULONG ulOffset;
ULONG ulContentLength;
// Get a handle for working with the Internet.
hInternet = InternetOpen("Wrack", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet == NULL)
return (false);
// Open an HTTP session for the site.
hConnect = InternetConnect(hInternet, "wrackgame.com", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL);
if (hConnect == NULL)
{
InternetCloseHandle(hInternet);
return (false);
}
// Open the POST request.
hRequest = HttpOpenRequest(hConnect, "POST", "leaderboard/upload_file.php", NULL, "http://www.wrackgame.com/leaderboard/upload.html", NULL, 0, NULL);
if (hRequest == NULL)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
return (false);
}
// Generate our various headers and footers.
sprintf_s(szBoundary, "----%04x%04x%04x", rand() % 0xffff, rand() % 0xffff, rand() % 0xffff);
sprintf_s(szContentTypeHeader, "Content-Type: multipart/form-data; boundary=%s", szBoundary);
sprintf_s(szFileHeader, "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: application/octet-stream\r\n\r\n", szBoundary, "file", "testreplay.wrp");
sprintf_s(szFileFooter, "\r\n");
sprintf_s(szBodyFooter, "--%s--\r\n", szBoundary);
// Build our header.
if (HttpAddRequestHeaders(hRequest, szContentTypeHeader, -1, HTTP_ADDREQ_FLAG_ADD) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
// Calculate how much data we'll be sending.
ulContentLength = network_CalcContentLength(szFileHeader, szFileFooter, szBodyFooter);
// Initialize our buffers.
memset(&Buffers, 0, sizeof(INTERNET_BUFFERS));
Buffers.dwStructSize = sizeof(INTERNET_BUFFERS);
Buffers.dwBufferTotal = ulContentLength;
// Send our HTTP request.
if (HttpSendRequestEx(hRequest, &Buffers, NULL, HSR_INITIATE, NULL) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
// Send the header.
ulTotalBytesWritten = 0;
if (InternetWriteFile(hRequest, szFileHeader, strlen(szFileHeader), &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Next, write the body of the replay.
ulOffset = 0;
while (ulOffset < (DWORD)REPLAY_GetReplaySize())
{
// Determine how many bytes of the replay to send. If we're almost
// done, send less than 1024 bytes.
dwNumBytesToWrite = min(1024, REPLAY_GetReplaySize() - ulOffset);
// Send a piece of the replay and log how many bytes we actually
// transferred.
if (InternetWriteFile(hRequest, REPLAY_GetReplayData() + ulOffset, dwNumBytesToWrite, &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Increment the offset of the replay buffer.
ulOffset += 1024;
}
// Send our file footer.
if (InternetWriteFile(hRequest, szFileFooter, strlen(szFileFooter), &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Send our body footer.
if (InternetWriteFile(hRequest, szBodyFooter, strlen(szBodyFooter), &dwBytesWritten) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
ulTotalBytesWritten += dwBytesWritten;
// Close our request now that we're done.
if (HttpEndRequest(hRequest, NULL, 0, NULL) == false)
{
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return (false);
}
InternetCloseHandle(hInternet);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
// No need to do anything more!
return (true);
私はそれが助けになるかどうかは分かりませんが、個々のチャンクではなく1ブロックのデータを書き込もうとしましたか? – Deanna
@Deanna:どうすればいいですか?私が知る限り、HttpSendRequestのようないくつかの関数を使用してプロセスを開始する必要があります.HttpSendRequestは、InternetWriteFileを使用して本文を送信する前にパケットを送信します。 – Carnevil
プロセスを開始するには、はい、しかし、少なくとも4回は 'InternetWriteFile()'を呼び出します。これは問題を引き起こしているタイミングかもしれません。 – Deanna