#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:
Ваш код почти корректен, вы должны убедиться в следующих моментах:
-
char* hdrs="Content-Type: application/x-www-form-urlencoded";
вы должны убедиться, что возвращаемый объект из сообщения POST будет иметь типx-www-form-urlencoded
илиJSON
. если это JSON, вам нужно определитьchar* hdrs="Content-Type: application/jsonrn";
Примечание: вы должны добавитьrn
к hdr. -
попробуйте вызвать метод ReadFile с буфером размером 10000, например, и напечатать buffer , он напечатает вывод ответа на соединение
-
В
HINTERNET hRequest2 = HttpOpenRequest(hConnect, "POST","/", NULL, NULL, accept, 0, 0);
вместо «/» вы должны вызвать путь к запрошенному API, например: .
ВHINTERNET hRequest2 = HttpOpenRequest(hConnect, "POST", "/users/jsonlogin", NULL, NULL, accept, 0, 0);