'POST form data using WinInet c++

I'm trying to make this program connect to a website and submit form data in order to login, but I don't know what I'm doing wrong. I have heard of others like curl and Winsock but I chose the WinINet library. So just for the testing of this program I've been using the website Pastebin to post to. So far, I haven't seen any results from this. If this program succeeds in posting the form data it will give me the header to the location of the post on their site.

Am I writing the form data char* correctly? I have seen on other stackoverflow posts where they had a large amount of dashes before some number then the put their form data.

Do I need to add something to it make it simulate clicking the submit button?
Do I need to write out values for each elements on the form?

I have tried HttpAddRequestHeaders and that didn't help me.

Also, I get the ERROR_INSUFFICIENT_BUFFER error on HttpOpenRequest but it still returns a valid HINTERNET.

#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,&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] = '\0';
    return pInfoBuffer;
}

void readfile(HINTERNET hRequest,char** buffs,int size){
    DWORD dwBytesAvailable;
    DWORD dwBytesRead;
    for(int i=0;i<size;i++){
        if(!InternetQueryDataAvailable(hRequest,&dwBytesAvailable,0,0)) break;
        buffs[i]=(char*)malloc(dwBytesAvailable+1);
        bool bResult=InternetReadFile(hRequest,buffs[i],dwBytesAvailable,&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("%s\n\n\n\n",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("%s\n\n\n\n",heads);

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

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


Solution 1:[1]

Your code is nearly correct, you must make sure of the following points:

  1. char* hdrs="Content-Type: application/x-www-form-urlencoded"; you must make sure that your return object from POST message will be of type x-www-form-urlencoded or JSON . if it's JSON you need to define char* hdrs="Content-Type: application/json\r\n"; Note: you must append \r\n to the hdrs.

  2. try to call readFile method with buffer of size 10000 for example and print buffer , it will print the output of the response to the connection

  3. In HINTERNET hRequest2 = HttpOpenRequest(hConnect, "POST","/", NULL, NULL, accept, 0, 0); instead of "/" you must call the path of the requested API for example: .
    In HINTERNET hRequest2 = HttpOpenRequest(hConnect, "POST", "/users/jsonlogin", NULL, NULL, accept, 0, 0);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ALOToverflow