ダウンローダクラス完成
無事にプロクシも突破するダウンローダが完成しました.
#ifndef _DOWNLOADER_ #define _DOWNLOADER_ #include <windows.h> #include <wininet.h> class Downloader { private: //インターネットハンドル HINTERNET hInternet; //コネクションハンドル HINTERNET hConnect; //リクエストハンドル HINTERNET hRequest; //ホスト名 TCHAR host[20]; //プロキシ名 TCHAR proxy[40]; //プロキシユーザ名 TCHAR user[20]; //プロキシパスワード TCHAR passwd[20]; //ユーザ名+パスワードのbase64変換 TCHAR base64[30]; public: //ダウンロードしたファイルサイズ long fSize; public: //デフォルトコンストラクタ Downloader(); //ホスト名指定コンストラクタ Downloader(TCHAR *_host); //デストラクタ ~Downloader(); //直接続 bool DirectOpen(void); //プロキシ経由接続 bool ProxyOpen(TCHAR *config); //ファイルダウンロード int Download(char *data, TCHAR *url); }; #endif
#include "Downloader.h" #include <stdio.h> #include <tchar.h> #pragma comment(lib, "wininet.lib") #pragma warning(disable:4996) //----------------------------------------------------------- //コンストラクタ(未使用) //----------------------------------------------------------- Downloader::Downloader() { } //----------------------------------------------------------- //コンストラクタ //@param : host 接続先ホスト名 //@note host:L"www.google.co.jp" //----------------------------------------------------------- Downloader::Downloader(TCHAR *_host) { _tcsncpy_s(host, _host, 20); } //----------------------------------------------------------- //デストラクタ //----------------------------------------------------------- Downloader::~Downloader() { InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); } //----------------------------------------------------------- //直接続 //@note : 事前にコンストラクタでhostを設定 //----------------------------------------------------------- bool Downloader::DirectOpen() { //インターネットのハンドルの作成 hInternet = InternetOpen(L"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); if (hInternet == NULL) { fprintf(stderr, "Cannot connect to Internet\n"); return false; } //HTTPサーバへ接続 hConnect = InternetConnect(hInternet, host, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 10000); if (hConnect == NULL) { fprintf(stderr, "Cannot connect to Server\n"); InternetCloseHandle(hInternet); return false; } return true; } //----------------------------------------------------------- //プロキシ経由接続 //@param _config : プロキシのコンフィグファイル //@note : _configの書式は_fgettsの順番に1行に1つ記述 //----------------------------------------------------------- bool Downloader::ProxyOpen(TCHAR *_config) { FILE *fp; //PROXYとUSER:PASSの読み込み fp = _tfopen(_config, L"r"); if (fp == NULL) return false; //proxy.doshisha.ac.jp:8080 _fgetts(proxy, 40, fp); //bth0103 _fgetts(user, 20, fp); //パスワード _fgetts(passwd, 20, fp); //base64 _fgetts(base64, 30, fp); fclose(fp); //インターネットのハンドルの作成 hInternet = InternetOpen(L"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)", CERN_PROXY_INTERNET_ACCESS, proxy, NULL, 0); if (hInternet == NULL) { fprintf(stderr, "Cannot connect to Internet\n"); return false; } //HTTPサーバへ接続 hConnect = InternetConnect(hInternet, host, INTERNET_DEFAULT_HTTP_PORT, L"", L"", INTERNET_SERVICE_HTTP, 0, 0); if (hConnect == NULL) { fprintf(stderr, "Cannot connect to Server\n"); InternetCloseHandle(hInternet); return false; } BOOL bResult; //プロキシユーザ設定 bResult = InternetSetOption(hConnect, INTERNET_OPTION_PROXY_USERNAME, user, lstrlen(user)); if (bResult == FALSE) { fprintf(stderr, "Cannot set Option\n"); InternetCloseHandle(hInternet); return false; } bResult = InternetSetOption(hConnect, INTERNET_OPTION_PROXY_PASSWORD, passwd, lstrlen(passwd)); if (bResult == FALSE) { fprintf(stderr, "Cannot set Option\n"); InternetCloseHandle(hInternet); return false; } return true; } //----------------------------------------------------------- //ダウンロード //@param data : 受信データのバッファへのポインタ //@param url : 接続先URL //@note url : L"/images/srpr/nav_logo27.png" (ホスト名は含まない) //----------------------------------------------------------- int Downloader::Download(char *data, TCHAR *url) { fSize = 0; char szBuf[1025]; unsigned long dwSize = 1024;//, dwCode; if (hConnect == NULL) return 0; //HTTPリクエストの作成 hRequest = HttpOpenRequest(hConnect, L"GET", url, HTTP_VERSION, L"", NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0); if (hRequest == NULL) { fprintf(stderr, "Request Create Failed\n"); InternetCloseHandle(hInternet); InternetCloseHandle(hConnect); return false; } TCHAR buf[60] = L"Proxy-Authorization: Basic "; _tcscat_s(buf, base64); //プロキシのリクエストヘッダを付加する if (HttpAddRequestHeaders(hRequest, buf, -1, HTTP_ADDREQ_FLAG_ADD) == FALSE) { fprintf(stderr, "Request Create Failed\n"); InternetCloseHandle(hInternet); InternetCloseHandle(hConnect); return false; } //HTTPリクエストを送信する if (HttpSendRequest(hRequest, NULL, 0, NULL, 0) == FALSE) { fprintf(stderr, "Request Send Failed\n"); InternetCloseHandle(hInternet); InternetCloseHandle(hConnect); InternetCloseHandle(hRequest); return false; } ////HTTPの情報を取得する //dwSize = sizeof(DWORD); //if (HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL) == FALSE) { // fprintf(stderr, "Get Infomation Failed\n"); // InternetCloseHandle(hInternet); // InternetCloseHandle(hConnect); // InternetCloseHandle(hRequest); // return false; //} ////結果処理 //if (dwCode == HTTP_STATUS_DENIED || dwCode == HTTP_STATUS_PROXY_AUTH_REQ) { // fprintf(stderr, "Status Bad\n"); // InternetCloseHandle(hInternet); // InternetCloseHandle(hConnect); // InternetCloseHandle(hRequest); // return false; //} //データ受信 while (1) { dwSize = 1024; if (InternetReadFile(hRequest, szBuf, dwSize, &dwSize) == FALSE) break; if (dwSize <= 0) break; szBuf[dwSize] = '\0'; memcpy(data+fSize, szBuf, dwSize); fSize += dwSize; } InternetCloseHandle(hRequest); return fSize; }