📄 wininetconnector.cpp
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: STDMETHODIMP CWinInetConnector::ShutdownConnection()
//
// parameters:
//
// description:
// Shuts the connection down
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CWinInetConnector::ShutdownConnection()
{
if (m_hRequest)
{
#ifndef UNDER_CE // dont call close handle! when we set to 0 the auto template magic will fix it
::InternetCloseHandle(m_hRequest);
#endif
m_hRequest = 0;
}
if (m_hConnect)
{
#ifndef HTTP_LITE
::InternetSetOption(m_hConnect, INTERNET_OPTION_END_BROWSER_SESSION, 0, 0);
#endif
#ifndef UNDER_CE // dont call close handle! when we set to 0 the auto template magic will fix it
::InternetCloseHandle(m_hConnect);
#endif
m_hConnect = 0;
}
if (m_hInternet)
{
::InternetCloseHandle(m_hInternet);
m_hInternet = 0;
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: STDMETHODIMP CWinInetConnector::SendRequest()
//
// parameters:
//
// description:
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CWinInetConnector::SendRequest()
{
if (! m_pRequest)
{
return E_INVALIDARG;
}
HRESULT hr = S_OK;
DWORD dwFlags = 0;
LPSTR pProxyUser = 0;
LPSTR pProxyPwd = 0;
LPSTR pUserName = 0;
LPSTR pPassword = 0;
PCCERT_CONTEXT pCertContext = 0;
#ifndef UNDER_CE
dwFlags = (m_Url.Scheme() == INTERNET_SCHEME_HTTPS || m_bUseSSL) ?
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_KEEP_CONNECTION:
INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_KEEP_CONNECTION;
#else
#ifndef HTTP_LITE
dwFlags = (m_Url.Scheme() == INTERNET_SCHEME_HTTPS || m_bUseSSL) ?
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_KEEP_CONNECTION:
INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_KEEP_CONNECTION;
#else
dwFlags = (m_Url.Scheme() == INTERNET_SCHEME_HTTPS || m_bUseSSL) ?
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE :
INTERNET_FLAG_NO_CACHE_WRITE;
#endif
#endif
#ifndef UNDER_CE
m_hRequest = ::HttpOpenRequest(m_hConnect, L"POST", m_Url.ExtraPath(), L"HTTP/1.0", 0, 0, dwFlags, 0);
CHK_BOOL(m_hRequest, MAP_WININET_ERROR());
#else
HINTERNET hTemp;
hTemp = ::HttpOpenRequest(m_hConnect, L"POST", m_Url.ExtraPath(), L"HTTP/1.0", 0, 0, dwFlags, reinterpret_cast<DWORD>(&m_hRequest));
#ifdef DEBUG
if(hTemp == NULL)
{
DWORD dwError = GetLastError();
WCHAR msg[100];
swprintf(msg, L"HttpOpenRequestA failed! error:%x\n", dwError);
OutputDebugString(msg);
}
#endif
CHK_BOOL(hTemp, MAP_WININET_ERROR());
m_hRequest = hTemp;
#endif
CHK_BOOL(::InternetSetOption(m_hRequest, INTERNET_OPTION_RECEIVE_TIMEOUT, &m_dwTimeout, sizeof(m_dwTimeout)) == TRUE,
MAP_WININET_ERROR());
__try
{
LPWSTR pTheUserName = m_bstrAuthUser ? m_bstrAuthUser : m_Url.UserName();
LPWSTR pThePassword = m_bstrAuthPassword ? m_bstrAuthPassword : m_Url.Password();
if (pTheUserName) { CONVERT_WIDECHAR_TO_MULTIBYTE(pTheUserName, pUserName); }
if (pThePassword) { CONVERT_WIDECHAR_TO_MULTIBYTE(pThePassword, pPassword); }
if (m_bstrProxyUser) { CONVERT_WIDECHAR_TO_MULTIBYTE(m_bstrProxyUser, pProxyUser); }
if (m_bstrProxyPassword) { CONVERT_WIDECHAR_TO_MULTIBYTE(m_bstrProxyPassword, pProxyPwd); }
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
if (pUserName)
{
CHK_BOOL(::InternetSetOptionA(m_hRequest, INTERNET_OPTION_USERNAME, pUserName, strlen(pUserName)) == TRUE,
MAP_WININET_ERROR());
}
if (pPassword)
{
CHK_BOOL(::InternetSetOptionA(m_hRequest, INTERNET_OPTION_PASSWORD, pPassword, strlen(pPassword)) == TRUE,
MAP_WININET_ERROR());
}
#ifndef HTTP_LITE
if (pProxyUser)
{
CHK_BOOL(::InternetSetOptionA(m_hRequest, INTERNET_OPTION_PROXY_USERNAME, pProxyUser, strlen(pProxyUser)) == TRUE,
MAP_WININET_ERROR());
}
if (pProxyPwd)
{
CHK_BOOL(::InternetSetOptionA(m_hRequest, INTERNET_OPTION_PROXY_PASSWORD, pProxyPwd, strlen(pProxyPwd)) == TRUE,
MAP_WININET_ERROR());
}
#endif
TRACE(("HttpOpenRequest ==> hRequest == (0x%08X)\n", m_hRequest));
CHK(AddHeaders());
hr = m_pRequest->Send(m_hRequest);
#ifndef HTTP_LITE
if (hr == CONN_E_HTTP_CLIENT_AUTH_CERT_NEEDED)
{
CHK(FindCertificate(m_bstrSSLClientCertificateName, &pCertContext));
if (pCertContext)
{
CHK_BOOL(::InternetSetOption(m_hRequest, INTERNET_OPTION_CLIENT_CERT_CONTEXT, const_cast<PCERT_CONTEXT>(pCertContext), sizeof(CERT_CONTEXT)) == TRUE,
MAP_WININET_ERROR());
CHK(m_pRequest->Send(m_hRequest));
}
else
{
hr = MAP_WININET_ERROR_(HRESULT_FROM_WIN32(ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED));
goto Cleanup;
}
}
#endif
CHK(m_pRequest->EmptyStream());
Cleanup:
if (pCertContext)
{
::CertFreeCertificateContext(pCertContext);
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: STDMETHODIMP CWinInetConnector::ReceiveResponse()
//
// parameters:
//
// description:
// Receives the response and checks HTTP status and content-type
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CWinInetConnector::ReceiveResponse()
{
HRESULT hr = S_OK;
DWORD dwStatus = 0;
DWORD dwSize = sizeof(DWORD);
if (::HttpQueryInfo(m_hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwSize, 0) != TRUE)
{
hr = CONN_E_CONNECTION_ERROR;
goto Cleanup;
}
TRACE(("Http Status == %i\n", dwStatus));
hr = ::HttpStatusToHresult(dwStatus);
if (SUCCEEDED(hr) || hr == CONN_E_SERVER_ERROR)
{
char contentType[1024];
dwSize = sizeof(contentType);
if (::HttpQueryInfoA(m_hRequest, HTTP_QUERY_CONTENT_TYPE, contentType, &dwSize, 0) != TRUE)
{
hr = CONN_E_BAD_CONTENT;
goto Cleanup;
}
CHK(::HttpContentTypeToHresult(contentType));
hr = S_OK;
}
TRACE(("Http response status (in connector) == %i\n", dwStatus));
Cleanup:
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: STDMETHODIMP CWinInetConnector::EmptyBuffers()
//
// parameters:
//
// description:
// Empties the buffers maintained by the connector
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CWinInetConnector::EmptyBuffers()
{
if (m_pRequest)
{
m_pRequest->EmptyStream();
}
if (m_hRequest)
{
#ifndef UNDER_CE // dont call close handle! when we set to 0 the auto template magic will fix it
::InternetCloseHandle(m_hRequest);
#endif
m_hRequest = 0;
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CWinInetConnector::AddHeaders()
//
// parameters:
//
// description:
//
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWinInetConnector::AddHeaders()
{
HRESULT hr = S_OK;
BSTR escSA = 0;
#ifdef UNDER_CE
WCHAR wcContentType[1024];
WCHAR *pwcContentType = wcContentType;
#endif
CHK(EscapeUrl(m_bstrSoapAction, &escSA));
if (escSA)
{
WCHAR *soapAction = 0;
BYTE *pSA = 0;
size_t saSize = wcslen(escSA) * sizeof(WCHAR);
size_t sa = saSize + char_array_size(s_szSoapAction) + char_array_size(s_szNewLine) +
sizeof(WCHAR) + sizeof(WCHAR) + sizeof(WCHAR);
#ifndef CE_NO_EXCEPTIONS
try
#else
__try
#endif
{
soapAction = reinterpret_cast<WCHAR *>(_alloca(sa));
}
#ifndef CE_NO_EXCEPTIONS
catch (...)
#else
__except(1)
#endif
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
pSA = reinterpret_cast<BYTE *>(soapAction);
memcpy(pSA, s_szSoapAction, char_array_size(s_szSoapAction));
pSA += char_array_size(s_szSoapAction);
memcpy(pSA, &s_Quote, sizeof(s_Quote));
pSA += sizeof(s_Quote);
memcpy(pSA, escSA, saSize);
pSA += saSize;
memcpy(pSA, &s_Quote, sizeof(s_Quote));
pSA += sizeof(s_Quote);
memcpy(pSA, s_szNewLine, sizeof(s_szNewLine)); // copies trailing zero
CHK_BOOL(::HttpAddRequestHeaders(m_hRequest, soapAction, -1, HTTP_ADDREQ_FLAG_ADD) == TRUE, MAP_WININET_ERROR());
}
#ifdef UNDER_CE
if(0!= m_bstrHTTPCharset && ::SysStringByteLen(m_bstrHTTPCharset) > 0) {
const WCHAR cwcContentType[] = L"Content-Type: text/xml; charset=\"%s\"\r\n";
// get the byte size of the charset
UINT uiSize = ::SysStringLen(m_bstrHTTPCharset) + wcslen(cwcContentType) + 1;
if(uiSize >= sizeof(wcContentType)/sizeof(wcContentType[0])) {
pwcContentType = new WCHAR[uiSize + 1];
if(!pwcContentType)
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
}
hr = StringCbPrintf(pwcContentType, sizeof(wcContentType), cwcContentType, m_bstrHTTPCharset);
if(FAILED(hr)) {
goto Cleanup;
}
CHK_BOOL(::HttpAddRequestHeaders(m_hRequest, pwcContentType, -1, HTTP_ADDREQ_FLAG_ADD) == TRUE, MAP_WININET_ERROR());
} else {
CHK_BOOL(::HttpAddRequestHeaders(m_hRequest, L"Content-Type: text/xml\r\n", -1, HTTP_ADDREQ_FLAG_ADD) == TRUE, MAP_WININET_ERROR());
}
#else
CHK_BOOL(::HttpAddRequestHeaders(m_hRequest, L"Content-Type: text/xml\r\n", -1, HTTP_ADDREQ_FLAG_ADD) == TRUE, MAP_WININET_ERROR());
#endif
CHK_BOOL(::HttpAddRequestHeaders(m_hRequest, L"User-Agent: SOAP Sdk\r\n", -1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE) == TRUE, MAP_WININET_ERROR());
Cleanup:
#ifdef UNDER_CE
if(pwcContentType && pwcContentType != wcContentType) {
delete [] pwcContentType;
}
#endif
::SysFreeString(escSA);
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT CWinInetConnector::WinInetErrorToHResult(HRESULT hr)
//
// parameters:
//
// description:
// Translates HRESULT into HRESULT based on WinInet's HRESULT map
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CWinInetConnector::WinInetErrorToHResult(HRESULT hr)
{
return ::HResultToHResult(&g_WinInetHResultMap, hr);
}
#ifdef _DEBUG
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: STDMETHODIMP_(bool) CWinInetConnector::IsConnected()
//
// parameters:
//
// description:
// Debug function - is connector truly connected?
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(bool) CWinInetConnector::IsConnected()
{
return m_hInternet && m_hConnect;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -