ОТПРАВКА данных формы с использованием WinInet c

#c #visual-studio #forms #wininet

#c #visual-studio #формы #wininet

Вопрос:

Я пытаюсь заставить эту программу подключиться к веб-сайту и отправить данные формы для входа в систему, но я не знаю, что я делаю не так. Я слышал о других, таких как curl и Winsock, но я выбрал библиотеку WinInet. Итак, только для тестирования этой программы я использовал веб-сайт Pastebin для публикации. Пока я не видел никаких результатов от этого. Если этой программе удастся опубликовать данные формы, она выдаст мне заголовок с указанием местоположения записи на их сайте.

Правильно ли я записываю символ данных формы *? Я видел в других сообщениях stackoverflow, где у них было большое количество тире перед некоторым числом, после чего помещались их данные формы.

Нужно ли мне добавить к ней что-то, чтобы имитировать нажатие кнопки отправки?
Нужно ли мне выписывать значения для каждого элемента формы?

Я пробовал HttpAddRequestHeaders, но это мне не помогло.

Кроме того, я получаю ошибку ERROR_INSUFFICIENT_BUFFER при HttpOpenRequest, но она по-прежнему возвращает действительный интерфейс.

 #include <Windows.h>
#include <WinInet.h>
#include <iostream>

#pragma comment( lib,"Wininet.lib")
using namespace std;

char* getheaders(HINTERNET hRequest){
    DWORD dwInfoLevel=HTTP_QUERY_RAW_HEADERS_CRLF;
    DWORD dwInfoBufferLength=10;
    char* pInfoBuffer=(char*)malloc(dwInfoBufferLength 1);
    while(!HttpQueryInfo(hRequest,dwInfoLevel,pInfoBuffer,amp;dwInfoBufferLength,NULL)){
        if (GetLastError()==ERROR_INSUFFICIENT_BUFFER){
            free(pInfoBuffer);
            pInfoBuffer=(char*)malloc(dwInfoBufferLength 1);
        }else{
            fprintf(stderr,"HttpQueryInfo failed, error = %d (0x%x)n",GetLastError(),GetLastError());
            break;
        }
    }
    pInfoBuffer[dwInfoBufferLength] = '';
    return pInfoBuffer;
}

void readfile(HINTERNET hRequest,char** buffs,int size){
    DWORD dwBytesAvailable;
    DWORD dwBytesRead;
    for(int i=0;i<size;i  ){
        if(!InternetQueryDataAvailable(hRequest,amp;dwBytesAvailable,0,0)) break;
        buffs[i]=(char*)malloc(dwBytesAvailable 1);
        bool bResult=InternetReadFile(hRequest,buffs[i],dwBytesAvailable,amp;dwBytesRead);
        if(!bResult | dwBytesRead==0) break;
    }
}


int main(int argc,char** argv){
    char* hdrs="Content-Type: application/x-www-form-urlencoded";
    char* frmdata="paste_code=test";
    LPCSTR accept[2]={"*/*", NULL};

    HINTERNET hSession = InternetOpen("http generic",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    HINTERNET hConnect = InternetConnect(hSession, "www.pastebin.com",INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
    HINTERNET hRequest = HttpOpenRequest(hConnect, "GET","/", NULL, NULL, accept, 0, 0);
    //ERROR_INSUFFICIENT_BUFFER (122) with "accept".

    bool send=HttpSendRequest(hRequest, hdrs, strlen(hdrs), NULL,NULL);
    if(!send){
        printf("HttpSendRequest failed, code=%d",GetLastError());
        system("pause>nul");
        return 0;
    }

    char* heads=getheaders(hRequest);
    printf("%snnnn",heads);

    HINTERNET hRequest2 = HttpOpenRequest(hConnect, "POST","/", NULL, NULL, accept, 0, 0);
    //ERROR_INSUFFICIENT_BUFFER (122) with "accept".

    send=HttpSendRequest(hRequest2, hdrs, strlen(hdrs), frmdata,strlen(frmdata));
    if(!send){
        printf("HttpSendRequest failed, code=%d",GetLastError());
        system("pause>nul");
        return 0;
    }

    heads=getheaders(hRequest);
    printf("%snnnn",heads);

    InternetCloseHandle(hRequest);
    InternetCloseHandle(hRequest2);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hSession);

    system("pause>nul");
    return 0;
}
  

Комментарии:

1. Почему вы делаете два запроса? Я не знаю особенностей pastebin, но вам, вероятно, следует просто выполнить запрос POST. Кроме того, я действительно сомневаюсь, что вам следует размещать в корневом каталоге. Коды GetLastError() имеют смысл только в случае сбоя функции. Похоже, что вы правильно используете данные типа содержимого и формы.

2. Я пытался просто сделать POST, но это не сработало. Я подумал, что мне, возможно, сначала понадобится получить файлы cookie или заголовки с веб-сайта. Используя Chrome, чтобы узнать, как он использует POST и GET, он будет ПОЛУЧАТЬ ДАННЫЕ с самого сайта, а затем ОТПРАВЛЯТЬ в /post.php и я тоже это пробовал.

3. Вот что передается по сети при публикации на их веб-странице ( pastebin.com/qjLbBt9H ); используется формат multipart / form-data.

4. С момента вашего последнего сообщения я использую анализатор пакетов (Wireshark), чтобы увидеть разницу в том, что делает браузер, по сравнению с тем, что делал я. Пока что результатом по-прежнему является «Вы не можете создать пустую вставку». Я думаю, это потому, что код перед данными формы меняется каждый раз «.——WebKitFormBoundary________________»

5. Да, я получаю то же самое даже при публикации, казалось бы, идентичных данных через WinInet. Возможно, они делают что-то скрытое на стороне сервера…

Ответ №1:

Ваш код почти корректен, вы должны убедиться в следующих моментах:

  1. char* hdrs="Content-Type: application/x-www-form-urlencoded"; вы должны убедиться, что возвращаемый объект из сообщения POST будет иметь тип x-www-form-urlencoded или JSON . если это JSON, вам нужно определить char* hdrs="Content-Type: application/jsonrn"; Примечание: вы должны добавить rn к hdr.

  2. попробуйте вызвать метод ReadFile с буфером размером 10000, например, и напечатать buffer , он напечатает вывод ответа на соединение

  3. В HINTERNET hRequest2 = HttpOpenRequest(hConnect, "POST","/", NULL, NULL, accept, 0, 0); вместо «/» вы должны вызвать путь к запрошенному API, например: .
    В HINTERNET hRequest2 = HttpOpenRequest(hConnect, "POST", "/users/jsonlogin", NULL, NULL, accept, 0, 0);