MFC下使用winInet实现Get与Post功能的http客户端,实现文件上传,实现basic认证

前言

winhttp与winInet主要区别有以下几点:

  1. winHttp被设计为主要应用再服务器端应用程序的场景下,让服务器端应用程序访问HTTP服务器。winINet被设计为一个HTTP客户端平台,用来交互式桌面应用程序。服务器端应用程序要求HTTP客户端服务使用winHttp,客户端则使用WInet。
  2. WinHTTP也可以用于系统服务以及基于HTTP的客户端应用,但是对于那种需要使用到FTP协议,cookie保存,缓存cache,自动证书对话框处理,IE兼容,或者下载平台支持的应用则应该使用WinINet。
  3. WinINet是WinHTTP的一个超集。按照Microsoft的说法,在这两者之间做选择的时候最好选择WinINet,除非你是计划运行一个服务器或者是一个能够仿造请求及session隔离的类似于服务器的进程。

一、winInet接口

官网地址:https://learn.microsoft.com/zh-cn/windows/win32/wininet/portal

在这里插入图片描述

二、客户端介绍

在这里插入图片描述
该客户端工程基于VS2019下,使用winInet进行实现。主要功能是通过Get和Post与服务器进行交互,认证采用了basic认证。服务端实现程序可以参考我的另一篇博客:https://blog.csdn.net/linyibin_123/article/details/129562224。

三、核心代码

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);
}

四、工程下载

下载地址:https://download.csdn.net/download/linyibin_123/87600814

五、测试结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/linyibin_123/article/details/129695087
今日推荐