Under MFC, use winInet to implement http client with Get and Post functions, realize file upload, and realize basic authentication

foreword

The main differences between winhttp and winInet are as follows:

  1. winHttp is designed to be used mainly in the context of server-side applications, allowing server-side applications to access HTTP servers. winINet is designed as an HTTP client platform for interactive desktop applications. The server side application requires the HTTP client service to use winHttp and the client side to use WInet.
  2. WinHTTP can also be used for system services and HTTP-based client applications, but for applications that need to use the FTP protocol, cookie storage, cache cache, automatic certificate dialog box processing, IE compatibility, or download platform support, WinINet should be used .
  3. WinINet is a superset of WinHTTP. According to Microsoft, when choosing between the two, it is best to choose WinINet, unless you plan to run a server or a server-like process that can simulate request and session isolation.

1. winInet interface

Official website address: https://learn.microsoft.com/zh-cn/windows/win32/wininet/portal

insert image description here

2. Client introduction

insert image description here
The client project is based on VS2019 and implemented using winInet. The main function is to interact with the server through Get and Post, and the authentication adopts basic authentication. For the server implementation program, please refer to my other blog: https://blog.csdn.net/linyibin_123/article/details/129562224.

3. Core code

HttpClient.h

#pragma once

int myprint(const char* msg, ...);

class HttpClient
{
public:
    HttpClient();
    virtual ~HttpClient();

    int HttpGetSend(const char* url, char* RecvText, char* userName, char* pwd);

    int HttpPostSend(const char* url, const char* Head, const char* PostData, 
            std::string& recvData, char* userName, char* pwd);
    
    void HttpUploadFile(const char* url, CString strFilePath, char* userName, char* pwd);
};

HttpClient.cpp

#include "pch.h"
#include "HttpClient.h"
#include <Windows.h>
#include <wininet.h>
#include <afxinet.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/timeb.h>
#include <errno.h>
#include <WinSock2.h>
#include <math.h>
#include <time.h>

#pragma comment (lib, "Wininet.lib")

static const char b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char reverse_table[128] =
{
	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
	64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
	64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
	41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64
};

unsigned char* base64_encode(unsigned char* bindata, size_t inlen, unsigned char** out, size_t* outlen)
{
	size_t _outlen = *outlen;
	unsigned char* _out = NULL;
	size_t out_pos = 0;

	if (NULL == *out)
	{
		_outlen = (inlen / 3 + (inlen % 3 != 0)) * 4 + 1;
		_out = (unsigned char*)malloc(_outlen);
	}
	else
	{
		_outlen = *outlen;
		_out = *out;
	}

	memset(_out, '=', _outlen);
	_out[_outlen - 1] = 0;

	unsigned int bits_collected = 0;
	unsigned int accumulator = 0;
	for (int i = 0; i < inlen; i++)
	{
		accumulator = (accumulator << 8) | (bindata[i] & 0xffu);
		bits_collected += 8;
		while (bits_collected >= 6)
		{
			bits_collected -= 6;
			_out[out_pos++] = b64_table[(accumulator >> bits_collected) & 0x3fu];
		}
	}

	if (bits_collected >= 6)
	{
		if (NULL == *out)
		{
			free(_out);
		}
		return NULL;
	}

	if (bits_collected > 0)
	{
		// Any trailing bits that are missing.
		accumulator <<= 6 - bits_collected;
		_out[out_pos++] = b64_table[accumulator & 0x3fu];
	}

	*outlen = _outlen;
	*out = _out;
	return _out;
}

unsigned char* base64_decode(unsigned char* bindata, size_t inlen, unsigned char** out, size_t* outlen)
{
	size_t _outlen = *outlen;
	unsigned char* _out = NULL;
	int bits_collected = 0;
	unsigned int accumulator = 0;
	size_t out_pos = 0;

	if (NULL == *out)
	{
		_outlen = inlen;
		_out = (unsigned char*)malloc(_outlen);
	}
	else
	{
		_outlen = *outlen;
		_out = *out;
	}

	int c = 0;
	for (int i = 0; i < inlen; i++)
	{
		c = bindata[i];
		if (isspace(c) || c == '=')
		{
			// Skip whitespace and padding. Be liberal in what you accept.
			continue;
		}
		if ((c > 127) || (c < 0) || (reverse_table[c] > 63))
		{
			return NULL;
		}
		accumulator = (accumulator << 6) | reverse_table[c];
		bits_collected += 6;
		if (bits_collected >= 8)
		{
			bits_collected -= 8;
			_out[out_pos++] = (char)((accumulator >> bits_collected) & 0xffu);
		}
	}

	*outlen = _outlen;
	*out = _out;
	return _out;
}

char regcode[] = { 0x0E, 0x23, 0x11, 0x14, 0x0E, 0x15, 0x0F, 0x06, 0x04, 0x2F, 0x03,
0x3C, 0x04, 0x3D, 0x0B, 0x1E, 0x08, 0x17, 0x09, 0x18, 0x10, 0x35, 0x07, 0x32, 0x02,
0x1B, 0x03, 0x0C, 0x02, 0x05, 0x03, 0x22, 0x1E, 0x17, 0x21, 0x1C, 0x18, 0x2D, 0x21,
0x22, 0x1A, 0x2B, 0x1B, 0x24, 0x14, 0x2D, 0x1F, 0x1E, 0x16, 0x3F, 0x15, 0x18, 0x18,
0x39, 0x17, 0x42, 0x14, 0x1F, 0x13, 0x0C, 0x16, 0x21, 0x19, 0x0E, 0x26, 0x1F, 0x2B,
0x30, 0x30, 0x05, 0x31, 0x3A, 0x2A, 0x2B, 0x2B, 0x0C, 0x2E, 0x31, 0x2D, 0x36, 0x26,
0x37, 0x27, 0x10, 0x26, 0x29, 0x27, 0x3E, 0x22, 0x3B, 0x25, 0x28, 0x2C, 0x19, 0x25,
0x2E, 0x40, 0x3F, 0x41, 0x34 };

char addcode[] = { 0x0E, 0x23, 0x11, 0x14, 0x0E, 0x15, 0x0F, 0x06, 0x04, 0x2F, 0x03,
0x3C, 0x04, 0x3D, 0x0B, 0x1E, 0x08, 0x17, 0x09, 0x18, 0x10, 0x35, 0x07, 0x32,
0x02, 0x1B, 0x03, 0x0C, 0x02, 0x05, 0x03, 0x22, 0x1E, 0x17, 0x21, 0x1C, 0x18,
0x2D, 0x21, 0x22, 0x1A, 0x2B, 0x1B, 0x24, 0x14, 0x2D, 0x1F, 0x1E, 0x16, 0x3F,
0x15, 0x18, 0x18, 0x39, 0x17, 0x42, 0x14, 0x1F, 0x13, 0x0C, 0x16, 0x21, 0x19,
0x0E, 0x26, 0x1F, 0x2B, 0x28, 0x30, 0x35, 0x31, 0x36, 0x30, 0x2B, 0x2B, 0x0C,
0x2A, 0x05, 0x2B, 0x2A, 0x26, 0x3F, 0x23, 0x10, 0x24, 0x3D, 0x31, 0x16, 0x22,
0x2B, 0x25, 0x24, 0x22, 0x31 };

int myprint(const char* msg, ...)        					// 打印函数
{
	char buf[1600] = {0};
	char test[1600] = {0};
	va_list  va;
	time_t now = time(NULL);
	char szTime[20] = {0};
	struct tm t;
	localtime_s(&t, &now);
	_snprintf_s(szTime, sizeof(szTime), sizeof(szTime)-1, "%4d-%02d-%02d %02d:%02d:%02d", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
	va_start (va, msg);
	_vsnprintf_s(buf, sizeof(buf) - 1, (char*)msg, va);
	va_end(va);

	_snprintf_s(test, sizeof(test), sizeof(test) - 1, "[Time:%s]===%s===\n", szTime, buf);
	OutputDebugStringA(test);
	return 0;
}
/
HttpClient::HttpClient()
{
}

HttpClient::~HttpClient()
{
}

int HttpClient::HttpGetSend(const char* url, char* RecvText, char* userName, char* pwd)
{
	char userPwd[64];
	char Authorization[64];
	if (!url || !RecvText)
		return -1;

	CString csUrl = url;
	LPCTSTR lpUrl = (LPCTSTR)csUrl;

	CInternetSession* pSession = new CInternetSession();
	pSession->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 2000);
	CHttpConnection* pConnection = NULL;
	CString strServer;
	CString strObject;
	DWORD dwServiceType;
	INTERNET_PORT nPort;

	snprintf(userPwd, sizeof(userPwd) - 1, "%s:%s", userName, pwd);
	int sLen = strlen(userPwd);
	unsigned char* out = 0;
	size_t len = 0;
	unsigned char* strcode = (unsigned char*)userPwd;
	unsigned char* encode = base64_encode(strcode, strlen((char*)strcode), &out, &len);
	snprintf(Authorization, sizeof(Authorization) - 1, "Authorization: Basic %s", encode);
	CString strHeaders = Authorization;
	strHeaders += _T("\r\n");
	strHeaders += _T("Content-Type:  text/xml\r\n");

    DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT;

	AfxParseURL(lpUrl, dwServiceType, strServer, strObject, nPort);
	if (AFX_INET_SERVICE_HTTP != dwServiceType && AFX_INET_SERVICE_HTTPS != dwServiceType)
	{
		myprint("########### Url No Http or Https ###########");
		return -1;
	}

    //https
    if(AFX_INET_SERVICE_HTTPS == dwServiceType)
    {
        
        dwFlags = dwFlags|INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
    }  

	try
	{
		myprint("########### strServer:%S, nPort:%d", strServer, nPort);
		//pSession->SetCookie(strObject, L"Session_id", L"");
		pSession->SetCookie(lpUrl, _T("Session_id"), _T("deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT"));
		pConnection = pSession->GetHttpConnection(strServer, nPort);
		if (NULL == pConnection)
		{
			myprint("########### pConnection == NULL ");
			delete pSession;
			return -1;
		}

		CHttpFile* pFile = pConnection->OpenRequest("GET", strObject, NULL, 1, NULL, NULL, INTERNET_FLAG_EXISTING_CONNECT);
		if (NULL == pFile)
		{
			myprint("########### pFile Open Error ");
			pConnection->Close();
			delete pSession;
			return -1;
		}

		pFile->AddRequestHeaders(strHeaders);
		pFile->SendRequest();
		pFile->Read((void*)RecvText, 400);

		myprint("RecvText:%s", RecvText);
		if (strstr(RecvText, "401 Unauthorized") || strstr(RecvText, "404 Not Found") ||
			RecvText == NULL || RecvText[0] == '\0')
		{
			myprint("########### return error,username or password error or page not found");
			pFile->Close();
			pConnection->Close();
			delete pSession;
			return -2;
		}

		pFile->Close();
		pConnection->Close();
		pSession->Close();
		delete pSession;
		return 0;
	}
	catch (CInternetException* e)
	{
		DWORD dwErrorCode = e->m_dwError;
		e->Delete();
		e = NULL;
		return -1;
	}
}

