[C++\HTTP] Пример простой отправки POST\GET

Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
991
Реакции[?]
1,209
Поинты[?]
3K
Случайно нашел свою флешку, которую про*бал около трех лет назад(хз как она могла под обшивку авто попасть....)


Пример простой обвязки над Wininet для отправки запросов. Писал кому-то для примера. возможно еще кому-то пригодится))

AsyncInet.h
Код:
//https://github.com/Codeh4ck/AsyncWinInet
#pragma once
#include <conio.h>
#include <windows.h>
#include <string>
#include <WinInet.h>
#include <iostream>
#pragma comment (lib, "Wininet.lib")
 

class AsyncInet;


typedef struct _InetContext
{
    AsyncInet *obj;
    DWORD dwContext;
} InetContext;



typedef enum _RequestType
{
    GET,
    POST
} RequestType;

class AsyncInet
{
public:
    AsyncInet();
    ~AsyncInet();

    enum
    {
        CONTEXT_CONNECT,
        CONTEXT_REQUESTHANDLE
    };

    BOOL Connect(std::string szAddr,
        std::string szAgent,
        unsigned short port = INTERNET_DEFAULT_HTTP_PORT,
        
        DWORD dwTimeout = 20 * 1000);

    BOOL SendRequest(
        std::string szURL,
        RequestType requestType,
        std::string szRequestData,
        std::string szReferrer,
        DWORD dwTimeout = 20 * 1000);

    unsigned long ReadData(
        PBYTE lpBuffer,
        DWORD dwSize,
        DWORD dwTimeout = 20 * 1000);

    void CloseConnection();

    static void WINAPI CallbackFunction(
        HINTERNET hInternet,
        DWORD dwContext,
        DWORD dwInetStatus,
        LPVOID lpStatusInfo,
        DWORD dwStatusInfoLength);

protected:
    InetContext context;
    HANDLE      hConnectEvent,
                hRequestOpenEvent,
                hRequestCompleteEvent;
    HINTERNET   hInetInstance,
                hInetConnect,
                hInetRequest;

};
AsyncInet.cpp
Код:
#include "AsyncInet.h"

AsyncInet::AsyncInet()
{
    this->hConnectEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    this->hRequestOpenEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    this->hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    this->hInetInstance = NULL;
    this->hInetConnect = NULL;
    this->hInetRequest = NULL;
}

AsyncInet::~AsyncInet()
{
    if (this->hConnectEvent)
        CloseHandle(this->hConnectEvent);

    if (this->hRequestOpenEvent)
        CloseHandle(this->hRequestOpenEvent);

    if (this->hRequestCompleteEvent)
        CloseHandle(this->hRequestCompleteEvent);

    CloseConnection();
    //std::cout << "CloseConnection" << std::endl;
}

BOOL AsyncInet::Connect(
    std::string szAddr,
    
    std::string szAgent,
    unsigned short port,
    DWORD dwTimeout)
{
    CloseConnection();

    ResetEvent(this->hConnectEvent);
    ResetEvent(this->hRequestOpenEvent);
    ResetEvent(this->hRequestCompleteEvent);

    if (!(this->hInetInstance =
        InternetOpenA(szAgent.c_str(),
        INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC)))
    {
        return FALSE;
    }

    if (InternetSetStatusCallbackA(this->hInetInstance, (INTERNET_STATUS_CALLBACK)&CallbackFunction))
    {
        return FALSE;
    }

    this->context.dwContext = AsyncInet::CONTEXT_CONNECT;
    this->context.obj = this;

    this->hInetConnect = InternetConnectA(this->hInetInstance, szAddr.c_str(),
        port, NULL, NULL,
        INTERNET_SERVICE_HTTP, INTERNET_FLAG_KEEP_CONNECTION |
        INTERNET_FLAG_NO_CACHE_WRITE, reinterpret_cast<DWORD>(&this->context));

    if (this->hInetConnect == NULL)
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
            if (WaitForSingleObject(this->hConnectEvent, dwTimeout))
                return FALSE;
        }
        return FALSE;
    }

    if (this->hInetConnect == NULL)
    {
        return FALSE;
    }

    return TRUE;
}

void AsyncInet::CloseConnection()
{
    if (this->hInetInstance)
        InternetCloseHandle(this->hInetInstance);

    if (this->hInetConnect)
        InternetCloseHandle(this->hInetConnect);

    if (this->hInetRequest)
        InternetCloseHandle(this->hInetRequest);

    this->hInetInstance = NULL;
    this->hInetConnect = NULL;
    this->hInetRequest = NULL;

}

void WINAPI AsyncInet::CallbackFunction(
    HINTERNET hInternet,
    DWORD dwContext,
    DWORD dwInetStatus,
    LPVOID lpStatusInfo,
    DWORD dwStatusInfoLength)
{

    InetContext *ctx = reinterpret_cast<InetContext*>(dwContext);

    switch (ctx->dwContext)
    {
    case AsyncInet::CONTEXT_CONNECT:
        if (dwInetStatus == INTERNET_STATUS_HANDLE_CREATED)
        {
            INTERNET_ASYNC_RESULT *inetResult = reinterpret_cast<INTERNET_ASYNC_RESULT*>(lpStatusInfo);
            ctx->obj->hInetConnect = reinterpret_cast<HINTERNET>(inetResult->dwResult);
            SetEvent(ctx->obj->hConnectEvent);
        }
        break;
    case AsyncInet::CONTEXT_REQUESTHANDLE:
        switch (dwInetStatus)
        {
        case INTERNET_STATUS_HANDLE_CREATED:
            {
                INTERNET_ASYNC_RESULT *inetResult1 = reinterpret_cast<INTERNET_ASYNC_RESULT*>(lpStatusInfo);
                ctx->obj->hInetRequest = reinterpret_cast<HINTERNET>(inetResult1->dwResult);
                SetEvent(ctx->obj->hRequestOpenEvent);
            }
            break;
        case INTERNET_STATUS_REQUEST_COMPLETE:
            SetEvent(ctx->obj->hRequestCompleteEvent);
            break;
        }
        break;
    }
}

BOOL AsyncInet::SendRequest(std::string szURL, RequestType requestType, std::string szRequestData, std::string szReferrer, DWORD dwTimeout)
{

    this->context.dwContext = AsyncInet::CONTEXT_REQUESTHANDLE;
    this->context.obj = this;

    std::string szVerb;
    if (requestType == RequestType::GET)
        szVerb = "GET";
    else
        szVerb = "POST";

    this->hInetRequest = HttpOpenRequestA(this->hInetConnect, szVerb.c_str(), szURL.c_str(),
        NULL, szReferrer.c_str(), NULL,
        INTERNET_FLAG_RELOAD | INTERNET_FLAG_KEEP_CONNECTION
        | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_FORMS_SUBMIT
        | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS
        | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP, reinterpret_cast<DWORD>(&this->context));

    if (this->hInetRequest == NULL)
    {
        std::cout << GetLastError() << std::endl;
        if (GetLastError() == ERROR_IO_PENDING)
        {
            if (WaitForSingleObject(this->hRequestOpenEvent, dwTimeout))
                return FALSE;
        }
    }

    if (this->hInetRequest == NULL)
        return FALSE;

    BOOL requestFlag;

    if (requestType == RequestType::GET)
    {
        requestFlag = HttpSendRequestA(this->hInetRequest, NULL, 0, const_cast<char*>(szRequestData.c_str()), szRequestData.size());
    }
    else {
        std::string szHeaders = "Content-Type: application/x-www-form-urlencoded";
        requestFlag = HttpSendRequestA(this->hInetRequest, szHeaders.c_str(), szHeaders.size(), const_cast<char*>(szRequestData.c_str()), szRequestData.size());
    }

    if (!requestFlag)
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
            if (WaitForSingleObject(this->hRequestCompleteEvent, dwTimeout) == WAIT_TIMEOUT)
            {
                CloseConnection();
                return FALSE;
            }
        }
    }
    return TRUE;
}

unsigned long AsyncInet::ReadData(PBYTE lpBuffer, DWORD dwSize, DWORD dwTimeout)
{
    INTERNET_BUFFERS inetBuffers;
    memset(&inetBuffers, 0, sizeof(inetBuffers));

    inetBuffers.dwStructSize = sizeof(inetBuffers);
    inetBuffers.lpvBuffer = lpBuffer;
    inetBuffers.dwBufferLength = dwSize - 1;

    this->context.dwContext = AsyncInet::CONTEXT_REQUESTHANDLE;
    this->context.obj = this;

    if (!InternetReadFileEx(this->hInetRequest, &inetBuffers, 0,
        reinterpret_cast<DWORD>(&this->context)))
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
            if (WaitForSingleObject(this->hRequestCompleteEvent, dwTimeout) == WAIT_TIMEOUT)
            {
                return FALSE;
            }
        }
    }

    return inetBuffers.dwBufferLength;
}
cWeb.h
Код:
#pragma once
#include <vector>

