?? myhttpclient.cpp
字號:
, pnIdx
)
)
return szHeader ;
SAFEFREE (szHeader) ;
if ( pnIdx ) *pnIdx = nOrigIdx ;
// If the function failed
if ( ::GetLastError () != ERROR_INSUFFICIENT_BUFFER ) {
// If the header does not exist
if ( ::GetLastError () == ERROR_HTTP_HEADER_NOT_FOUND )
return NULL ;
ThrowException (HTTPCLIENT_ERR_QUERYINFO_FAILED, ::GetLastError ()) ;
}
// Allocates required memory
szHeader = (LPSTR) ::malloc (cbBuff.Value ()) ;
if ( szHeader == NULL )
ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;
::strcpy (szHeader, szName) ;
if ( !::HttpQueryInfoA (
hRequest
, HTTP_QUERY_CUSTOM // Get a custom header
, static_cast<void *> (szHeader)
, cbBuff.Ptr ()
, pnIdx
)
) {
SAFEFREE (szHeader) ;
ThrowException (HTTPCLIENT_ERR_QUERYINFO_FAILED, ::GetLastError ()) ;
}
return szHeader ;
}
void CHttpToolA::InternetSetOption (HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, DWORD dwBufferLength)
throw (Exception &)
{
if ( ::InternetSetOptionA (hInternet, dwOption, lpBuffer, dwBufferLength) )
return ;
ThrowException (HTTPCLIENT_ERR_INTERNETSETOPTION_FAILED, ::GetLastError ()) ;
}
// Generates a new upload boundary. If an error occurs, NULL is returned
// The returned string must be freed by using the ::free () function.
LPSTR CHttpToolA::CreateUploadBoundary (void)
throw ()
{
GUID guid ;
if ( FAILED ( ::CoCreateGuid (&guid)) )
return NULL ;
PSTR szBoundary = (PSTR) ::malloc (sizeof (CHAR) * 44) ;
if ( szBoundary == NULL )
return NULL ;
::sprintf (szBoundary, "----LYOUL-%.08x%.04x%.04x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x-"
, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1]
, guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
return szBoundary ;
}
///////////////////////////////////////// CHttpToolA /////////////////////////////////////////
///////////////////////////////////////// CHttpToolW /////////////////////////////////////////
inline
LPCWSTR CHttpToolW::GetConstMessage (int nIdx)
throw ()
{
// user-defined error message
if ( nIdx >= 1000 )
return g_UsrErrMsgW[0] ;
// Win32 API error (which has a win32 error code)
if ( nIdx >= 600 )
return g_Win32MsgWin32W[nIdx % 100] ;
// WinInet error (which has a win32 error code)
if ( nIdx >= 400 )
return g_WinInetMsgWin32W[nIdx % 100] ;
// Normal error (which has a win32 error code)
if ( nIdx >= 200 )
return g_NormalMsgWin32W[nIdx % 100] ;
// Normal error
if ( nIdx >= 100 )
return g_NormalMsgW[nIdx % 100] ;
return g_NotSpecifiedW[nIdx] ;
}
void CHttpToolW::ThrowException (DWORD nErrMsgIdx)
throw (Exception &)
{
throw Exception (GetConstMessage (nErrMsgIdx), nErrMsgIdx) ;
}
void CHttpToolW::ThrowException (LPCWSTR szErrMsg, DWORD nErrMsgIdx)
throw (Exception &)
{
throw Exception (szErrMsg, nErrMsgIdx) ;
}
void CHttpToolW::ThrowException (DWORD nErrMsgIdx, DWORD dwErrCode, LPCWSTR szStrArg)
throw (Exception &)
{
if ( szStrArg == NULL )
throw Exception (GetConstMessage (nErrMsgIdx), nErrMsgIdx, dwErrCode) ;
WCHAR szErrMsg[512] ;
LPCWSTR szFormat = GetConstMessage (nErrMsgIdx) ;
int cchWritten = SNPrintf (szErrMsg, 511, szFormat, szStrArg ? szStrArg : L"NULL") ;
// if an error occurs
if ( cchWritten < -1 )
throw Exception (szFormat, nErrMsgIdx, dwErrCode) ;
if ( cchWritten == -1 )
cchWritten = 511 ;
szErrMsg[cchWritten] = NULL ;
throw Exception (szErrMsg, nErrMsgIdx, dwErrCode) ;
}
void CHttpToolW::ThrowException (LPCSTR szErrMsg, DWORD nErrMsgIdx, DWORD dwErrCode)
throw (Exception &)
{
LPWSTR szErrMsgW = NULL ;
try {
szErrMsgW = Ansi2Unicode (szErrMsg) ;
} catch (Exception &) {
;
}
Exception objException (szErrMsgW, nErrMsgIdx, dwErrCode) ;
SAFEFREE (szErrMsgW) ;
throw objException ;
}
void CHttpToolW::ThrowException (httpclientexceptionA & e)
throw (Exception &)
{
ThrowException (e.errmsg (), e.LastError (), e.Win32LastError ()) ;
}
void CHttpToolW::ThrowException (::SafeIntException & e)
throw (Exception &)
{
switch ( e.m_code ) {
case ERROR_ARITHMETIC_OVERFLOW:
ThrowException (HTTPCLIENT_ERR_ARITHMETIC_OVERFLOW) ;
break ;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
ThrowException (HTTPCLIENT_ERR_INT_DIVIDE_BY_ZERO) ;
break ;
default:
ThrowException (HTTPCLIENT_ERR_UNEXPECTED_ARITHMETIC_ERROR) ;
break ;
}
}
// Conversion methods
// This function returns a converted ansi string from a unicode string.
// The returned string must be freed by using the ::free () function.
LPSTR CHttpToolW::Unicode2Ansi (LPCWSTR szStr, UINT CodePage)
throw (Exception &)
{
// The unicode encodings are not allowed
HTTPTOOL_ASSERT ((CodePage != CP_UTF8) && (CodePage != CP_UTF7)
, "CHttpToolW::Unicode2Ansi: CP_UTF8 and CP_UTF7 can not be used for the CodePage parameter.") ;
if ( szStr == NULL )
return NULL ;
int cchNeeded ;
if ( 0 == (cchNeeded = ::WideCharToMultiByte (CodePage, 0, szStr, -1, NULL, 0, NULL, NULL)) )
ThrowException (HTTPCLIENT_ERR_WIDECHARTOMULTIBYTE_FAILED, ::GetLastError ()) ;
PSTR szAnsi = (PSTR) ::malloc (sizeof (CHAR) * cchNeeded) ;
if ( szAnsi == NULL )
ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;
if ( 0 == ::WideCharToMultiByte (CodePage, 0, szStr, -1, szAnsi, cchNeeded, NULL, NULL) ) {
SAFEFREE (szAnsi) ;
ThrowException (HTTPCLIENT_ERR_WIDECHARTOMULTIBYTE_FAILED, ::GetLastError ()) ;
}
return szAnsi ;
}
// This method returns a converted unicode string from a ansi string.
// The returned string must be freed by using the ::free () function.
LPWSTR CHttpToolW::Ansi2Unicode (LPCSTR szStr, UINT CodePage)
throw (Exception &)
{
// The unicode encodings are not allowed
HTTPTOOL_ASSERT ((CodePage != CP_UTF8) && (CodePage != CP_UTF7)
, "CHttpToolW::Ansi2Unicode: CP_UTF8 and CP_UTF7 can not be used for the CodePage parameter.") ;
if ( szStr == NULL )
return NULL ;
int cchNeeded ;
if ( 0 == (cchNeeded = ::MultiByteToWideChar (CodePage, 0, szStr, -1, NULL, 0)) )
ThrowException (HTTPCLIENT_ERR_MULTIBYTETOWIDECHAR_FAILED, ::GetLastError ()) ;
PWSTR szUni = (PWSTR) ::malloc (sizeof (WCHAR) * cchNeeded) ;
if ( szUni == NULL )
ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;
if ( 0 == ::MultiByteToWideChar (CodePage, 0, szStr, -1, szUni, cchNeeded) ) {
SAFEFREE (szUni) ;
ThrowException (HTTPCLIENT_ERR_MULTIBYTETOWIDECHAR_FAILED, ::GetLastError ()) ;
}
return szUni ;
}
// comparison function (used by STL multimap)
bool CHttpToolW::operator () (LPCWSTR szKey1, LPCWSTR szKey2) const
throw ()
{
// return true if the two strings are null
if ( szKey1 == NULL && szKey2 == NULL )
return true ;
if ( szKey1 == NULL )
return true ;
if ( szKey2 == NULL )
return false ;
// case insensitive
return ::wcsicmp (szKey1, szKey2) < 0 ;
}
// Initializes a internet handle.
HINTERNET CHttpToolW::OpenInternet (LPCWSTR szUserAgent, DWORD dwAccessType
, LPCWSTR szProxyName, LPCWSTR szProxyBypass, DWORD dwFlags)
throw (Exception &)
{
HINTERNET hInternet ;
if ( NULL == (hInternet = InternetOpenW (
szUserAgent // user agent
, dwAccessType // use direct connection or proxy connection
, szProxyName
, szProxyBypass
, dwFlags)
) )
ThrowException (HTTPCLIENT_ERR_INTERNETOPEN_FAILED, ::GetLastError ()) ;
return hInternet ;
}
// Closes a internet handle
void CHttpToolW::CloseInternet (HINTERNET & hInternet)
throw ()
{
CHttpToolA::CloseInternet (hInternet) ;
}
// Returns a connection handle
// The hInternet must be a valid internet handle.
HINTERNET CHttpToolW::OpenConnection (HINTERNET hInternet, LPCWSTR szServerAddr, INTERNET_PORT nPort
, LPCWSTR szUsrName, LPCWSTR szUsrPwd)
throw (Exception &)
{
HTTPTOOL_ASSERT (hInternet != NULL, "CHttpToolW::OpenConnection: hInternet can not be NULL.") ;
HTTPTOOL_ASSERT (szServerAddr != NULL, "CHttpToolW::OpenConnection: szServerAddr can not be NULL.") ;
HTTPTOOL_ASSERT (::wcslen (szServerAddr) != 0, "CHttpToolW::OpenConnection: szServerAddr can not be an empty string.") ;
HINTERNET hConnection ;
if ( NULL == (hConnection = ::InternetConnectW (
hInternet
, szServerAddr
, nPort
, szUsrName
, szUsrPwd
, INTERNET_SERVICE_HTTP
, 0
, NULL)
) )
ThrowException (HTTPCLIENT_ERR_INTERNETCONNECT_FAILED, ::GetLastError ()) ;
return hConnection ;
}
// Closes a connection handle
void CHttpToolW::CloseConnection (HINTERNET & hConnection)
throw ()
{
CHttpToolA::CloseConnection (hConnection) ;
}
// Returns a HTTP request handle
HINTERNET CHttpToolW::OpenRequest (HINTERNET hConnection, LPCWSTR szMethod, LPCWSTR szObjectName
, DWORD dwFlags, LPCWSTR szReferer, UINT CodePage)
throw (Exception &)
{
HTTPTOOL_ASSERT (hConnection != NULL, "CHttpToolW::OpenRequest: hConnection can not be NULL.") ;
HTTPTOOL_ASSERT (szObjectName != NULL, "CHttpToolW::OpenRequest: szObjectName can not be NULL.") ;
HTTPTOOL_ASSERT (::wcslen (szObjectName) != 0, "CHttpToolW::OpenRequest: szObjectName can not be an empty string.") ;
// The unicode encodings are not allowed
HTTPTOOL_ASSERT ((CodePage != CP_UTF8) && (CodePage != CP_UTF7)
, "CHttpToolW::OpenRequest: CP_UTF8 and CP_UTF7 can not be used for the CodePage parameter.") ;
LPSTR szMethodA = NULL ;
LPSTR szObjectNameA = NULL ;
LPSTR szRefererA = NULL ;
HINTERNET hRequest = NULL ;
try {
szMethodA = Unicode2Ansi (szMethod, CodePage) ;
szObjectNameA = Unicode2Ansi (szObjectName, CodePage) ;
szRefererA = Unicode2Ansi (szReferer, CodePage) ;
hRequest = CHttpToolA::OpenRequest (hConnection, szMethodA, szObjectNameA
, dwFlags, szRefererA) ;
} catch (Exception &) {
SAFEFREE (szMethodA) ;
SAFEFREE (szObjectNameA) ;
SAFEFREE (szRefererA) ;
throw ;
} catch (CHttpToolA::Exception & e) {
SAFEFREE (szMethodA) ;
SAFEFREE (szObjectNameA) ;
SAFEFREE (szRefererA) ;
ThrowException (e) ;
}
SAFEFREE (szMethodA) ;
SAFEFREE (szObjectNameA) ;
SAFEFREE (szRefererA) ;
return hRequest ;
}
// Closes a request handle
void CHttpToolW::CloseRequest (HINTERNET & hRequest)
throw ()
{
CHttpToolA::CloseRequest (hRequest) ;
}
void CHttpToolW::AddHeader (HINTERNET hRequest, LPCWSTR szName, LPCWSTR szValue, UINT CodePage)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolW::AddHeader: hRequest can not be NULL.") ;
HTTPTOOL_ASSERT (szName != NULL, "CHttpToolW::AddHeader: szName can not be NULL.") ;
// The unicode encodings are not allowed
HTTPTOOL_ASSERT ((CodePage != CP_UTF8) && (CodePage != CP_UTF7)
, "CHttpToolW::AddHeader: CP_UTF8 and CP_UTF7 can not be used for the CodePage parameter.") ;
LPSTR szNameA = NULL ;
LPSTR szValueA = NULL ;
try {
szNameA = Unicode2Ansi (szName, CodePage) ;
szValueA = Unicode2Ansi (szValue, CodePage) ;
CHttpToolA::AddHeader (hRequest, szNameA, szValueA) ;
} catch (Exception &) {
SAFEFREE (szNameA) ;
SAFEFREE (szValueA) ;
throw ;
} catch (CHttpToolA::Exception & e) {
SAFEFREE (szNameA) ;
SAFEFREE (szValueA) ;
ThrowException (e) ;
}
SAFEFREE (szNameA) ;
SAFEFREE (szValueA) ;
}
void CHttpToolW::SendRequest (HINTERNET hRequest, LPCWSTR szPosted, UINT CodePage)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolW::SendRequest: hRequest can not be NULL.") ;
// The unicode encodings are not allowed
HTTPTOOL_ASSERT ((CodePage != CP_UTF8) && (CodePage != CP_UTF7)
, "CHttpToolW::SendRequest: CP_UTF8 and CP_UTF7 can not be used for the CodePage parameter.") ;
LPSTR szPostedA = Unicode2Ansi (szPosted, CodePage) ;
::SafeInt<DWORD> cchPosted ;
try {
cchPosted = szPostedA ? ::strlen (szPostedA) : 0 ;
} catch (::SafeIntException & e) {
SAFEFREE (szPostedA) ;
ThrowException (e) ;
}
if ( !::HttpSendRequestW (
hRequest
, NULL // Additional header
, 0 // The length of the additional header
, (void *) szPostedA // A posted data
, cchPosted.Value () // The length of the posted data
) ) {
SAFEFREE (szPostedA) ;
ThrowException (HTTPCLIENT_ERR_HTTPSENDREQUEST_FAILED, ::GetLastError ()) ;
}
SAFEFREE (szPostedA) ;
}
void CHttpToolW::SendRequestEx (HINTERNET hRequest, DWORD dwPostedSize)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolW::SendRequestEx: hRequest can not be NULL.") ;
INTERNET_BUFFERSW BufferIn;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur
BufferIn.Next = NULL;
BufferIn.lpcszHeader = NULL;
BufferIn.dwHeadersLength = 0;
BufferIn.dwHeadersTotal = 0;
BufferIn.lpvBuffer = NULL;
BufferIn.dwBufferLength = 0;
BufferIn.dwBufferTotal = dwPostedSize; // This is the only member used other than dwStructSize
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -