1 : 	#include <windows.h>
     2 : 	#include <wininet.h>
     3 : 	#include <stdio.h>
     4 : 	
     5 : 	//wininet.libをリンク
     6 : 	#pragma comment(lib,"wininet.lib")
     7 : 	
     8 : 	//ユーザーエージェント文字列
     9 : 	#define GETWWWPAGE_USERAGENT	"KNO SampleAgent"
    10 : 	
    11 : 	//一度に確保するバッファサイズ
    12 : 	#define WWWGETREADBUFSIZE         (10240)
    13 : 	
    14 : 	//HTTP又はHTTPSのページを取得する
    15 : 	HGLOBAL GetWWWPage(
    16 : 					int* piStatusCode,	//ステータスコードを受け取る
    17 : 					char* szServer,		//接続先
    18 : 					char* szPath,		//要求ファイル
    19 : 					char* szMethod,		//GET or POST
    20 : 					char* szPostData,	//POSTするデータ
    21 : 					BOOL fIsSSL,		//SSL通信フラグ
    22 : 					unsigned short wPort)//ポート番号,0でデフォルト
    23 : 	{
    24 : 		HINTERNET hSession = NULL;
    25 : 	    HINTERNET hConnect = NULL;
    26 : 	    HINTERNET hRequest = NULL;
    27 : 		{
    28 : 			DWORD dwSize = 0;
    29 : 			INTERNET_BUFFERS inetbuf;
    30 : 			char szBuf[1024];
    31 : 			int iStatusCode=0;
    32 : 	
    33 : 			//デフォルトポートを設定
    34 : 			//INTERNET_DEFAULT_HTTPS_PORT = 443です。
    35 : 			if(wPort ==0) 
    36 : 				wPort = fIsSSL ? 
    37 : 							INTERNET_DEFAULT_HTTPS_PORT : 
    38 : 							INTERNET_DEFAULT_HTTP_PORT; 
    39 : 	
    40 : 	
    41 : 			//セッションを開く
    42 : 			hSession = InternetOpen(GETWWWPAGE_USERAGENT,
    43 : 									INTERNET_OPEN_TYPE_PRECONFIG,
    44 : 									NULL, NULL, 0);
    45 : 			if (hSession == NULL){
    46 : 				printf( "Error on InternetOpen %d\n", GetLastError() );
    47 : 				goto ONERROR_EXIT;
    48 : 			}
    49 : 			//接続
    50 : 			hConnect = InternetConnect(
    51 : 							hSession,
    52 : 							szServer,
    53 : 							wPort,
    54 : 							NULL,	//Username
    55 : 							NULL,	//Password
    56 : 							INTERNET_SERVICE_HTTP,
    57 : 							0,
    58 : 							0);
    59 : 			if (hConnect == NULL){
    60 : 				printf( "Error on InternetConnect %d\n", GetLastError() );
    61 : 				goto ONERROR_EXIT;
    62 : 			}
    63 : 	
    64 : 			//リクエストを開く
    65 : 			hRequest = HttpOpenRequest(
    66 : 						   hConnect,
    67 : 						   szMethod,
    68 : 						   szPath,
    69 : 						   NULL,
    70 : 						   NULL,
    71 : 						   NULL,
    72 : 						   INTERNET_FLAG_NO_CACHE_WRITE
    73 : 						   |(fIsSSL ? INTERNET_FLAG_SECURE:0),
    74 : 						   0);
    75 : 			if (hRequest == NULL){
    76 : 				printf( "Error on HttpOpenRequest %d\n", GetLastError() );
    77 : 				goto ONERROR_EXIT;
    78 : 			}
    79 : 	
    80 : 	
    81 : 			DWORD dwError = 0;
    82 : 			DWORD dwFlags;
    83 : 			DWORD dwBuffLen = sizeof(dwFlags);
    84 : 	
    85 : 			//セキュリティフラグを変更
    86 : 			BOOL fRet = InternetQueryOption(hRequest,
    87 : 											INTERNET_OPTION_SECURITY_FLAGS,
    88 : 											 (LPVOID)&dwFlags, &dwBuffLen);
    89 : 			if(fRet == FALSE){
    90 : 				printf( "Error on InternetQueryOption %d\n", GetLastError() );
    91 : 				goto ONERROR_EXIT;
    92 : 			}
    93 : 	
    94 : 			//発行元が不明な証明書や、期限の切れた証明書を受け入れるかどうか。
    95 : 			//テスト環境では必要に応じてフラグをつける
    96 : 		//	dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;		
    97 : 		//	dwFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
    98 : 		//	dwFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
    99 : 	
   100 : 			//HTTPS→HTTPやその逆のリダイレクトを受け入れるかどうか
   101 : 			dwFlags |= SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTP;
   102 : 			dwFlags |= SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTPS;
   103 : 	
   104 : 			fRet = InternetSetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS,
   105 : 										&dwFlags, sizeof(dwFlags));
   106 : 			if(fRet == FALSE){
   107 : 				printf( "Error on InternetSetOption %d\n", GetLastError() );
   108 : 				goto ONERROR_EXIT;
   109 : 			}
   110 : 	
   111 : 	
   112 : 			//ヘッダの追加が必要な場合
   113 : 			if(strcmp(szMethod,"POST")==0){
   114 : 				char sHeader[]  //form-urlencodedのFORMデータ
   115 : 					= "Content-Type: application/x-www-form-urlencoded\r\n";
   116 : 				if(!HttpAddRequestHeaders(hRequest,
   117 : 					sHeader,
   118 : 					-1,
   119 : 					HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD))
   120 : 				{
   121 : 					printf( "Error on HttpAddRequestHeaders %d\n",
   122 : 						GetLastError() );
   123 : 					goto ONERROR_EXIT;
   124 : 				}
   125 : 			}
   126 : 	
   127 : 			int iPostLen = strlen(szPostData);
   128 : 	
   129 : 			memset(&inetbuf, 0, sizeof(INTERNET_BUFFERS));
   130 : 			inetbuf.dwStructSize = sizeof(INTERNET_BUFFERS);
   131 : 			inetbuf.dwBufferTotal = iPostLen;
   132 : 	
   133 : 	
   134 : 			if (HttpSendRequestEx(hRequest, &inetbuf, NULL, 0, 0) == FALSE){
   135 : 				printf( "Error on HttpSendRequestEx %d\n", GetLastError() );
   136 : 				goto ONERROR_EXIT;
   137 : 			}
   138 : 	
   139 : 			//POSTデータを書き込む
   140 : 			if(iPostLen){
   141 : 				if (InternetWriteFile(hRequest, 
   142 : 					szPostData,
   143 : 					strlen(szPostData),
   144 : 					&dwSize) == FALSE)
   145 : 				{
   146 : 					printf( "Error on InternetWriteFile %d\n", GetLastError() );
   147 : 					goto ONERROR_EXIT;
   148 : 				}
   149 : 			}
   150 : 			
   151 : 			//リクエストを送信
   152 : 			if (HttpEndRequest(hRequest, NULL, 0, 0) == FALSE){
   153 : 				printf( "Error on HttpEndRequest %d\n", GetLastError() );
   154 : 				goto ONERROR_EXIT;
   155 : 			}
   156 : 	
   157 : 			//HTTPのステータスコードを受け取る
   158 : 			//HTTP_QUERY_STATUS_TEXTで文字列も受け取れる
   159 : 			if (HttpQueryInfo(
   160 : 						hRequest,
   161 : 						HTTP_QUERY_STATUS_CODE,
   162 : 						szBuf, &dwSize, 0))
   163 : 			{
   164 : 				iStatusCode = atoi(szBuf);	//HTTPステータスコード
   165 : 			}
   166 : 	
   167 : 			//ここから本文の受信処理
   168 : 			HGLOBAL hRecvBuffer 
   169 : 				= GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,WWWGETREADBUFSIZE+1);
   170 : 			DWORD dwReadSize = WWWGETREADBUFSIZE;
   171 : 	
   172 : 			char *lpRecvPoint = 0;
   173 : 			dwSize = WWWGETREADBUFSIZE;
   174 : 			for (;;){
   175 : 				char* lpRecvBuffer = (char*)GlobalLock(hRecvBuffer);
   176 : 				if (InternetReadFile(
   177 : 					hRequest,
   178 : 					lpRecvBuffer + (dwReadSize-dwSize),
   179 : 					WWWGETREADBUFSIZE,
   180 : 					&dwSize) == FALSE)
   181 : 				{
   182 : 					break;
   183 : 				}
   184 : 				GlobalUnlock(hRecvBuffer);
   185 : 				if (dwSize <= 0){
   186 : 					break;
   187 : 				}
   188 : 				dwReadSize+=dwSize;
   189 : 				if(!(hRecvBuffer 
   190 : 					= GlobalReAlloc(hRecvBuffer,dwReadSize+1,GMEM_ZEROINIT))){
   191 : 					goto ONERROR_EXIT;
   192 : 				}
   193 : 			}
   194 : 			//使ったハンドルを閉じる
   195 : 			InternetCloseHandle(hRequest);
   196 : 			InternetCloseHandle(hConnect);
   197 : 			InternetCloseHandle(hSession);
   198 : 			*piStatusCode = iStatusCode;
   199 : 			return hRecvBuffer;
   200 : 		}
   201 : 	ONERROR_EXIT://エラー処理
   202 : 	    if(hRequest)InternetCloseHandle(hRequest);
   203 : 	    if(hConnect)InternetCloseHandle(hConnect);
   204 : 	    if(hSession)InternetCloseHandle(hSession);
   205 : 		return NULL;
   206 : 	}
   207 : 	
   208 : 	
   209 : 	int main(){
   210 : 		HGLOBAL hRecvBuffer;
   211 : 		int iStatusCode =0;
   212 : 		hRecvBuffer = GetWWWPage(
   213 : 			&iStatusCode,
   214 : 			"hoge.net",
   215 : 			"/post.cgi",
   216 : 			"POST",
   217 : 			"name=hoge&page=mui",
   218 : 			TRUE,0);
   219 : 		if(!hRecvBuffer) return 0;
   220 : 		char* lpBuffer = (char*)GlobalLock(hRecvBuffer);
   221 : 		printf(lpBuffer);
   222 : 		GlobalUnlock(hRecvBuffer);
   223 : 		GlobalFree(hRecvBuffer);
   224 : 		return 0;
   225 : 	}
   226 : 	
   227 : 	
   228 :