2012-01-21 3 views
2

HTTP POST 요청을 사용하여 게임의 웹 사이트로 파일을 보내려고합니다. HTML 페이지의 양식을 사용하여 파일을 보내면 제대로 작동합니다. 그러나 게임 내에서 똑같은 것을 시뮬레이션 할 수 없었습니다. 요청이 성공적으로 완료되었음을 나타내는 200의 응답 코드가 수신되지만 업로드 스크립트는 GET 요청을 받았음을 나타내며 $ _FILES 및 $ _POST 배열은 비어 있습니다. 필자는 Wireshark에서 HTML 폼의 POST와 게임의 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); 
+0

도움이 될지 모르겠지만 개별 청크가 아닌 데이터 블록 하나를 작성해 보았습니까? – Deanna

+0

@Deanna : 어떻게해야합니까? 내가 아는 한, HttpSendRequest와 같은 프로세스를 시작하기 위해 여러 함수를 사용해야한다. HttpSendRequest는 InternetWriteFile을 사용하여 본문을 보내기 전에 패킷을 보낸다. – Carnevil

+0

프로세스를 시작하려면 예, 그렇지만 적어도 InternetWriteFile()에 4 번 이상 호출하면 문제의 원인이 될 수 있습니다. – Deanna

답변

1

나는이 이전 답변을 시도하는 방법에 대한 예제를 따라 몇 가지 쉬운 포함 c interface을 가지고,하지만 난 그것을하지 않았다 생각 통과. 어쨌든, 나는 바보 같다. 이제 완벽하게 작동합니다. 그것이 작동하지 않는 이유는 "wrackgame.com"대신 "www.wrackgame.com"대신 InternetOpen()의 두 번째 매개 변수가 있었기 때문입니다. 왜 업로드 스크립트 /leaderboard/upload_file.php가 실행 중이 었는지 생각하면 왜 작동하지 못하는지 알 수 없습니다. 트래픽이 서버에 도달하지 못하는 것이 아닙니다. 이상한.

어쨌든 도움을 주신 모든 분들께 감사드립니다.

0

나는이 WinINet lib 디렉토리에 익숙하지 해요,하지만 libcurl에서이 setup a HTTP POST request

+0

libcurl을 사용하지 않는 것이 좋습니다. 이것은 일반 Wininet 코드를 사용하여 작동 할 수 있어야합니다. 현재 코드에 어떤 문제가 있으며 최소한 문제를 진단하기 위해 무엇을 할 수 있습니까? 왜 제대로 작동하지 않는지에 대한 단서가 있다면 적어도 거기에서 시작할 수 있습니다. – Carnevil

관련 문제