Example #1
0
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();
}
Example #2
0
//リクエストを送る
//内部メモリバッファに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;
}