Не удается получить HTTP-запрос POST для правильной работы - PullRequest
2 голосов
/ 21 января 2012

Я пытаюсь отправить файл из игры, над которой я работаю, на веб-сайт игры, используя запрос HTTP POST. Когда я отправляю файл с помощью формы на странице HTML, он работает нормально. Тем не менее, я не смог симулировать то же самое внутри игры. Я получаю код ответа 200, указывающий, что запрос прошел успешно, однако скрипт загрузки указывает, что он получил запрос GET, а массивы $ _FILES и $ _POST пусты. Я посмотрел на вывод POST HTML-формы и POST игры в Wireshark, но не смог обнаружить сколько-нибудь значимых различий между ними. (Если бы я знал, как точно дублировать метод POST HTML-формы, я бы это сделал, но я не думаю, что это возможно.)

В любом случае, вот код, который я использую для его отправки. Спасибо!

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 );

Ответы [ 2 ]

1 голос
/ 26 января 2012

Я пытался ответить на этот вопрос раньше, но, думаю, этого не произошло. Во всяком случае, я чувствую себя довольно глупо. Сейчас работает отлично. Причина, по которой он не работал, заключается в том, что у меня был второй параметр InternetOpen () как «wrackgame.com» вместо «www.wrackgame.com». Я понятия не имею, почему это мешало ему работать - особенно учитывая, что мой скрипт загрузки, /leaderboard/upload_file.php, выполнялся. Не то чтобы трафик не доходил до сервера. Странно.

В любом случае, спасибо всем за помощь!

0 голосов
/ 21 января 2012

Я не знаком с WinINet lib, но libcurl имеет c интерфейс , включая некоторые простые для понимания примеры того, как настроить запрос HTTP POST

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...