int HttpClient::HttpPostSend(const char* url, const char* Head, const char* PostData, 
        std::string& recvData, char* userName, char* pwd)
{
    myprint("yibin test HttpPostSend 000");
    if(!url)
        return NULL;

    CString strServer;
	CString strObject;
	DWORD dwServiceType;
	INTERNET_PORT nPort;
    char sIp[64];
    char sPath[64];

    CString csUrl = url;
	LPCTSTR lpUrl = (LPCTSTR)csUrl;

    HINTERNET hOpen = InternetOpenA("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)",
                                1,NULL,NULL,NULL);
    if(hOpen <= 0)
    {
        myprint("########### InternetOpenA Failed. ###########");
        return -1;
    }

    AfxParseURL(lpUrl, dwServiceType, strServer, strObject, nPort);

    strcpy_s(sIp, strServer);
    strcpy_s(sPath, strObject);

    myprint("sIp:%s, sPath:%s",sIp, sPath);
    
    HINTERNET hCon=InternetConnectA(hOpen, sIp, nPort, NULL, NULL, 3, NULL, NULL);
    if(hCon <= 0)
    {
        myprint("########### hCon<=0 ###########");
        InternetCloseHandle(hOpen);
        return -1;
    }
    
    if (AFX_INET_SERVICE_HTTP != dwServiceType && AFX_INET_SERVICE_HTTPS != dwServiceType)
    {
        myprint("########### Url No Http or Https ###########");
        InternetCloseHandle (hCon);
        InternetCloseHandle (hOpen);
        return -1;
    }

    DWORD dwFlags = INTERNET_FLAG_RELOAD|INTERNET_COOKIE_THIRD_PARTY;
    
    if(AFX_INET_SERVICE_HTTPS == dwServiceType)
    {
        dwFlags = dwFlags|INTERNET_FLAG_SECURE;
    }
    else
    {
        dwFlags = dwFlags|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS;
    }
    
    std::string Headers;
    if(Head != NULL)
    {
        Headers = Head;
        if(Headers.find("Referer: ") == Headers.npos)
        {
            Headers += "Referer: ";
            if(AFX_INET_SERVICE_HTTPS == dwServiceType)
            {
                Headers += "https://";
            }
            else
            {
                Headers += "http://";
            }
            Headers += sIp;
            Headers += sPath;
        }
        if(Headers.find("Accept: ") == Headers.npos)
        {
            Headers += "\r\nAccept: */*";
        }
        if(Headers.find("Accept-Language: ") == Headers.npos)
        {
            Headers += "\r\nAccept-Language: zh-cn";
        }

        if(Headers.find("Authorization: ") == Headers.npos)
        {
            char userPwd[64];
            char Authorization[64];
            snprintf(userPwd, sizeof(userPwd) - 1, "%s:%s", userName, pwd);
        	int sLen = strlen(userPwd);
        	unsigned char* out = 0;
        	size_t len = 0;
        	unsigned char* strcode = (unsigned char*)userPwd;
        	unsigned char* encode = base64_encode(strcode, strlen((char*)strcode), &out, &len);
            snprintf(Authorization, sizeof(Authorization) - 1, "\r\nAuthorization: Basic %s", encode);
        
            Headers += Authorization;
        }
        if(Headers.find("Content-Type: ") == Headers.npos)
        {
            Headers += "\r\nContent-Type: application/x-www-form-urlencoded";
        }
    }

    HINTERNET hReq = 0;

    {
        hReq = HttpOpenRequestA(hCon, "POST", sPath, "HTTP/1.1" , NULL, NULL, dwFlags, NULL);
    }
    if (hReq <= 0)
    {
        myprint("########### HttpOpenRequestA Failed. ###########");
        InternetCloseHandle (hCon);
        InternetCloseHandle (hOpen);
        return -1;
    }
    {
        char* chTmp = _strdup(PostData);
        HttpSendRequestA(hReq, Headers.c_str(), Headers.length(), chTmp, strlen(PostData));
        delete chTmp;
    }

    while (true)
    {
        char buf[1024]={0};
        DWORD Read = 0;
        InternetReadFile(hReq, buf, 1024, &Read);
        if(Read <= NULL)
            break;
        recvData.append(buf,Read);
    }
    InternetCloseHandle(hReq);
    InternetCloseHandle(hCon);
    InternetCloseHandle(hOpen);
    
    return 0;
}

void HttpClient::HttpUploadFile(const char* url, CString strFilePath, char* userName, char* pwd)
{
    HINTERNET hSession = 0;
    HINTERNET hConnect = 0;
    HINTERNET hRequest = 0;

    DWORD dwNumberOfBytesWritten = 0;
    DWORD dwBytesSend = 0;

    INTERNET_BUFFERS BufferIn;

    DWORD dwFlag;
    LPCTSTR boundary = TEXT("-----------------------------67491722032265"); //随机字符串
    LPCSTR aboundary = "-----------------------------67491722032265"; //ansi

    CString strServer;
	CString strObject;
	DWORD dwServiceType;
	INTERNET_PORT nPort;
    char sIp[64];
    char sPath[64];

    CString csUrl = url;
	LPCTSTR lpUrl = (LPCTSTR)csUrl;
    AfxParseURL(lpUrl, dwServiceType, strServer, strObject, nPort);

    strcpy_s(sIp, strServer);
    strcpy_s(sPath, strObject);

    myprint("sIp:%s, sPath:%s",sIp, sPath);

    CString strFileName = strFilePath.Right(strFilePath.GetLength()-strFilePath.ReverseFind('\\')-1);
    char sFileName[32];
    strcpy_s(sFileName, strFileName);
    myprint("sFileName:%s",sFileName);

    HANDLE hFile;
    hFile = CreateFile((LPTSTR)(LPCTSTR)strFilePath,
        GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);

    DWORD dwFileSize = GetFileSize(hFile, 0);

    char userPwd[64];
    char Authorization[64];
    snprintf(userPwd, sizeof(userPwd) - 1, "%s:%s", userName, pwd);
	int sLen = strlen(userPwd);
	unsigned char* out = 0;
	size_t len = 0;
	unsigned char* strcode = (unsigned char*)userPwd;
	unsigned char* encode = base64_encode(strcode, strlen((char*)strcode), &out, &len);
    snprintf(Authorization, sizeof(Authorization) - 1, "Authorization: Basic %s", encode);

    TCHAR content_type[128];
    _stprintf_s(content_type, TEXT("Content-Type: multipart/form-data; boundary=%s"), boundary);
    LPTSTR referer = TEXT("Referer: http://127.0.0.1/upload/~upload");
    LPTSTR accept = TEXT("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    LPTSTR accept_lan = TEXT("Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
    LPTSTR accept_encoding = TEXT("Accept-Encoding: gzip, deflate");
    LPTSTR user_agent = TEXT("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0");


    hSession = InternetOpen(_T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"),
        INTERNET_OPEN_TYPE_PRECONFIG,
        0,
        INTERNET_INVALID_PORT_NUMBER,
        0);
    if (0 == hSession)
    {
        return;
    }

    hConnect = InternetConnect(hSession,
        sIp,
        nPort,
        _T(""),
        _T(""),
        INTERNET_SERVICE_HTTP,
        0,
        0);
    if (0 == hConnect)
    {

        InternetCloseHandle(hSession);
        return;
    }

    dwFlag = INTERNET_FLAG_KEEP_CONNECTION;

    hRequest = HttpOpenRequest(hConnect,
        _T("POST"),
        sPath,
        HTTP_VERSION,
        0,                //Referrer
        0,                //AcceptTypes 
        dwFlag,
        0);
    if (0 == hRequest)
    {

        InternetCloseHandle(hConnect);
        InternetCloseHandle(hSession);
        return;
    }

    HttpAddRequestHeaders(hRequest, Authorization, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
    HttpAddRequestHeaders(hRequest, content_type, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
    HttpAddRequestHeaders(hRequest, referer, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
    HttpAddRequestHeaders(hRequest, accept, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
    HttpAddRequestHeaders(hRequest, accept_lan, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
    HttpAddRequestHeaders(hRequest, accept_encoding, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);

    BYTE* lpBuffer = (BYTE*)VirtualAlloc(0, dwFileSize, MEM_COMMIT, PAGE_READWRITE);
    if (0 == lpBuffer)
    {
        InternetCloseHandle(hRequest);
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hSession);
        return;
    }

    DWORD dwRead;
    ReadFile(hFile, lpBuffer, dwFileSize, &dwRead, 0);

    CloseHandle(hFile);

    char first_boundary[128];
    char delimiter[128];
    char end_boundary[128];
    char content_dispos[128];
    
    sprintf_s(first_boundary, "--%s\r\n", aboundary);
    sprintf_s(delimiter, "\r\n--%s\r\n", aboundary);
    sprintf_s(end_boundary, "\r\n--%s--\r\n", aboundary);
    sprintf_s(content_dispos, "Content-Disposition: form-data; filename=\"%s\"\r\n", sFileName);

    //LPSTR content_dispos = "Content-Disposition: form-data; filename=\"test.txt\"\r\n";

    LPSTR content_type2 = "Content-Type: application/octet-stream\r\n\r\n";

    LPSTR rn = "\r\n";

    BufferIn.dwStructSize = sizeof(INTERNET_BUFFERS);
    BufferIn.Next = NULL;
    BufferIn.lpcszHeader = NULL;
    BufferIn.dwHeadersLength = 0;
    BufferIn.dwHeadersTotal = 0;
    BufferIn.lpvBuffer = NULL;
    BufferIn.dwBufferLength = 0;
    BufferIn.dwBufferTotal = dwFileSize
        + strlen(first_boundary)
        + strlen(content_dispos)
        + strlen(content_type2)
        + strlen(end_boundary); //Content-Length:
    BufferIn.dwOffsetLow = 0;
    BufferIn.dwOffsetHigh = 0;

    if (!HttpSendRequestEx(hRequest, &BufferIn, 0, 0, 0))
    {
        InternetCloseHandle(hRequest);
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hSession);
        return;
    }

    InternetWriteFile(hRequest, (byte*)first_boundary, strlen(first_boundary), &dwNumberOfBytesWritten); //first boundary
    InternetWriteFile(hRequest, (byte*)content_dispos, strlen(content_dispos), &dwNumberOfBytesWritten);
    InternetWriteFile(hRequest, (byte*)content_type2, strlen(content_type2), &dwNumberOfBytesWritten);
    InternetWriteFile(hRequest, lpBuffer, dwFileSize, &dwNumberOfBytesWritten);

    InternetWriteFile(hRequest, (byte*)end_boundary, strlen(end_boundary), &dwNumberOfBytesWritten);//last boundary

    HttpEndRequest(hRequest, 0, 0, 0);
    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hSession);

    VirtualFree(lpBuffer, 0, MEM_RELEASE);
}

myhttpclientDlg.h

// myhttpclientDlg.h: 头文件
#pragma once
#include "HttpClient.h"

class CmyhttpclientDlg : public CDialogEx
{
// 构造
public:
	CmyhttpclientDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_MYHTTPCLIENT_DIALOG };
#endif

private:
    CEdit   m_edUser;
    CEdit   m_edPwd;
    CEdit   m_edGetUrl;
    CEdit	m_edGetRecv;
    CEdit	m_edPostUrl;
    CEdit	m_edPostHead;
    CEdit	m_edPostBody;
    CEdit	m_edPostRecv;
	CEdit	m_edPostFilePath;
    BOOL    m_bPostFile;
    CButton	m_BtnBrowser;
    HttpClient m_httpClient;

protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持

// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedButtonGetClear();
	afx_msg void OnBnClickedButtonGetSend();
	afx_msg void OnBnClickedButtonPostSend();
	afx_msg void OnBnClickedButtonPostClear();
	afx_msg void OnBnClickedCheckFile();
	afx_msg void OnBnClickedButtonBrowser();
};

myhttpclientDlg.cpp

// myhttpclientDlg.cpp: 实现文件
#include "pch.h"
#include "framework.h"
#include "myhttpclient.h"
#include "myhttpclientDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CmyhttpclientDlg::CmyhttpclientDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MYHTTPCLIENT_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CmyhttpclientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT_USER, m_edUser);
    DDX_Control(pDX, IDC_EDIT_PWD, m_edPwd);
    DDX_Control(pDX, IDC_EDIT_GET_URL, m_edGetUrl);
    DDX_Control(pDX, IDC_EDIT_GET_RECV, m_edGetRecv);
    DDX_Control(pDX, IDC_EDIT_POST_URL, m_edPostUrl);
    DDX_Control(pDX, IDC_EDIT_POST_HEAD, m_edPostHead);
    DDX_Control(pDX, IDC_EDIT_POST_BODY, m_edPostBody);
    DDX_Control(pDX, IDC_EDIT_POST_RECV, m_edPostRecv);
    DDX_Control(pDX, IDC_EDIT_FILE, m_edPostFilePath);
    DDX_Control(pDX, IDC_BUTTON_BROWSER, m_BtnBrowser);
    DDX_Check(pDX, IDC_CHECK_FILE, m_bPostFile);
    
}

BEGIN_MESSAGE_MAP(CmyhttpclientDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_GET_CLEAR, &CmyhttpclientDlg::OnBnClickedButtonGetClear)
	ON_BN_CLICKED(IDC_BUTTON_GET_SEND, &CmyhttpclientDlg::OnBnClickedButtonGetSend)
	ON_BN_CLICKED(IDC_BUTTON_POST_SEND, &CmyhttpclientDlg::OnBnClickedButtonPostSend)
	ON_BN_CLICKED(IDC_BUTTON_POST_CLEAR, &CmyhttpclientDlg::OnBnClickedButtonPostClear)
	ON_BN_CLICKED(IDC_CHECK_FILE, &CmyhttpclientDlg::OnBnClickedCheckFile)
	ON_BN_CLICKED(IDC_BUTTON_BROWSER, &CmyhttpclientDlg::OnBnClickedButtonBrowser)
END_MESSAGE_MAP()


// CmyhttpclientDlg 消息处理程序
BOOL CmyhttpclientDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
	return TRUE; 
}

void CmyhttpclientDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	
	CDialogEx::OnSysCommand(nID, lParam);
	
}

void CmyhttpclientDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CmyhttpclientDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CmyhttpclientDlg::OnBnClickedButtonGetClear()
{
	// TODO: 在此添加控件通知处理程序代码
}


void CmyhttpclientDlg::OnBnClickedButtonGetSend()
{
	CString sUserName;
    CString sPassword;
    CString sUrl;

    m_edUser.GetWindowText(sUserName);
    m_edPwd.GetWindowText(sPassword);
    m_edGetUrl.GetWindowText(sUrl);

    char sText[1024] = {0};
    char url[256] = {0};
    char user[32] = {0};
    char pwd[32] = {0};
    strcpy_s(url, sUrl);
    strcpy_s(user, sUserName);
    strcpy_s(pwd, sPassword);
    
    myprint("url:%s", url);
    if(m_httpClient.HttpGetSend(url, sText, user, pwd) < 0)
    {
        AfxMessageBox(_T("GET 发送失败"));
    }
    else
    {
		CString sRecv;
		sRecv.Format(_T("%s"), sText);
		m_edGetRecv.SetWindowText(sRecv);
    }  
}


void CmyhttpclientDlg::OnBnClickedButtonPostSend()
{
    UpdateData(TRUE);
    
	CString sUserName;
    CString sPassword;
    CString sUrl;
    CString sHead;
    CString sBody;
     
    m_edUser.GetWindowText(sUserName);
    m_edPwd.GetWindowText(sPassword);
    m_edPostUrl.GetWindowText(sUrl);
    m_edPostHead.GetWindowText(sHead);
    m_edPostBody.GetWindowText(sBody);

    char url[256] = {0};
    char user[32] = {0};
    char pwd[32] = {0};
    char head[512] = {0};
    char body[1024] = {0};
    
    strcpy_s(url, sUrl);
    strcpy_s(user, sUserName);
    strcpy_s(pwd, sPassword);
    strcpy_s(head, sHead);
    strcpy_s(body, sBody);

    std::string recvData;

    if(m_bPostFile)
    {
        myprint("Post file");
        CString sFilePath;
        m_edPostFilePath.GetWindowText(sFilePath);
        m_httpClient.HttpUploadFile(url, sFilePath, user, pwd);
    }
    else
    {
        myprint("Post data");
        if(m_httpClient.HttpPostSend(url, head, body, recvData, user, pwd) < 0)
        {
            AfxMessageBox(_T("POST 发送失败"));
        }
        else
        {
    		myprint("recvData.c_str():%s", recvData.c_str());
    		CString sRecv;
    		sRecv.Format(_T("%s"), recvData.c_str());
    		m_edPostRecv.SetWindowText(sRecv);
        }
    }
}


void CmyhttpclientDlg::OnBnClickedButtonPostClear()
{
    m_edPostRecv.Clear();
}


void CmyhttpclientDlg::OnBnClickedCheckFile()
{
    UpdateData(TRUE);
    if (m_bPostFile)
    {
        myprint("m_bPostFile = true");
        m_BtnBrowser.EnableWindow(true);
    } 
    else
    {
        myprint("m_bPostFile = false");
        m_BtnBrowser.EnableWindow(false);
    }
}

void CmyhttpclientDlg::OnBnClickedButtonBrowser()
{
	CString strFile = _T("");
    CFileDialog dlgFile(true, NULL, NULL, OFN_HIDEREADONLY, _T("IMG Files (*.jpg)|*.jpg|GIF Files (*.gif)|*.gif|All Files (*.*)|*.*||"), NULL);
    if (dlgFile.DoModal())
    {
        strFile = dlgFile.GetPathName();
    }

    m_edPostFilePath.SetWindowText(strFile);
}

4. Engineering download

Download address: https://download.csdn.net/download/linyibin_123/87600814

5. Test results

insert image description here

Guess you like

Origin blog.csdn.net/linyibin_123/article/details/129695087