Click here to Skip to main content
15,886,026 members
Articles / Desktop Programming / MFC

CHttpClient - A Helper Class Using WinInet

Rate me:
Please Sign up or sign in to vote.
4.96/5 (59 votes)
10 Aug 20073 min read 485.7K   24.9K   163  
A C++ class which helps you to interact with a HTTP web server.
/*!
 * \file	HttpClient.cpp
 * \brief	An implementation of the HttpClient component.
 * \author	Jo Hyeong-ryeol
 * \since	2004.10.17
 * \version	$LastChangedRevision: 101 $
 *			$LastChangedDate: 2006-02-04 01:28:18 +0900 (토, 04 2 2006) $
 * 
 * This file contains an implementation of the HttpClient component.
 * \n\n
 * Copyright &copy; 2006 by <a href="mailto:hyeongryeol@gmail.com">Jo Hyeong-ryeol</a>\n
 * Permission to copy, use, modify, sell and distribute this software is
 * granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied warranty,
 * and with no claim as to its suitability for any purpose.
 */
#include "stdafx.h"
#include "HttpClient.h"

#pragma warning (disable: 4996)	// avoids 'This function or variable may be unsafe' message


// CHttpClient

STDMETHODIMP CHttpClient::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IDispatch,
		&IID_IHttpClient2,
		&IID_IDispHttpClient2,
	};

	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

// Checks whether the post is active
HRESULT CHttpClient::_CheckActivePost (PCWSTR szTargetName)
	throw ()
{
	Ryeol::CHttpPostStatW		objPostStat ;
	m_objHttpClient.Query (objPostStat) ;
	ATLASSERT ( !objPostStat.IsActive () ) ;
	if ( objPostStat.IsActive () ) {
		WCHAR		szTemp[128] ;
		::swprintf (szTemp, L"It is not allowed to call %s if the POST context is active.", szTargetName) ;
		ErrorHttpClient (szTemp) ;
		return E_UNEXPECTED ;
	}
	return S_OK ;
}

// Copies a string to a buffer
HRESULT CHttpClient::_CopyStringToBuff (PWSTR szBuff, DWORD cchBuff, PCWSTR szSrc)
	throw ()
{
	if ( STRSAFE_E_INVALID_PARAMETER
			== ::StringCchCopyW (szBuff, cchBuff, szSrc ? szSrc : L"") ) {
		ErrorHttpClient (L"The ::StringCchCopyW returns STRSAFE_E_INVALID_PARAMETER") ;
		return E_FAIL ;
	}
	return S_OK ;
}

// Creates a new SysString based on pbstrDest.
// bSetNull : If thie argument is TRUE and the szSrc is NULL, *pszDest points to NULL.
//				otherwise *pszDest points empty string. (L"")
HRESULT CHttpClient::_DupStringAsSysStr (BSTR * pbstrDest, PCWSTR szSrc, BOOL bSetNull)
	throw ()
{
	ATLASSERT ( pbstrDest != NULL ) ;

	if ( szSrc || !bSetNull ) {
		*pbstrDest = ::SysAllocString (szSrc ? szSrc : L"") ;
		if ( *pbstrDest == NULL ) {
			ErrorHttpClient (L"Out of memory") ;
			return E_OUTOFMEMORY ;
		}
	}
	else
		*pbstrDest = NULL ;

	return S_OK ;
}


// This method creates a COM interface from a CHttpResponseW object.
// The ownership of the pobjHttpRes is transfered.
// So after calling this method, pobjHttpRes can not be used.
template<typename QueriedInterface>
HRESULT CHttpClient::_GetIHttpResponse2 (Ryeol::CHttpResponseW * pobjHttpRes, QueriedInterface ** ppQueriedInterface)
	throw ()
{
	ATLASSERT ( pobjHttpRes != NULL ) ;
	ATLASSERT ( ppQueriedInterface != NULL ) ;
	*ppQueriedInterface = NULL ;

	CComPtr<IHttpResponseInternal2>	spHttpRes ;
	HRESULT							hResult ;

	try {
		hResult = spHttpRes.CoCreateInstance (
					__uuidof (HttpResponse2)
					, NULL
					, CLSCTX_INPROC_SERVER) ;

		if ( FAILED (hResult) ) {
			ErrorHttpClient (
				L"Failed to create a HttpResponse object"
				, Ryeol::HTTPCLIENT_ERR_NOT_SPECIFIED
				, hResult
			) ;
			throw hResult ;
		}

		if ( FAILED (hResult = spHttpRes->SetInternalObject (pobjHttpRes)) ) {
			ErrorHttpClient (
				L"Failed to set a Ryeol::CHttpResponseW object"
				, Ryeol::HTTPCLIENT_ERR_NOT_SPECIFIED
				, hResult
			) ;
			throw hResult ;
		}
		pobjHttpRes = NULL ;

		if ( FAILED (hResult = spHttpRes.QueryInterface (ppQueriedInterface)) ) {
			ErrorHttpClient (
				L"Failed to set a IHttpResponse2 or IDispHttpResponse2 interface"
				, Ryeol::HTTPCLIENT_ERR_NOT_SPECIFIED
				, hResult
			) ;
			throw hResult ;
		}

	} catch (HRESULT & hRes) {
		delete pobjHttpRes ;
		return hRes ;
	}
	return S_OK ;
}




#define IMPLEMENT_HTTPCLIENT_STRINGPROPERTY_READONLY(PropertyName)													\
																													\
STDMETHODIMP CHttpClient::Get##PropertyName##Len (DWORD * pdwLen)													\
{																													\
	ATLASSERT ( pdwLen != NULL ) ;																					\
	if ( pdwLen == NULL ) {																							\
		ErrorHttpClient (L"The argument(pdwLen) can not be NULL") ;													\
		return E_INVALIDARG ;																						\
	}																												\
																													\
	try {																											\
		*pdwLen = static_cast<DWORD> (::wcslen (m_objHttpClient.Get##PropertyName ())) ;							\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
																													\
	return S_OK ;																									\
}																													\
																													\
STDMETHODIMP CHttpClient::Get##PropertyName##IntoBuff (OLECHAR * szBuff, DWORD cchBuff)								\
{																													\
	ATLASSERT ( szBuff != NULL && cchBuff != 0 ) ;																	\
	if ( szBuff == NULL ) {																							\
		ErrorHttpClient (L"The argument(szBuff) can not be NULL") ;													\
		return E_INVALIDARG ;																						\
	}																												\
	if ( cchBuff == 0 ) {																							\
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;												\
		return E_INVALIDARG ;																						\
	}																												\
																													\
	if ( cchBuff == 1 ) {																							\
		szBuff[0] = '\0' ;																							\
		return S_OK ;																								\
	}																												\
	HRESULT			hResult ;																						\
	try {																											\
		hResult = _CopyStringToBuff (szBuff, cchBuff, m_objHttpClient.Get##PropertyName ()) ;						\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
	return hResult ;																								\
}																													\
																													\
STDMETHODIMP CHttpClient::Get##PropertyName (BSTR * pbstr##PropertyName)											\
{																													\
	ATLASSERT ( pbstr##PropertyName != NULL ) ;																		\
	if ( pbstr##PropertyName == NULL ) {																			\
		ErrorHttpClient (L"The argument(pbstr##PropertyName) can not be NULL") ;									\
		return E_INVALIDARG ;																						\
	}																												\
	HRESULT			hResult ;																						\
	try {																											\
		hResult = _DupStringAsSysStr (pbstr##PropertyName, m_objHttpClient.Get##PropertyName (), TRUE) ;			\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
	return hResult ;																								\
}																													\
																													\
STDMETHODIMP CHttpClient::get_##PropertyName (BSTR * pbstr##PropertyName)											\
{																													\
	return Get##PropertyName (pbstr##PropertyName) ;																\
}


#define IMPLEMENT_HTTPCLIENT_STRINGPROPERTY(PropertyName)															\
																													\
IMPLEMENT_HTTPCLIENT_STRINGPROPERTY_READONLY (PropertyName)															\
																													\
STDMETHODIMP CHttpClient::Set##PropertyName (PCWSTR sz##PropertyName)												\
{																													\
	try {																											\
		m_objHttpClient.Set##PropertyName (sz##PropertyName) ;														\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
	return S_OK ;																									\
}																													\
																													\
STDMETHODIMP CHttpClient::put_##PropertyName (const BSTR bstr##PropertyName)										\
{																													\
	return Set##PropertyName (static_cast<PCWSTR> (bstr##PropertyName)) ;											\
}


#define IMPLEMENT_HTTPCLIENT_VALUEPROPERTY(ValueType, PropertyName, bCheckPostContext)								\
																													\
STDMETHODIMP CHttpClient::Get##PropertyName (ValueType * p##PropertyName)											\
{																													\
	ATLASSERT ( p##PropertyName != NULL ) ;																			\
	if ( p##PropertyName == NULL ) {																				\
		ErrorHttpClient (L"The argument(p##PropertyName) can not be NULL") ;										\
		return E_INVALIDARG ;																						\
	}																												\
																													\
	try {																											\
		*p##PropertyName = m_objHttpClient.Get##PropertyName () ;													\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
																													\
	return S_OK ;																									\
}																													\
																													\
STDMETHODIMP CHttpClient::Set##PropertyName (ValueType PropertyName)												\
{																													\
	if ( bCheckPostContext ) {																						\
		HRESULT		hResult ;																						\
		if ( FAILED (hResult = _CheckActivePost (L"Set PropertyName")) )											\
			return hResult ;																						\
	}																												\
																													\
	try {																											\
		m_objHttpClient.Set##PropertyName (PropertyName) ;															\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
	return S_OK ;																									\
}																													\
																													\
STDMETHODIMP CHttpClient::get_##PropertyName (ValueType * p##PropertyName)											\
{																													\
	return Get##PropertyName (p##PropertyName) ;																	\
}																													\
																													\
STDMETHODIMP CHttpClient::put_##PropertyName (ValueType PropertyName)												\
{																													\
	return Set##PropertyName (PropertyName) ;																		\
}



IMPLEMENT_HTTPCLIENT_VALUEPROPERTY (BOOL, StrictFileCheck, FALSE)
IMPLEMENT_HTTPCLIENT_VALUEPROPERTY (BOOL, UseUtf8, TRUE)
IMPLEMENT_HTTPCLIENT_VALUEPROPERTY (UINT, AnsiCodePage, TRUE)




STDMETHODIMP CHttpClient::ClearHeader (BOOL * pbCleared)
{
	ATLASSERT ( pbCleared != NULL ) ;
	if ( pbCleared == NULL ) {
		ErrorHttpClient (L"The argument(pbCleared) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pbCleared = m_objHttpClient.ClearHeader () ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveHeaderAt (DWORD nIdx, BOOL * pbRemoved)
{
	ATLASSERT ( pbRemoved != NULL ) ;
	if ( pbRemoved == NULL ) {
		ErrorHttpClient (L"The argument(pbRemoved) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pbRemoved = m_objHttpClient.RemoveHeader (nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveHeader (PCWSTR szName, DWORD nIdx, BOOL * pbRemoved)
{
	ATLASSERT ( szName != NULL && pbRemoved != NULL ) ;
	if ( szName == NULL || pbRemoved == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbRemoved) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pbRemoved = m_objHttpClient.RemoveHeader (szName, nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveHeader (const BSTR bstrName, DWORD nIdx, BOOL * pbRemoved)
{
	return RemoveHeader (static_cast<PCWSTR> (bstrName), nIdx, pbRemoved) ;
}

STDMETHODIMP CHttpClient::RemoveAllHeader (PCWSTR szName, BOOL * pbRemoved)
{
	ATLASSERT ( szName != NULL && pbRemoved != NULL ) ;
	if ( szName == NULL || pbRemoved == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbRemoved) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pbRemoved = m_objHttpClient.RemoveAllHeader (szName) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveAllHeader (const BSTR bstrName, BOOL * pbRemoved)
{
	return RemoveAllHeader (static_cast<PCWSTR> (bstrName), pbRemoved) ;
}

STDMETHODIMP CHttpClient::AddHeader (PCWSTR szName, PCWSTR szValue)
{
	ATLASSERT ( szName != NULL && szValue != NULL ) ;
	if ( szName == NULL || szValue == NULL ) {
		ErrorHttpClient (L"The argument(szName or szValue) can not be NULL") ;
		return E_INVALIDARG ;
	}
	ATLASSERT ( szName[0] != '\0' && szValue[0] != '\0' ) ;
	if ( szName[0] == '\0' || szValue[0] == '\0' ) {
		ErrorHttpClient (L"The argument(szName or szValue) can not be an empty string") ;
		return E_INVALIDARG ;
	}

	try {
		m_objHttpClient.AddHeader (szName, szValue) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::AddHeader (const BSTR bstrName, const BSTR bstrValue)
{
	return AddHeader (static_cast<PCWSTR> (bstrName), static_cast<PCWSTR> (bstrValue)) ;
}

STDMETHODIMP CHttpClient::SetHeader (PCWSTR szName, PCWSTR szValue, DWORD nIdx)
{
	ATLASSERT ( szName != NULL && szValue != NULL ) ;
	if ( szName == NULL || szValue == NULL ) {
		ErrorHttpClient (L"The argument(szName or szValue) can not be NULL") ;
		return E_INVALIDARG ;
	}
	ATLASSERT ( szName[0] != '\0' && szValue[0] != '\0' ) ;
	if ( szName[0] == '\0' || szValue[0] == '\0' ) {
		ErrorHttpClient (L"The argument(szName or szValue) can not be an empty string") ;
		return E_INVALIDARG ;
	}

	try {
		m_objHttpClient.SetHeader (szName, szValue, nIdx) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::SetHeader (const BSTR bstrName, const BSTR bstrValue, DWORD nIdx)
{
	return SetHeader (static_cast<PCWSTR> (bstrName), static_cast<PCWSTR> (bstrValue), nIdx) ;
}


STDMETHODIMP CHttpClient::GetHeaderNameAtLen (DWORD nIdx, DWORD * pdwLen)
{
	ATLASSERT ( pdwLen != NULL ) ;
	if ( pdwLen == NULL ) {
		ErrorHttpClient (L"The argument(pdwLen) can not be NULL") ;
		return E_INVALIDARG ;
	}

	PCWSTR		szHeaderName = m_objHttpClient.GetHeaderName (nIdx) ;
	*pdwLen = szHeaderName ? static_cast<DWORD> (::wcslen (szHeaderName)) : 0 ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetHeaderNameAtIntoBuff (OLECHAR * szBuff, DWORD cchBuff, DWORD nIdx)
{
	ATLASSERT ( szBuff != NULL && cchBuff != 0 ) ;
	if ( szBuff == NULL ) {
		ErrorHttpClient (L"The argument(szBuff) can not be NULL") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 0 ) {
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;
		return E_INVALIDARG ;
	}

	if ( cchBuff == 1 ) {
		szBuff[0] = '\0' ;
		return S_OK ;
	}
	return _CopyStringToBuff (szBuff, cchBuff, m_objHttpClient.GetHeaderName (nIdx)) ;
}

// If the header is not found, NULL is returned.
STDMETHODIMP CHttpClient::GetHeaderNameAt (DWORD nIdx, BSTR * pbstrName)
{
	ATLASSERT ( pbstrName != NULL ) ;
	if ( pbstrName == NULL ) {
		ErrorHttpClient (L"The argument(pbstrName) can not be NULL") ;
		return E_INVALIDARG ;
	}
	return _DupStringAsSysStr (pbstrName, m_objHttpClient.GetHeaderName (nIdx), TRUE) ;
}

STDMETHODIMP CHttpClient::GetHeaderAtLen (DWORD nIdx, DWORD * pdwLen)
{
	ATLASSERT ( pdwLen != NULL ) ;
	if ( pdwLen == NULL ) {
		ErrorHttpClient (L"The argument(pdwLen) can not be NULL") ;
		return E_INVALIDARG ;
	}

	PCWSTR		szHeader = m_objHttpClient.GetHeader (nIdx) ;
	*pdwLen = szHeader ? static_cast<DWORD> (::wcslen (szHeader)) : 0 ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetHeaderAtIntoBuff (OLECHAR * szBuff, DWORD cchBuff, DWORD nIdx)
{
	ATLASSERT ( szBuff != NULL && cchBuff != 0 ) ;
	if ( szBuff == NULL ) {
		ErrorHttpClient (L"The argument(szBuff) can not be NULL") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 0 ) {
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;
		return E_INVALIDARG ;
	}

	if ( cchBuff == 1 ) {
		szBuff[0] = '\0' ;
		return S_OK ;
	}
	return _CopyStringToBuff (szBuff, cchBuff, m_objHttpClient.GetHeader (nIdx)) ;
}

// If the header is not found, NULL is returned.
STDMETHODIMP CHttpClient::GetHeaderAt (DWORD nIdx, BSTR * pbstrHeader)
{
	ATLASSERT ( pbstrHeader != NULL ) ;
	if ( pbstrHeader == NULL ) {
		ErrorHttpClient (L"The argument(pbstrHeader) can not be NULL") ;
		return E_INVALIDARG ;
	}
	return _DupStringAsSysStr (pbstrHeader, m_objHttpClient.GetHeader (nIdx), TRUE) ;
}

STDMETHODIMP CHttpClient::GetHeaderLen (PCWSTR szName, DWORD nIdx, DWORD * pdwLen)
{
	ATLASSERT ( szName != NULL && pdwLen != NULL ) ;
	if ( szName == NULL || pdwLen == NULL ) {
		ErrorHttpClient (L"The argument(szName or pdwLen) can not be NULL") ;
		return E_INVALIDARG ;
	}

	PCWSTR		szHeader = m_objHttpClient.GetHeader (szName, nIdx) ;
	*pdwLen = szHeader ? static_cast<DWORD> (::wcslen (szHeader)) : 0 ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetHeaderLen (const BSTR bstrName, DWORD nIdx, DWORD * pdwLen)
{
	return GetHeaderLen (static_cast<PCWSTR> (bstrName), nIdx, pdwLen) ;
}

STDMETHODIMP CHttpClient::GetHeaderIntoBuff (OLECHAR * szBuff, DWORD cchBuff, PCWSTR szName, DWORD nIdx)
{
	ATLASSERT ( szName != NULL && szBuff != NULL && cchBuff != 0 ) ;
	if ( szName == NULL || szBuff == NULL ) {
		ErrorHttpClient (L"The argument(szName or szBuff) can not be NULL") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 0 ) {
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;
		return E_INVALIDARG ;
	}

	if ( cchBuff == 1 ) {
		szBuff[0] = '\0' ;
		return S_OK ;
	}
	return _CopyStringToBuff (szBuff, cchBuff, m_objHttpClient.GetHeader (szName, nIdx)) ;
}

// If the header is not found, NULL is returned.
STDMETHODIMP CHttpClient::GetHeader (PCWSTR szName, DWORD nIdx, BSTR * pbstrHeader)
{
	ATLASSERT ( szName != NULL && pbstrHeader != NULL ) ;
	if ( szName == NULL || pbstrHeader == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbstrHeader) can not be NULL") ;
		return E_INVALIDARG ;
	}
	return _DupStringAsSysStr (pbstrHeader, m_objHttpClient.GetHeader (szName, nIdx) , TRUE) ;
}

STDMETHODIMP CHttpClient::GetHeader (const BSTR bstrName, DWORD nIdx, BSTR * pbstrHeader)
{
	return GetHeader (static_cast<PCWSTR> (bstrName), nIdx, pbstrHeader) ;
}

STDMETHODIMP CHttpClient::HeaderExists (PCWSTR szName, DWORD nIdx, BOOL * pbExist)
{
	ATLASSERT ( szName != NULL && pbExist != NULL ) ;
	if ( szName == NULL || pbExist == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbExist) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pbExist = m_objHttpClient.HeaderExists (szName, nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::HeaderExists (const BSTR bstrName, DWORD nIdx, BOOL * pbExist)
{
	return HeaderExists (static_cast<PCWSTR> (bstrName), nIdx, pbExist) ;
}

STDMETHODIMP CHttpClient::GetHeaderCount (PCWSTR szName, DWORD * pdwCount)
{
	ATLASSERT ( pdwCount != NULL ) ;
	if ( pdwCount == NULL ) {
		ErrorHttpClient (L"The argument(pdwCount) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pdwCount = m_objHttpClient.GetHeaderCount (szName) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetHeaderCount (const BSTR bstrName, DWORD * pdwCount)
{
	return GetHeaderCount (static_cast<PCWSTR> (bstrName), pdwCount) ;
}

STDMETHODIMP CHttpClient::GetAllHeaderCount (DWORD * pdwCount)
{
	ATLASSERT ( pdwCount != NULL ) ;
	if ( pdwCount == NULL ) {
		ErrorHttpClient (L"The argument(pdwCount) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pdwCount = m_objHttpClient.GetHeaderCount (NULL) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::ClearParam (BOOL * pbCleared)
{
	ATLASSERT ( pbCleared != NULL ) ;
	if ( pbCleared == NULL ) {
		ErrorHttpClient (L"The argument(pbCleared) can not be NULL") ;
		return E_INVALIDARG ;
	}

	HRESULT		hResult ;
	if ( FAILED (hResult = _CheckActivePost (L"ClearParam")) )
		return hResult ;

	*pbCleared = m_objHttpClient.ClearParam () ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveParamAt (DWORD nIdx, BOOL * pbRemoved)
{
	ATLASSERT ( pbRemoved != NULL ) ;
	if ( pbRemoved == NULL ) {
		ErrorHttpClient (L"The argument(pbRemoved) can not be NULL") ;
		return E_INVALIDARG ;
	}

	HRESULT		hResult ;
	if ( FAILED (hResult = _CheckActivePost (L"RemoveParamAt")) )
		return hResult ;

	*pbRemoved = m_objHttpClient.RemoveParam (nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveParam (PCWSTR szName, DWORD nIdx, BOOL * pbRemoved)
{
	ATLASSERT ( szName != NULL && pbRemoved != NULL ) ;
	if ( szName == NULL || pbRemoved == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbRemoved) can not be NULL") ;
		return E_INVALIDARG ;
	}

	HRESULT		hResult ;
	if ( FAILED (hResult = _CheckActivePost (L"RemoveParamW")) )
		return hResult ;

	*pbRemoved = m_objHttpClient.RemoveParam (szName, nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveParam (const BSTR bstrName, DWORD nIdx, BOOL * pbRemoved)
{
	return RemoveParam (static_cast<PCWSTR> (bstrName), nIdx, pbRemoved) ;
}

STDMETHODIMP CHttpClient::RemoveAllParam (PCWSTR szName, BOOL * pbRemoved)
{
	ATLASSERT ( szName != NULL && pbRemoved != NULL ) ;
	if ( szName == NULL || pbRemoved == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbRemoved) can not be NULL") ;
		return E_INVALIDARG ;
	}

	HRESULT		hResult ;
	if ( FAILED (hResult = _CheckActivePost (L"RemoveAllParamW")) )
		return hResult ;

	*pbRemoved = m_objHttpClient.RemoveAllParam (szName) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::RemoveAllParam (const BSTR bstrName, BOOL * pbRemoved)
{
	return RemoveAllParam (static_cast<PCWSTR> (bstrName), pbRemoved) ;
}

STDMETHODIMP CHttpClient::AddParam (PCWSTR szName, PCWSTR szValue, DWORD dwParamAttr)
{
	ATLASSERT ( szName != NULL ) ;
	if ( szName == NULL ) {
		ErrorHttpClient (L"The argument(szName) can not be NULL") ;
		return E_INVALIDARG ;
	}

	HRESULT		hResult ;
	if ( FAILED (hResult = _CheckActivePost (L"AddParamW")) )
		return hResult ;

	try {
		m_objHttpClient.AddParam (szName, szValue, dwParamAttr) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::AddParam (const BSTR bstrName, const BSTR bstrValue, DWORD dwParamAttr)
{
	return AddParam (static_cast<PCWSTR> (bstrName), static_cast<PCWSTR> (bstrValue), dwParamAttr) ;
}

STDMETHODIMP CHttpClient::SetParam (PCWSTR szName, PCWSTR szValue, DWORD dwParamAttr, DWORD nIdx)
{
	ATLASSERT ( szName != NULL ) ;
	if ( szName == NULL ) {
		ErrorHttpClient (L"The argument(szName) can not be NULL") ;
		return E_INVALIDARG ;
	}

	HRESULT		hResult ;
	if ( FAILED (hResult = _CheckActivePost (L"SetParamW")) )
		return hResult ;

	try {
		m_objHttpClient.SetParam (szName, szValue, dwParamAttr, nIdx) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::SetParam (const BSTR bstrName, const BSTR bstrValue, DWORD dwParamAttr, DWORD nIdx)
{
	return SetParam (static_cast<PCWSTR> (bstrName), static_cast<PCWSTR> (bstrValue), dwParamAttr, nIdx) ;
}


STDMETHODIMP CHttpClient::GetParamNameAtLen (DWORD nIdx, DWORD * pdwLen)
{
	ATLASSERT ( pdwLen != NULL ) ;
	if ( pdwLen == NULL ) {
		ErrorHttpClient (L"The argument(pdwLen) can not be NULL") ;
		return E_INVALIDARG ;
	}

	PCWSTR		szParamName = m_objHttpClient.GetParamName (nIdx) ;
	*pdwLen = szParamName ? static_cast<DWORD> (::wcslen (szParamName)) : 0 ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetParamNameAtIntoBuff (OLECHAR * szBuff, DWORD cchBuff, DWORD nIdx)
{
	ATLASSERT ( szBuff != NULL && cchBuff != 0 ) ;
	if ( szBuff == NULL ) {
		ErrorHttpClient (L"The argument(szBuff) can not be NULL") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 0 ) {
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;
		return E_INVALIDARG ;
	}

	if ( cchBuff == 1 ) {
		szBuff[0] = '\0' ;
		return S_OK ;
	}
	return _CopyStringToBuff (szBuff, cchBuff, m_objHttpClient.GetParamName (nIdx)) ;
}

// If the header is not found, NULL is returned.
STDMETHODIMP CHttpClient::GetParamNameAt (DWORD nIdx, BSTR * pbstrName)
{
	ATLASSERT ( pbstrName != NULL ) ;
	if ( pbstrName == NULL ) {
		ErrorHttpClient (L"The argument(pbstrName) can not be NULL") ;
		return E_INVALIDARG ;
	}
	return _DupStringAsSysStr (pbstrName, m_objHttpClient.GetParamName (nIdx), TRUE) ;
}

STDMETHODIMP CHttpClient::GetParamAtLen (DWORD nIdx, DWORD * pdwLen)
{
	ATLASSERT ( pdwLen != NULL ) ;
	if ( pdwLen == NULL ) {
		ErrorHttpClient (L"The argument(pdwLen) can not be NULL") ;
		return E_INVALIDARG ;
	}

	PCWSTR		szParam = m_objHttpClient.GetParam (nIdx) ;
	*pdwLen = szParam ? static_cast<DWORD> (::wcslen (szParam)) : 0 ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetParamAtIntoBuff (OLECHAR * szBuff, DWORD cchBuff, DWORD nIdx)
{
	ATLASSERT ( szBuff != NULL && cchBuff != 0 ) ;
	if ( szBuff == NULL ) {
		ErrorHttpClient (L"The argument(szBuff) can not be NULL") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 0 ) {
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 1 ) {
		szBuff[0] = '\0' ;
		return S_OK ;
	}
	return _CopyStringToBuff (szBuff, cchBuff, m_objHttpClient.GetParam (nIdx)) ;
}

// If the header is not found, NULL is returned.
STDMETHODIMP CHttpClient::GetParamAt (DWORD nIdx, BSTR * pbstrParam)
{
	ATLASSERT ( pbstrParam != NULL ) ;
	if ( pbstrParam == NULL ) {
		ErrorHttpClient (L"The argument(pbstrParam) can not be NULL") ;
		return E_INVALIDARG ;
	}
	return _DupStringAsSysStr (pbstrParam, m_objHttpClient.GetParam (nIdx), TRUE) ;
}

STDMETHODIMP CHttpClient::GetParamLen (PCWSTR szName, DWORD nIdx, DWORD * pdwLen)
{
	ATLASSERT ( szName != NULL && pdwLen != NULL ) ;
	if ( szName == NULL || pdwLen == NULL ) {
		ErrorHttpClient (L"The argument(szName or pdwLen) can not be NULL") ;
		return E_INVALIDARG ;
	}

	PCWSTR		szParam = m_objHttpClient.GetParam (szName, nIdx) ;
	*pdwLen = szParam ? static_cast<DWORD> (::wcslen (szParam)) : 0 ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetParamLen (const BSTR bstrName, DWORD nIdx, DWORD * pdwLen)
{
	return GetParamLen (static_cast<PCWSTR> (bstrName), nIdx, pdwLen) ;
}

STDMETHODIMP CHttpClient::GetParamIntoBuff (OLECHAR * szBuff, DWORD cchBuff, PCWSTR szName, DWORD nIdx)
{
	ATLASSERT ( szName != NULL && szBuff != NULL && cchBuff != 0 ) ;
	if ( szName == NULL || szBuff == NULL ) {
		ErrorHttpClient (L"The argument(szName or szBuff) can not be NULL") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 0 ) {
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;
		return E_INVALIDARG ;
	}

	if ( cchBuff == 1 ) {
		szBuff[0] = '\0' ;
		return S_OK ;
	}
	return _CopyStringToBuff (szBuff, cchBuff, m_objHttpClient.GetParam (szName, nIdx)) ;
}

// If the header is not found, NULL is returned.
STDMETHODIMP CHttpClient::GetParam (PCWSTR szName, DWORD nIdx, BSTR * pbstrParam)
{
	ATLASSERT ( szName != NULL && pbstrParam != NULL ) ;
	if ( szName == NULL || pbstrParam == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbstrParam) can not be NULL") ;
		return E_INVALIDARG ;
	}
	return _DupStringAsSysStr (pbstrParam, m_objHttpClient.GetParam (szName, nIdx), TRUE) ;
}

STDMETHODIMP CHttpClient::GetParam (const BSTR bstrName, DWORD nIdx, BSTR * pbstrParam)
{
	return GetParam (static_cast<PCWSTR> (bstrName), nIdx, pbstrParam) ;
}

STDMETHODIMP CHttpClient::GetParamAttrAt (DWORD nIdx, DWORD * pdwAttr)
{
	ATLASSERT ( pdwAttr != NULL ) ;
	if ( pdwAttr == NULL ) {
		ErrorHttpClient (L"The argument(pdwAttr) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pdwAttr = m_objHttpClient.GetParamAttr (nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetParamAttr (PCWSTR szName, DWORD nIdx, DWORD * pdwAttr)
{
	ATLASSERT ( szName != NULL && pdwAttr != NULL ) ;
	if ( szName == NULL || pdwAttr == NULL ) {
		ErrorHttpClient (L"The argument(szName or pdwAttr) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pdwAttr = m_objHttpClient.GetParamAttr (szName, nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetParamAttr (const BSTR bstrName, DWORD nIdx, DWORD * pdwAttr)
{
	return GetParamAttr (static_cast<PCWSTR> (bstrName), nIdx, pdwAttr) ;
}

STDMETHODIMP CHttpClient::ParamExists (PCWSTR szName, DWORD nIdx, BOOL * pbExist)
{
	ATLASSERT ( szName != NULL && pbExist != NULL ) ;
	if ( szName == NULL || pbExist == NULL ) {
		ErrorHttpClient (L"The argument(szName or pbExist) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pbExist = m_objHttpClient.ParamExists (szName, nIdx) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::ParamExists (const BSTR bstrName, DWORD nIdx, BOOL * pbExist)
{
	return ParamExists (static_cast<PCWSTR> (bstrName), nIdx, pbExist) ;
}

STDMETHODIMP CHttpClient::GetParamCount (PCWSTR szName, DWORD * pdwCount)
{
	ATLASSERT ( pdwCount != NULL ) ;
	if ( pdwCount == NULL ) {
		ErrorHttpClient (L"The argument(pdwCount) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pdwCount = m_objHttpClient.GetHeaderCount (szName) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::GetParamCount (const BSTR bstrName, DWORD * pdwCount)
{
	return GetParamCount (static_cast<PCWSTR> (bstrName), pdwCount) ;
}

STDMETHODIMP CHttpClient::GetAllParamCount (DWORD * pdwCount)
{
	ATLASSERT ( pdwCount != NULL ) ;
	if ( pdwCount == NULL ) {
		ErrorHttpClient (L"The argument(pdwCount) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pdwCount = m_objHttpClient.GetParamCount (NULL) ;
	return S_OK ;
}

STDMETHODIMP CHttpClient::SetInternet (PCWSTR szUserAgent, DWORD dwAccessType, PCWSTR szProxyName, PCWSTR szProxyBypass, DWORD dwFlags)
{
	try {
		m_objHttpClient.SetInternet (szUserAgent, dwAccessType, szProxyName, szProxyBypass, dwFlags) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::SetInternet (const BSTR bstrUserAgent, DWORD dwAccessType, const BSTR bstrProxyName, const BSTR bstrProxyBypass, DWORD dwFlags)
{
	return SetInternet (static_cast<PCWSTR> (bstrUserAgent), dwAccessType, static_cast<PCWSTR> (bstrProxyName), static_cast<PCWSTR> (bstrProxyBypass), dwFlags) ;
}






IMPLEMENT_HTTPCLIENT_STRINGPROPERTY (InternetUserAgent)
IMPLEMENT_HTTPCLIENT_VALUEPROPERTY (DWORD, InternetAccessType, FALSE)
IMPLEMENT_HTTPCLIENT_STRINGPROPERTY (InternetProxyName)
IMPLEMENT_HTTPCLIENT_STRINGPROPERTY (InternetProxyBypass)
IMPLEMENT_HTTPCLIENT_VALUEPROPERTY (DWORD, InternetFlags, FALSE)






STDMETHODIMP CHttpClient::MakeGetUrlLen (PCWSTR szUrl, DWORD * pdwLen)
{
	ATLASSERT ( pdwLen != NULL ) ;
	if ( pdwLen == NULL ) {
		ErrorHttpClient (L"The argument(pdwLen) can not be NULL") ;
		return E_INVALIDARG ;
	}

	try {
		*pdwLen = m_objHttpClient.MakeGetUrlLen (szUrl) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::MakeGetUrlLen (const BSTR bstrUrl, DWORD * pdwLen)
{
	return MakeGetUrlLen (static_cast<PCWSTR> (bstrUrl), pdwLen) ;
}

STDMETHODIMP CHttpClient::MakeGetUrlIntoBuff (OLECHAR * szBuff, DWORD cchBuff, PCWSTR szUrl)
{
	ATLASSERT ( szBuff != NULL && cchBuff != 0 ) ;
	if ( szBuff == NULL ) {
		ErrorHttpClient (L"The argument(szBuff) can not be NULL") ;
		return E_INVALIDARG ;
	}
	if ( cchBuff == 0 ) {
		ErrorHttpClient (L"The argument(cchBuff) can not be zero") ;
		return E_INVALIDARG ;
	}

	if ( cchBuff == 1 ) {
		szBuff[0] = '\0' ;
		return S_OK ;
	}

	{
		HRESULT		hResult ;
		DWORD		cchRequired ;

		if ( FAILED (hResult = MakeGetUrlLen (szUrl, &cchRequired)) )
			return hResult ;

		if ( cchBuff <= cchRequired ) {
			ErrorHttpClient (L"The buffer size is not sufficient") ;
			return E_INVALIDARG ;
		}
	}

	try {
		m_objHttpClient.MakeGetUrl (szBuff, szUrl) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::MakeGetUrl (PCWSTR szUrl, BSTR * pbstrGetUrl)
{
	ATLASSERT ( pbstrGetUrl != NULL ) ;
	if ( pbstrGetUrl == NULL ) {
		ErrorHttpClient (L"The argument(pbstrGetUrl) can not be NULL") ;
		return E_INVALIDARG ;
	}
	*pbstrGetUrl = NULL ;

	HRESULT		hResult ;
	DWORD		cchRequired ;

	if ( FAILED (hResult = MakeGetUrlLen (szUrl, &cchRequired)) )
		return hResult ;

	*pbstrGetUrl = ::SysAllocStringLen (NULL, cchRequired) ;
	if ( *pbstrGetUrl == NULL ) {
		ErrorHttpClient (L"Out of memory") ;
		return E_OUTOFMEMORY ;
	}

	if ( FAILED (hResult = MakeGetUrlIntoBuff (*pbstrGetUrl, cchRequired + 1, szUrl)) ) {
		::SysFreeString (*pbstrGetUrl) ;
		*pbstrGetUrl = NULL ;
		return hResult ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::MakeGetUrl (const BSTR bstrUrl, BSTR * pbstrGetUrl)
{
	return MakeGetUrl (static_cast<PCWSTR> (bstrUrl), pbstrGetUrl) ;
}


STDMETHODIMP CHttpClient::SetProxyAccount (PCWSTR szUserName, PCWSTR szPassword)
{
	ATLASSERT ( !(szUserName && szUserName[0] == '\0') ) ;
	ATLASSERT ( !(szPassword == NULL || szPassword[0] == '\0') ) ;

	if ( szUserName != NULL && szUserName[0] == '\0' ) {
		ErrorHttpClient (L"The argument(szUserName) can not be an empty string") ;
		return E_INVALIDARG ;
	}
	if ( szPassword == NULL || szPassword[0] == '\0' ) {
		ErrorHttpClient (L"The argument(szPassword) can not be NULL or an empty string") ;
		return E_INVALIDARG ;
	}

	try {
		m_objHttpClient.SetProxyAccount (szUserName, szPassword) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::SetProxyAccount (const BSTR bstrUserName, const BSTR bstrPassword)
{
	return SetProxyAccount (static_cast<PCWSTR> (bstrUserName), static_cast<PCWSTR> (bstrPassword)) ;
}


IMPLEMENT_HTTPCLIENT_STRINGPROPERTY_READONLY (ProxyUserName)
IMPLEMENT_HTTPCLIENT_STRINGPROPERTY_READONLY (ProxyPassword)


STDMETHODIMP CHttpClient::BeginPost (LPCOLESTR szUrl, BOOL bUseCache)
{
	try {
		m_objHttpClient.BeginPost (szUrl, bUseCache) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::BeginPost (const BSTR bstrUrl, BOOL bUseCache)
{
	return BeginPost (static_cast<PCWSTR> (bstrUrl), bUseCache) ;
}

STDMETHODIMP CHttpClient::BeginPostEx (LPCWSTR szUrl, DWORD dwFlags, LPCWSTR szReferer, LPCWSTR szUsrName, LPCWSTR szUsrPwd)
{
	try {
		m_objHttpClient.BeginPostEx (szUrl, dwFlags, szReferer, szUsrName, szUsrPwd) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::BeginPostEx (const BSTR bstrUrl, DWORD dwFlags, const BSTR bstrReferer, const BSTR bstrUsrName, const BSTR bstrUsrPwd)
{
	return BeginPostEx (static_cast<PCWSTR> (bstrUrl), dwFlags, static_cast<PCWSTR> (bstrReferer), static_cast<PCWSTR> (bstrUsrName), static_cast<PCWSTR> (bstrUsrPwd)) ;
}

STDMETHODIMP CHttpClient::BeginUpload (LPCOLESTR szUrl, BOOL bUseCache)
{
	try {
		m_objHttpClient.BeginUpload (szUrl, bUseCache) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::BeginUpload (const BSTR bstrUrl, BOOL bUseCache)
{
	return BeginUpload (static_cast<PCWSTR> (bstrUrl), bUseCache) ;
}

STDMETHODIMP CHttpClient::BeginUploadEx (LPCWSTR szUrl, DWORD dwFlags, LPCWSTR szReferer, LPCWSTR szUsrName, LPCWSTR szUsrPwd)
{
	try {
		m_objHttpClient.BeginUploadEx (szUrl, dwFlags, szReferer, szUsrName, szUsrPwd) ;
	} catch (Ryeol::httpclientexceptionW & e) {
		ErrorHttpClientException (e) ;
		return E_FAIL ;
	}
	return S_OK ;
}

STDMETHODIMP CHttpClient::BeginUploadEx (const BSTR bstrUrl, DWORD dwFlags, const BSTR bstrReferer, const BSTR bstrUsrName, const BSTR bstrUsrPwd)
{
	return BeginUploadEx (static_cast<PCWSTR> (bstrUrl), dwFlags, static_cast<PCWSTR> (bstrReferer), static_cast<PCWSTR> (bstrUsrName), static_cast<PCWSTR> (bstrUsrPwd)) ;
}


#define IMPLEMENT_HTTPCLIENT_QUERY(Interface)																		\
																													\
STDMETHODIMP CHttpClient::Query (Interface * pInterface)															\
{																													\
	ATLASSERT ( pInterface != NULL ) ;																				\
	if ( pInterface == NULL ) {																						\
		ErrorHttpClient (L"The argument(pInterface) can not be NULL") ;												\
		return E_INVALIDARG ;																						\
	}																												\
																													\
	/* Get the Ryeol::CHttpPostStatW pointer */																		\
	Ryeol::CHttpPostStatW *		pobjPostStat = NULL ;																\
	{																												\
		CComPtr<IHttpPostStatInternal2>	spIPostStatInternal ;														\
		HRESULT							hResult ;																	\
																													\
		hResult = pInterface->QueryInterface (																		\
					__uuidof (IHttpPostStatInternal2)																\
					, (void **) &spIPostStatInternal) ;																\
		if ( FAILED (hResult) ) {																					\
			ErrorHttpClient (																						\
				L"Failed to get a IHttpPostStatInternal2 interface"													\
				, Ryeol::HTTPCLIENT_ERR_NOT_SPECIFIED																\
				, hResult																							\
			) ;																										\
			return hResult ;																						\
		}																											\
																													\
		if ( FAILED (hResult = spIPostStatInternal->GetInternalObject ((void **) &pobjPostStat)) ) {				\
			ErrorHttpClient (																						\
				L"Failed to set a Ryeol::CHttpPostStatW object"														\
			) ;																										\
			return hResult ;																						\
		}																											\
	}																												\
																													\
	m_objHttpClient.Query (*pobjPostStat) ;																			\
	return S_OK ;																									\
}

IMPLEMENT_HTTPCLIENT_QUERY (IHttpPostStat2)
IMPLEMENT_HTTPCLIENT_QUERY (IDispHttpPostStat2)


STDMETHODIMP CHttpClient::Cancel (BOOL * pbCanceled)
{
	ATLASSERT ( pbCanceled != NULL ) ;
	if ( pbCanceled == NULL ) {
		ErrorHttpClient (L"The argument(pbCanceled) can not be NULL") ;
		return E_INVALIDARG ;
	}

	*pbCanceled = m_objHttpClient.Cancel () ;
	return S_OK ;
}


#define IMPLEMENT_HTTPCLIENT_PROCEED(Interface)																		\
																													\
STDMETHODIMP CHttpClient::Proceed (DWORD cbDesired, Interface ** ppInterface)										\
{																													\
	ATLASSERT ( ppInterface != NULL ) ;																				\
	if ( ppInterface == NULL ) {																					\
		ErrorHttpClient (L"The argument(ppInterface) can not be NULL") ;											\
		return E_INVALIDARG ;																						\
	}																												\
	*ppInterface = NULL ;																							\
																													\
	Ryeol::CHttpResponseW *		pobjHttpRes = NULL ;																\
	try {																											\
		pobjHttpRes = m_objHttpClient.Proceed (cbDesired) ;															\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
																													\
	if ( pobjHttpRes )																								\
		return _GetIHttpResponse2 (pobjHttpRes, ppInterface) ;														\
																													\
	return S_OK ;																									\
}																													

IMPLEMENT_HTTPCLIENT_PROCEED (IHttpResponse2)
IMPLEMENT_HTTPCLIENT_PROCEED (IDispHttpResponse2)


#define IMPLEMENT_HTTPCLIENT_REQUESTXXX(method, Interface)															\
																													\
STDMETHODIMP CHttpClient::##method (LPCWSTR szUrl, BOOL bUseCache, Interface ** ppInterface)						\
{																													\
	if ( ppInterface == NULL ) {																					\
		ErrorHttpClient (L"The argument(ppInterface) can not be NULL") ;											\
		return E_INVALIDARG ;																						\
	}																												\
	*ppInterface = NULL ;																							\
																													\
	Ryeol::CHttpResponseW *		pobjHttpRes = NULL ;																\
	try {																											\
	pobjHttpRes = m_objHttpClient.##method (szUrl, bUseCache) ;														\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
																													\
	return _GetIHttpResponse2 (pobjHttpRes, ppInterface) ;															\
}																													\
																													\
STDMETHODIMP CHttpClient::##method (const BSTR bstrUrl, BOOL bUseCache, Interface ** ppInterface)					\
{																													\
	return method (static_cast<PCWSTR> (bstrUrl), bUseCache, ppInterface) ;											\
}																													\
																													\
STDMETHODIMP CHttpClient::##method##Ex (LPCWSTR szUrl, DWORD dwFlags, LPCWSTR szReferer, LPCWSTR szUsrName			\
															, LPCWSTR szUsrPwd, Interface ** ppInterface)			\
{																													\
	if ( ppInterface == NULL ) {																					\
		ErrorHttpClient (L"The argument(ppInterface) can not be NULL") ;											\
		return E_INVALIDARG ;																						\
	}																												\
	*ppInterface = NULL ;																							\
																													\
	Ryeol::CHttpResponseW *		pobjHttpRes = NULL ;																\
	try {																											\
		pobjHttpRes = m_objHttpClient.##method##Ex (szUrl, dwFlags, szReferer, szUsrName, szUsrPwd) ;				\
	} catch (Ryeol::httpclientexceptionW & e) {																		\
		ErrorHttpClientException (e) ;																				\
		return E_FAIL ;																								\
	}																												\
																													\
	return _GetIHttpResponse2 (pobjHttpRes, ppInterface) ;															\
}																													\
																													\
STDMETHODIMP CHttpClient::##method##Ex (const BSTR bstrUrl, DWORD dwFlags, const BSTR bstrReferer					\
											, const BSTR bstrUsrName, const BSTR bstrUsrPwd							\
												, Interface ** ppInterface)											\
{																													\
	return method##Ex (static_cast<PCWSTR> (bstrUrl), dwFlags, static_cast<PCWSTR> (bstrReferer)					\
			, static_cast<PCWSTR> (bstrUsrName), static_cast<PCWSTR> (bstrUsrPwd), ppInterface) ;					\
}

IMPLEMENT_HTTPCLIENT_REQUESTXXX (RequestGet, IHttpResponse2)
IMPLEMENT_HTTPCLIENT_REQUESTXXX (RequestPost, IHttpResponse2)
IMPLEMENT_HTTPCLIENT_REQUESTXXX (RequestUpload, IHttpResponse2)

IMPLEMENT_HTTPCLIENT_REQUESTXXX (RequestGet, IDispHttpResponse2)
IMPLEMENT_HTTPCLIENT_REQUESTXXX (RequestPost, IDispHttpResponse2)
IMPLEMENT_HTTPCLIENT_REQUESTXXX (RequestUpload, IDispHttpResponse2)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
Korea (Republic of) Korea (Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions