📄 myhttpclient.cpp
字号:
}
return szUni ;
}
// comparison function (used by STL multimap)
bool CHttpToolA::operator () (LPCSTR szKey1, LPCSTR 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 ::stricmp (szKey1, szKey2) < 0 ;
}
// Initializes a internet handle.
HINTERNET CHttpToolA::OpenInternet (LPCSTR szUserAgent, DWORD dwAccessType
, LPCSTR szProxyName, LPCSTR szProxyBypass, DWORD dwFlags)
throw (Exception &)
{
HINTERNET hInternet ;
if ( NULL == (hInternet = ::InternetOpenA (
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 CHttpToolA::CloseInternet (HINTERNET & hInternet)
throw ()
{
if ( hInternet == NULL )
return ;
// Ignore any errors while closing the handle
::InternetCloseHandle (hInternet) ;
hInternet = NULL ;
}
// Returns a connection handle
// The hInternet must be a valid internet handle.
HINTERNET CHttpToolA::OpenConnection (HINTERNET hInternet, LPCSTR szServerAddr, INTERNET_PORT nPort
, LPCSTR szUsrName, LPCSTR szUsrPwd)
throw (Exception &)
{
HTTPTOOL_ASSERT (hInternet != NULL, "CHttpToolA::OpenConnection: hInternet can not be NULL.") ;
HTTPTOOL_ASSERT (szServerAddr != NULL, "CHttpToolA::OpenConnection: szServerAddr can not be NULL.") ;
HTTPTOOL_ASSERT (::strlen (szServerAddr) != 0, "CHttpToolA::OpenConnection: szServerAddr can not be an empty string.") ;
HINTERNET hConnection ;
if ( NULL == (hConnection = ::InternetConnectA (
hInternet
, szServerAddr
, nPort
, szUsrName
, szUsrPwd
, INTERNET_SERVICE_HTTP
, 0
, NULL)
) )
ThrowException (HTTPCLIENT_ERR_INTERNETCONNECT_FAILED, ::GetLastError ()) ;
return hConnection ;
}
// Closes a connection handle
void CHttpToolA::CloseConnection (HINTERNET & hConnection)
throw ()
{
if ( hConnection == NULL )
return ;
// Ignore any errors while closing the handle
::InternetCloseHandle (hConnection) ;
hConnection = NULL ;
}
// Returns a HTTP request handle
HINTERNET CHttpToolA::OpenRequest (HINTERNET hConnection, LPCSTR szMethod, LPCSTR szObjectName
, DWORD dwFlags, LPCSTR szReferer, UINT /* CodePage */)
throw (Exception &)
{
HTTPTOOL_ASSERT (hConnection != NULL, "CHttpToolA::OpenRequest: hConnection can not be NULL.") ;
HTTPTOOL_ASSERT (szObjectName != NULL, "CHttpToolA::OpenRequest: szObjectName can not be NULL.") ;
HTTPTOOL_ASSERT (::strlen (szObjectName) != 0, "CHttpToolA::OpenRequest: szObjectName can not be an empty string.") ;
static LPCSTR szAcceptedType[] = {
"*/*"
, NULL
} ;
HINTERNET hRequest = NULL ;
// Opens a HTTP request handle
if ( NULL == (hRequest = ::HttpOpenRequestA (
hConnection
, szMethod // HTTP Method
, szObjectName // Target object
, "HTTP/1.1" // HTTP/1.1
, szReferer // referer
, szAcceptedType // Accepts any type.
, dwFlags // Flags
, NULL // Doesn't use any context value.
)
) )
ThrowException (HTTPCLIENT_ERR_HTTPOPENREQUEST_FAILED, ::GetLastError ()) ;
return hRequest ;
}
// Closes a request handle
void CHttpToolA::CloseRequest (HINTERNET & hRequest)
throw ()
{
if ( hRequest == NULL )
return ;
// Ignore any errors while closing the handle
::InternetCloseHandle (hRequest) ;
hRequest = NULL ;
}
void CHttpToolA::AddHeader (HINTERNET hRequest, LPCSTR szName, LPCSTR szValue, UINT /* CodePage */)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::AddHeader: hRequest can not be NULL.") ;
HTTPTOOL_ASSERT (szName != NULL, "CHttpToolA::AddHeader: szName can not be NULL.") ;
::SafeInt<size_t> cbHeader ;
::SafeInt<DWORD> cchHeader ;
try {
cbHeader = ::strlen (szName) ;
cbHeader += szValue ? ::strlen (szValue) : 0 ;
cbHeader += (4 + 1) ; // for ": ", "\r\n", '\0'
cchHeader = cbHeader - 1 ;
} catch (::SafeIntException & e) {
ThrowException (e) ;
}
PSTR szHeader = (PSTR) ::malloc (sizeof (CHAR) * (cbHeader.Value ())) ;
if ( szHeader == NULL )
ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;
::strcpy (szHeader, szName) ;
::strcat (szHeader, ": ") ;
::strcat (szHeader, szValue ? szValue : "") ;
::strcat (szHeader, "\r\n") ;
// Adds a header
if ( !::HttpAddRequestHeadersA (
hRequest
, szHeader // headers to append to the request.
, cchHeader.Value () // header length
, HTTP_ADDREQ_FLAG_ADD // flags
)
) {
SAFEFREE (szHeader) ;
ThrowException (HTTPCLIENT_ERR_HTTPADDREQUESTHEADERS_FAILED, ::GetLastError ()) ;
}
SAFEFREE (szHeader) ;
}
void CHttpToolA::SendRequest (HINTERNET hRequest, LPCSTR szPosted, UINT /* CodePage */)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::SendRequest: hRequest can not be NULL.") ;
::SafeInt<DWORD> cchPosted ;
try {
cchPosted = szPosted ? ::strlen (szPosted) : 0 ;
} catch (::SafeIntException & e) {
ThrowException (e) ;
}
if ( !::HttpSendRequestA (
hRequest
, NULL // Additional header
, 0 // The length of the additional header
, (void *) szPosted // A posted data
, cchPosted.Value () // The length of the posted data
) )
ThrowException (HTTPCLIENT_ERR_HTTPSENDREQUEST_FAILED, ::GetLastError ()) ;
}
void CHttpToolA::SendRequestEx (HINTERNET hRequest, DWORD dwPostedSize)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::SendRequestEx: hRequest can not be NULL.") ;
INTERNET_BUFFERSA 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
BufferIn.dwOffsetLow = 0;
BufferIn.dwOffsetHigh = 0;
if ( !::HttpSendRequestExA (
hRequest
, &BufferIn
, NULL
, 0
, 0
) )
ThrowException (HTTPCLIENT_ERR_HTTPSENDREQUESTEX_FAILED, ::GetLastError ()) ;
}
void CHttpToolA::InternetWriteFile (HINTERNET hRequest, const BYTE * pbyBuff, DWORD cbyBuff)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::InternetWriteFile: hRequest can not be NULL.") ;
HTTPTOOL_ASSERT (pbyBuff != NULL, "CHttpToolA::InternetWriteFile: pbyBuff can not be NULL.") ;
HTTPTOOL_ASSERT (cbyBuff != 0, "CHttpToolA::InternetWriteFile: cbyBuff can not be zero.") ;
DWORD dwTotalWritten = 0, dwWritten ;
while ( dwTotalWritten < cbyBuff ) {
if ( !::InternetWriteFile (
hRequest
, pbyBuff + dwTotalWritten
, cbyBuff - dwTotalWritten
, &dwWritten
)
)
ThrowException (HTTPCLIENT_ERR_INTERNETWRITEFILE_FAILED, ::GetLastError ()) ;
dwTotalWritten += dwWritten ;
}
}
void CHttpToolA::EndRequest (HINTERNET hRequest)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::EndRequest: hRequest can not be NULL.") ;
if ( !::HttpEndRequest (
hRequest
, NULL
, 0
, 0
)
)
ThrowException (HTTPCLIENT_ERR_HTTPENDREQUEST_FAILED, ::GetLastError ()) ;
}
// Checks whether the file exists.
// (Does not throw an exception)
BOOL CHttpToolA::FileExists (LPCSTR szFilePath)
throw (Exception &)
{
HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::FileExists: szFilePath can not be NULL.") ;
HANDLE hFile = ::CreateFileA (
szFilePath
, 0
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL) ;
if ( hFile != INVALID_HANDLE_VALUE )
{
::CloseHandle (hFile) ;
return TRUE ;
}
return FALSE ;
}
// It returns a INVALID_HANDLE_VALUE if the specified file is not valid.
// (Does not throw an exception)
HANDLE CHttpToolA::OpenFile (LPCSTR szFilePath)
throw (Exception &)
{
HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::OpenFile: szFilePath can not be NULL.") ;
return ::CreateFileA (
szFilePath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN
, NULL) ;
}
// If it fails to create an file, it will return INVALID_HANDLE_VALUE.
// (Does not throw an exception)
HANDLE CHttpToolA::CreateFileAlwaysToWrite (LPCSTR szFilePath)
throw (Exception &)
{
HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::CreateFileAlwaysToWrite: szFilePath can not be NULL.") ;
return ::CreateFileA (
szFilePath
, GENERIC_WRITE
, 0
, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL) ;
}
DWORD CHttpToolA::GetFileSize (HANDLE hFile, LPCSTR szFilePath)
throw (Exception &)
{
HTTPTOOL_ASSERT (hFile != NULL, "CHttpToolA::GetFileSize: hFile can not be NULL.") ;
HTTPTOOL_ASSERT (szFilePath != NULL, "CHttpToolA::GetFileSize: szFilePath can not be NULL.") ;
DWORD dwFileSize = ::GetFileSize (hFile, NULL) ;
if ( dwFileSize == INVALID_FILE_SIZE )
ThrowException (HTTPCLIENT_ERR_GETFILESIZE_FAILED, ::GetLastError (), szFilePath) ;
return dwFileSize ;
}
// The file handle must point to BOF. If the file handle is INVALID_HANDLE_VALUE
// The default mime type is returned.
// The returned string must be freed by using the ::free () function.
LPSTR CHttpToolA::GetMimeType (HANDLE hFile, UINT CodePage)
throw (Exception &)
{
HTTPTOOL_ASSERT (hFile != NULL, "CHttpToolA::GetMimeType: hFile can not be NULL.") ;
LPSTR szMimeType = NULL ;
try {
szMimeType = CHttpToolW::GetMimeType (hFile, CodePage) ;
} catch (CHttpToolW::Exception & e) {
ThrowException (e) ;
}
return szMimeType ;
}
// Returns the HTTP status text from the HTTP request handle.
// The returned string must be freed by using the ::free () function.
LPSTR CHttpToolA::GetStatusText (HINTERNET hRequest)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::GetStatusText: hRequest can not be NULL.") ;
DWORD cbBuff = 0 ;
LPSTR szStatusText = NULL ;
// Get required buffer size
if ( !::HttpQueryInfoA (
hRequest
, HTTP_QUERY_STATUS_TEXT // Get the status text
, static_cast<void *> (szStatusText)
, &cbBuff // Required buffer size (byte)
, NULL // Don't use a header index
)
)
if ( ::GetLastError () != ERROR_INSUFFICIENT_BUFFER )
ThrowException (HTTPCLIENT_ERR_QUERYINFO_FAILED, ::GetLastError ()) ;
_ASSERTE ( cbBuff != 0 ) ;
szStatusText = (LPSTR) ::malloc (cbBuff) ;
if ( szStatusText == NULL )
ThrowException (HTTPCLIENT_ERR_OUT_OF_MEMORY) ;
// Get the status text
if ( !::HttpQueryInfoA (
hRequest
, HTTP_QUERY_STATUS_TEXT // Get the status text
, static_cast<void *> (szStatusText)
, &cbBuff // Allocated buffer size (byte)
, NULL // Don't use a header index
)
) {
::free (szStatusText) ;
ThrowException (HTTPCLIENT_ERR_QUERYINFO_FAILED, ::GetLastError ()) ;
}
return szStatusText ;
}
// Get the HTTP header which has the name specified by szName from the HTTP request handle.
// If the header is not found, NULL is returned.
// The returned string must be freed by using the ::free () function.
// pnIdx exactly corresponds to the lpdwIndex parameter in the ::HttpQueryInfo function.
// For more information about this parameter, see microsoft's SDK documentation.
LPSTR CHttpToolA::GetHeader (HINTERNET hRequest, LPCSTR szName, DWORD * pnIdx)
throw (Exception &)
{
HTTPTOOL_ASSERT (hRequest != NULL, "CHttpToolA::GetHeader: hRequest can not be NULL.") ;
HTTPTOOL_ASSERT (szName != NULL, "CHttpToolA::GetHeader: szName can not be NULL.") ;
DWORD nOrigIdx = 0 ;
if ( pnIdx ) nOrigIdx = *pnIdx ;
// Copy the header name
::SafeInt<DWORD> cbBuff ;
try {
cbBuff = ::strlen (szName) ;
cbBuff++ ;
cbBuff *= sizeof (CHAR) ;
} catch (::SafeIntException & e) {
ThrowException (e) ;
}
PSTR szHeader = (PSTR) ::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 ()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -