CWinHTTPUtil::~CWinHTTPUtil(void) { CloseSession(); ClearUpList(); for( size_t i=0; i<this->dlBuffList.size(); i++ ) { SAFE_DELETE(this->dlBuffList[i]); } this->dlBuffList.clear(); if( this->upStopEvent != NULL ) { CloseHandle(this->upStopEvent); this->upStopEvent = NULL; } if( this->writeCompEvent != NULL ) { CloseHandle(this->writeCompEvent); this->writeCompEvent = NULL; } if( this->responseCompEvent != NULL ) { CloseHandle(this->responseCompEvent); this->responseCompEvent = NULL; } CoUninitialize(); }
//リクエストを送る //内部メモリバッファにDLする場合はファイル容量に要注意 //戻り値:エラーコード DWORD CWinHTTPUtil::SendRequest( LPCWSTR url, //[IN] アクセスするURL NW_VERB_MODE verbMode, //[IN] VERBの種類 LPCWSTR addHttpHeader, //[IN] Httpヘッダに追加するものあるなら指定 LPCWSTR saveFilePath, //[IN] DLファイル名、NULL時は内部メモリバッファにDL UPLOAD_DATA_LIST* upList //[IN] サーバーに送信するデータ(PUT or POST) ) { if( url == NULL ){ return ERR_INVALID_ARG; } if( this->session == NULL ){ return ERR_NW_NO_SESSION; } //リクエストクローズ if( this->request != NULL ){ WinHttpSetStatusCallback( this->request, NULL, NULL, NULL ); WinHttpCloseHandle(this->request); this->request = NULL; } ClearUpList(); for( size_t i=0; i<this->dlBuffList.size(); i++ ){ SAFE_DELETE(this->dlBuffList[i]); } this->dlBuffList.clear(); //URLの分解 URL_COMPONENTS stURL; ZeroMemory(&stURL, sizeof(URL_COMPONENTS)); stURL.dwStructSize = sizeof(URL_COMPONENTS); stURL.dwSchemeLength = -1; stURL.dwHostNameLength = -1; stURL.dwUrlPathLength = -1; stURL.dwExtraInfoLength = -1; if( WinHttpCrackUrl( url, (DWORD)wcslen(url), 0, &stURL) == NULL ){ return ERR_FALSE; } if( stURL.dwHostNameLength <= 0 ){ return ERR_FALSE; } wstring host = L""; host.insert(0,stURL.lpszHostName, stURL.dwHostNameLength ); host += L"\0"; if( CompareNoCase(host, stURL.lpszHostName) != 0 || this->lastPort != stURL.nPort){ //前回と違うコネクションなのでやりなおし if( this->connect != NULL ){ WinHttpCloseHandle(this->connect); this->connect = NULL; } } //コネクションオープン if( this->connect == NULL ){ this->connect = WinHttpConnect( this->session, host.c_str(), stURL.nPort, 0 ); if( this->connect == NULL ){ return ERR_NW_OPEN_CONNECT; } } //Verbの設定 wstring verb = L"GET"; if( verbMode == NW_VERB_GET ){ verb = L"GET"; }else if( verbMode == NW_VERB_POST ){ verb = L"POST"; }else if( verbMode == NW_VERB_PUT ){ verb = L"PUT"; } wstring sendUrl = L""; sendUrl.insert(0, stURL.lpszUrlPath, stURL.dwUrlPathLength+stURL.dwExtraInfoLength); sendUrl += L"\0"; //リクエストオープン if( stURL.nPort == INTERNET_DEFAULT_HTTPS_PORT ){ this->request = WinHttpOpenRequest( this->connect, verb.c_str(), sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); }else{ this->request = WinHttpOpenRequest( this->connect, verb.c_str(), sendUrl.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0 ); } if( this->request == NULL ){ return ERR_NW_OPEN_REQUEST; } if( this->useProxy == TRUE ){ //ProxyのIDとパスワードがあったらセット if( this->proxyID.size() > 0 || this->proxyPWD.size() > 0 ){ if( WinHttpSetCredentials( this->request, WINHTTP_AUTH_TARGET_PROXY, WINHTTP_AUTH_SCHEME_BASIC, this->proxyID.c_str(), this->proxyPWD.c_str(), NULL ) == FALSE ){ return ERR_NW_PROXY_LOGIN; } } } //HTTPヘッダを設定 if( addHttpHeader != NULL ){ WinHttpAddRequestHeaders( this->request, addHttpHeader, -1, WINHTTP_ADDREQ_FLAG_ADD ); } //コールバック設定 WinHttpSetStatusCallback(this->request, StatusCallback, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, NULL ); //アップロードデータのコピー this->totalUpSize = 0; if( upList != NULL ){ for( DWORD i=0; i<upList->listCount; i++ ){ UPLOAD_DATA* item = new UPLOAD_DATA; item->filePathFlag = upList->list[i].filePathFlag; item->buffSize = upList->list[i].buffSize; if( item->buffSize > 0 ){ item->buff = new BYTE[item->buffSize]; memcpy(item->buff, upList->list[i].buff, item->buffSize); } upDataList.push_back(item); if( item->filePathFlag == TRUE ){ HANDLE file = CreateFileW( (WCHAR*)item->buff, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( file == INVALID_HANDLE_VALUE ){ //ファイルにアクセスできないのでエラー return ERR_NW_OPEN_FILE; } DWORD HSize=0; DWORD LSize=0; LSize = GetFileSize(file, &HSize); CloseHandle(file); if( HSize > 0 ){ //DWORD以上は未サポート return ERR_SIZE; } this->totalUpSize += LSize; }else{ this->totalUpSize += item->buffSize; } } } this->lastHost = host; this->lastPort = stURL.nPort; if( saveFilePath != NULL ){ this->saveFilePath = saveFilePath; }else{ this->saveFilePath = L""; } ResetEvent(this->upStopEvent); ResetEvent(this->responseCompEvent); this->errEndCode = NO_ERR; if( WinHttpSendRequest( this->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, totalUpSize, (DWORD_PTR)this) == FALSE ){ return ERR_NW_SEND_REQUEST; } if( this->asyncMode == FALSE ){ //同期なので完了するまで待つ WaitForSingleObject(this->responseCompEvent, INFINITE); return this->errEndCode; } return NO_ERR; }