#include "AsyncInet.h"
class cWeb  :
    public AsyncInet
{
public:

    cWeb(const std::string& Host)
    {
        this->szHost = Host;
        m_QueryParams.clear();
    }
    virtual ~cWeb()
    {
        CloseConnection();
    }
    
    
    void        setAgent(const std::string& szAgent)
    {
        this->szAgent = szAgent;
    }
    void        setScript(const std::string& szScript)
    {
        this->szScript = szScript;
    }
    void        addQueryParam(const std::string& name, const std::string& value)
    {
        QueryParam newParam;
        newParam.name = name;
        newParam.value = value;
        m_QueryParams.push_back(newParam);
    }
    BOOL        Conect()
    {
        return Connect(this->szHost, this->szAgent);
    }
    BOOL        Request(const std::string& data = "")
    {
        std::string PostData = "";
        if (data.empty())
        {
            std::vector<QueryParam>::iterator it, end = m_QueryParams.end();
            for (it = m_QueryParams.begin(); it != end; it++)
                PostData += it->name + "=" + it->value + "&";
        }
        else
            PostData = data;
        return SendRequest(this->szScript  , RequestType::POST, PostData, "");
    }
    std::string getAnswer()
    {
        std::string szResponse = "";
        char szBuf[1024];
        int iLength;

        while ((iLength =  ReadData(reinterpret_cast<PBYTE>(szBuf), 1024)) > 0)
        {

            szBuf[iLength] = 0;
            szResponse += szBuf;
        }

        return szResponse;
    }
private:
    std::string  szHost;
    std::string  szScript;
    std::string  szAgent;
    struct QueryParam
    {
        std::string name;
        std::string value;
    };
    std::vector<QueryParam> m_QueryParams;
};

Ex:



Код:
/*Задаем объект класса и передаем в него  наш хост*/
cWeb *m_pWeb = new cWeb("YouHost.ru");

/*Устанавливаем UserAgent если нужно*/
m_pWeb->setAgent("MyAgent");

/*Пробуем соеденится с сервером*/
    if (m_pWeb->Conect())
    {
      /*Указываем наш скрипт для обработки запросов*/
        m_pWeb->setScript("DataRequest.php");
        
        /*Указываем параметры для Post-запроса(addQueryParam(имя_параметра, параметр)*/
        m_pWeb->addQueryParam("MESSAGE", "TEST_POST");
        m_pWeb->addQueryParam("VALUE1", "123");
        m_pWeb->addQueryParam("VALUE2", "456");
        
        /*пробуем отправить запрос*/
        if (m_pWeb->Request())
        {   
        /*получаем ответ от сервера*/
            const std::string szResultAnswer = m_pWeb->getAnswer();
            
            //.......
        }
    }
    
    /*удаляем созданный экземпляр класса и завершаем работу с сервером*/
    delete m_pWeb;

DataRequest.php
PHP:
<?php

     //проверяесм кто подал запрос
     if($_SERVER['HTTP_USER_AGENT'] != "MyAgent")
              exit ( "error agent");

    
     if(isset($_POST['MESSAGE']))
        {
            $ClientMessage = $_POST['MESSAGE'];
            switch ($ClientMessage)
            {
             case 'TEST_POST':
            $value1 = $_POST['VALUE1'];
            $value2  = $_POST['VALUE2'];
             #.....
            break;
            }
        }
?>
 
Эксперт
Статус
Оффлайн
Регистрация
16 Ноя 2017
Сообщения
1,570
Реакции[?]
1,266
Поинты[?]
4K
Крайслер , а через сниффер ведь можно ссылку спалить?) Зафигачь туториал по сокет подключениям, как у нашего любимого kurwa polak :roflanEbalo:
За тутор грац :da:
 
Забаненный
Статус
Оффлайн
Регистрация
22 Мар 2019
Сообщения
148
Реакции[?]
41
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Крайслер , а через сниффер ведь можно ссылку спалить?) Зафигачь туториал по сокет подключениям, как у нашего любимого kurwa polak :roflanEbalo:
За тутор грац :da:
Sslpinning - и не будет никакой сниффер видеть твой траффик.
А подключение по сокетам бесполезно - только если шифровать получаемые/отправляемые данные (но какой смысл - если то же самое можно делать по https?)
 
Эксперт
Статус
Оффлайн
Регистрация
16 Ноя 2017
Сообщения
1,570
Реакции[?]
1,266
Поинты[?]
4K
Sslpinning - и не будет никакой сниффер видеть твой траффик.
А подключение по сокетам бесполезно - только если шифровать получаемые/отправляемые данные (но какой смысл - если то же самое можно делать по https?)
(SSLStrip)
 
Забаненный
Статус
Оффлайн
Регистрация
22 Мар 2019
Сообщения
148
Реакции[?]
41
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Эксперт
Статус
Оффлайн
Регистрация
16 Ноя 2017
Сообщения
1,570
Реакции[?]
1,266
Поинты[?]
4K
Начинающий
Статус
Оффлайн
Регистрация
11 Май 2017
Сообщения
35
Реакции[?]
23
Поинты[?]
0
Пардон, вы правы: Неплохое средство защиты. Спасибо за наводку :roflanzdarova:
есть разве что минусы этого действа, обновления софта придётся качать по http ибо ssl сертификат имеет особенность истекать.
так же по поводу сокетов, общение по https гораздо медленнее чем по чистому tcp.
по поводу гайдов, накой они нужны если есть семплы (или документация) нужных тебе действий там же где ты находишь библиотеку
 
Сверху Снизу