xmlhttprequest.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,107 行 · 第 1/2 页
CPP
1,107 行
LPTSTR lpszPassword = NULL; if (pCtx->m_User.length() > 0) { bPromptForAuthentication = false; lpszUserName = pCtx->m_User; if (pCtx->m_Password.length() > 0) lpszPassword = pCtx->m_Password; } hConnect = InternetConnect(hOpen,pCtx->m_HostName,pCtx->m_Port,lpszUserName,lpszPassword, INTERNET_SERVICE_HTTP,0,reinterpret_cast<DWORD> (pCtx)); if (NULL == hConnect) { DWORD res = GetLastError(); pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); pCtx->m_bSuccess = false; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { DWORD dwFlags = (443 == pCtx->m_Port) ? INTERNET_FLAG_SECURE : 0; dwFlags |= INTERNET_FLAG_NO_CACHE_WRITE; hRequest = HttpOpenRequest(hConnect,pCtx->m_Method, pCtx->m_URLPath,NULL,NULL,NULL, dwFlags,reinterpret_cast<DWORD> (pCtx)); if (NULL == hRequest) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } BOOL rc = TRUE; if (!pCtx->m_bAbort && pCtx->m_bSuccess && pCtx->m_RequestHeaderMap.GetSize() > 0) { _bstr_t requestHeaders; for (int i = 0 ; i < pCtx->m_RequestHeaderMap.GetSize(); ++i) { requestHeaders += pCtx->m_RequestHeaderMap.GetKeyAt(i); requestHeaders += _T(": "); requestHeaders += pCtx->m_RequestHeaderMap.GetValueAt(i); requestHeaders += _T("\r\n"); } rc = HttpAddRequestHeaders(hRequest,requestHeaders,-1,HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); if (!rc) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } DWORD dwLen = 0; DWORD dwError = ERROR_SUCCESS; do { if (!pCtx->m_bAbort && pCtx->m_bSuccess) { rc = HttpSendRequest(hRequest,NULL,0,pCtx->m_pBody,pCtx->m_lBodyLength); if (!rc) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); break; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { dwLen = sizeof(DWORD); rc = HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &pCtx->m_dwStatus,&dwLen,NULL); if (!rc) { DWORD res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); break; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess && bPromptForAuthentication && (HTTP_STATUS_PROXY_AUTH_REQ == pCtx->m_dwStatus || HTTP_STATUS_DENIED == pCtx->m_dwStatus)) dwError = InternetErrorDlg(pCtx->m_HwndParent, hRequest, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL); else break; } while (ERROR_INTERNET_FORCE_RETRY == dwError && !pCtx->m_bAbort && pCtx->m_bSuccess); if (!pCtx->m_bAbort && pCtx->m_bSuccess) { dwLen = 1024; TCHAR *pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,pBuff,&dwLen,NULL); if (!rc) { DWORD res = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == res) { delete [] pBuff; pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF,pBuff,&dwLen,NULL); if (!rc) { res = GetLastError(); pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } else { pCtx->m_bSuccess = false; pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); } } if (rc) pCtx->m_ResponseHeaders = pBuff; delete [] pBuff; } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { dwLen = 1024; TCHAR *pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_STATUS_TEXT,pBuff,&dwLen,NULL); if (!rc) { DWORD res = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == res) { delete [] pBuff; pBuff = new TCHAR[dwLen]; rc = HttpQueryInfo(hRequest,HTTP_QUERY_STATUS_TEXT,pBuff,&dwLen,NULL); if (!rc) _tcscpy(pBuff,_T("Unknown")); } else _tcscpy(pBuff,_T("Unknown")); } pCtx->m_StatusText = pBuff; delete [] pBuff; if (HTTP_STATUS_OK != pCtx->m_dwStatus) { TCHAR errBuff[MAX_PATH] = _T(""); wsprintf(errBuff,_T("HTTP Status Code: %d, Reason: "),pCtx->m_dwStatus); pCtx->m_Error = errBuff; pCtx->m_Error += pCtx->m_StatusText; pCtx->m_bSuccess = false; } } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { PBYTE buffer[255]; DWORD dwRead = 0; delete [] pCtx->m_pResponseBody; pCtx->m_pResponseBody = NULL; pCtx->m_lResponseBodyLength = 0; while (rc = InternetReadFile(hRequest,buffer,255,&dwRead)) { if (!rc || pCtx->m_bAbort || 0 == dwRead) break; PBYTE tmp = new BYTE[pCtx->m_lResponseBodyLength + dwRead]; if (pCtx->m_pResponseBody) { memcpy(tmp,pCtx->m_pResponseBody,pCtx->m_lResponseBodyLength); delete [] pCtx->m_pResponseBody; } memcpy(tmp+pCtx->m_lResponseBodyLength,buffer,dwRead); pCtx->m_pResponseBody = tmp; pCtx->m_lResponseBodyLength += dwRead; } if (!rc) { DWORD res = GetLastError(); pCtx->m_Error = _T("Error reading response: ") + CXMLHttpRequest::GetErrorMsg(res); pCtx->m_bSuccess = false; } } if (hRequest != NULL) InternetCloseHandle(hRequest); if (hConnect != NULL) InternetCloseHandle(hConnect); if (hOpen) InternetCloseHandle(hOpen); if (!pCtx->m_bAbort && pCtx->m_bAsync) ::PostMessage(pCtx->m_hWnd,MSG_READY_STATE_CHANGE,4,0); return 0;}HWND CXMLHttpRequest::GetParentWindow(){ HWND hWnd = GetDesktopWindow(); CComPtr<IServiceProvider> pSP; HRESULT hr = GetSite(IID_IServiceProvider, reinterpret_cast<LPVOID *> (&pSP)); if (S_OK != hr) return hWnd; CComPtr<IWebBrowser2> pWB; hr = pSP->QueryService(SID_SWebBrowserApp,IID_IWebBrowser2, reinterpret_cast<LPVOID *> (&pWB)); if (S_OK != hr) return hWnd; long lWnd = 0; hr = pWB->get_HWND(&lWnd); if (S_OK != hr) return hWnd; return reinterpret_cast<HWND> (lWnd);}void CALLBACK CXMLHttpRequest::InternetStatusCallback(HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength){ ATLTRACE(_T("CXMLHttpRequest::InternetStatusCallback - dwInternetStatus %d\n"),dwInternetStatus);} STDMETHODIMP CXMLHttpRequest::abort(){ ATLTRACE(_T("CXMLHttpRequest::abort\n")); m_bAbort = true; return S_OK;} STDMETHODIMP CXMLHttpRequest::get_status(long * plStatus){ ATLTRACE(_T("CXMLHttpRequest::get_status\n")); if (NULL == plStatus) return E_POINTER; *plStatus = 0; // check if there is a send active if (NULL != m_hThread) { DWORD exitCode = 0; BOOL rc = ::GetExitCodeThread(m_hThread, &exitCode); if (!rc || STILL_ACTIVE == exitCode) return E_PENDING; ::CloseHandle(m_hThread); m_hThread = NULL; } *plStatus = m_dwStatus; return S_OK;}STDMETHODIMP CXMLHttpRequest::get_statusText( BSTR * pbstrStatus){ ATLTRACE(_T("CXMLHttpRequest::get_statusText\n")); if (NULL == pbstrStatus) return E_POINTER; *pbstrStatus = NULL; // check if there is a send active if (NULL != m_hThread) { DWORD exitCode = 0; BOOL rc = ::GetExitCodeThread(m_hThread, &exitCode); if (!rc || STILL_ACTIVE == exitCode) return E_PENDING; ::CloseHandle(m_hThread); m_hThread = NULL; } *pbstrStatus = m_StatusText.copy(); return S_OK;}STDMETHODIMP CXMLHttpRequest::get_responseXML(IDispatch **ppBody){ ATLTRACE(_T("CXMLHttpRequest::get_responseXML\n")); if (NULL == ppBody) return E_POINTER; *ppBody = NULL; // check if there is a send active if (NULL != m_hThread) { DWORD exitCode = 0; BOOL rc = ::GetExitCodeThread(m_hThread, &exitCode); if (!rc || STILL_ACTIVE == exitCode) return E_PENDING; ::CloseHandle(m_hThread); m_hThread = NULL; } BSTR text = NULL; HRESULT hr = get_responseText(&text); if (S_OK != hr || NULL == text) return hr; CXMLDOMDocumentObj *pObj = NULL; hr = CXMLDOMDocumentObj::CreateInstance(&pObj); if (S_OK == hr) { pObj->AddRef(); VARIANT_BOOL isSuccessful = VARIANT_FALSE; hr = pObj->loadXML(text, &isSuccessful); if (S_OK == hr && VARIANT_TRUE == isSuccessful) { *ppBody = pObj; (*ppBody)->AddRef(); } pObj->Release(); } ::SysFreeString(text); return hr;}STDMETHODIMP CXMLHttpRequest::get_responseText(BSTR *pVal){ ATLTRACE(_T("CXMLHttpRequest::get_responseText\n")); if (NULL == pVal) return E_POINTER; *pVal = NULL; // check if there is a send active if (NULL != m_hThread) { DWORD exitCode = 0; BOOL rc = ::GetExitCodeThread(m_hThread, &exitCode); if (!rc || STILL_ACTIVE == exitCode) return E_PENDING; ::CloseHandle(m_hThread); m_hThread = NULL; } if (NULL == m_pResponseBody) return S_OK; TCHAR *psz = new TCHAR[m_lResponseBodyLength+1]; ZeroMemory(psz,m_lResponseBodyLength+1); CopyMemory(psz,m_pResponseBody,m_lResponseBodyLength); *pVal = SysAllocStringByteLen(psz,m_lResponseBodyLength); delete [] psz; return S_OK;}STDMETHODIMP CXMLHttpRequest::get_responseBody(VARIANT *pVal){ ATLTRACE(_T("CXMLHttpRequest::get_responseBody\n")); if (NULL == pVal) return E_POINTER; ::VariantInit(pVal); V_VT(pVal) = VT_NULL; // check if there is a send active if (NULL != m_hThread) { DWORD exitCode = 0; BOOL rc = ::GetExitCodeThread(m_hThread, &exitCode); if (!rc || STILL_ACTIVE == exitCode) return E_PENDING; ::CloseHandle(m_hThread); m_hThread = NULL; } if (NULL == m_pResponseBody) return S_OK; return CXMLHttpRequest::InitializeVarFromByte(*pVal, m_pResponseBody,m_lResponseBodyLength);}STDMETHODIMP CXMLHttpRequest::get_responseStream(VARIANT *pVal){ ATLTRACE(_T("CXMLHttpRequest::get_responseStream\n")); if (NULL == pVal) return E_POINTER; ::VariantInit(pVal); V_VT(pVal) = VT_NULL; // check if there is a send active if (NULL != m_hThread) { DWORD exitCode = 0; BOOL rc = ::GetExitCodeThread(m_hThread, &exitCode); if (!rc || STILL_ACTIVE == exitCode) return E_PENDING; ::CloseHandle(m_hThread); m_hThread = NULL; } if (NULL == m_pResponseBody) return S_OK; //Create an IStream from global memory CComPtr<IStream> pStm; HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm); if (S_OK != hr) return hr; hr = pStm->Write(m_pResponseBody, m_lResponseBodyLength, NULL); if (S_OK != hr) return hr; LARGE_INTEGER dlibMove; memset(&dlibMove,0,sizeof(LARGE_INTEGER)); hr = pStm->Seek(dlibMove,STREAM_SEEK_SET,NULL); if (S_OK != hr) return hr; V_VT(pVal) = VT_UNKNOWN; V_UNKNOWN(pVal) = pStm.Detach(); return S_OK;}STDMETHODIMP CXMLHttpRequest::get_readyState(long *pVal){ ATLTRACE(_T("CXMLHttpRequest::get_readyState\n")); if (NULL == pVal) return E_POINTER; *pVal = m_lReadyState; return S_OK;}STDMETHODIMP CXMLHttpRequest::put_onreadystatechange(IDispatch * pReadyStateSink){ ATLTRACE(_T("CXMLHttpRequest::put_onreadystatechange\n")); if (m_pOnReadyStateChange != NULL) { m_pOnReadyStateChange->Release(); m_pOnReadyStateChange = NULL; } m_pOnReadyStateChange = pReadyStateSink; if (m_pOnReadyStateChange != NULL) m_pOnReadyStateChange->AddRef(); return S_OK;}_bstr_t CXMLHttpRequest::GetErrorMsg(DWORD rc){ _bstr_t msg(_T("")); TCHAR *lpBuffer = NULL; if (ERROR_INTERNET_EXTENDED_ERROR == rc) { DWORD dwError = 0; DWORD dwLength = 0; InternetGetLastResponseInfo (&dwError, NULL, &dwLength); if (dwLength > 0) { lpBuffer = (TCHAR *) LocalAlloc(LPTR,dwLength); if (!lpBuffer) { msg = _T("Unable to allocate memory to display Internet extended error: "); rc = GetLastError(); } else { if (!InternetGetLastResponseInfo(&dwError,lpBuffer,&dwLength)) { msg = _T("Unable to get Internet extended error: "); rc = GetLastError(); LocalFree(lpBuffer); } else { int len = lstrlen(lpBuffer); for (int i=0; i < len; ++i) { if (_istcntrl(lpBuffer[i])) lpBuffer[i] = _T(' '); } msg = lpBuffer; LocalFree(lpBuffer); return msg; } } } } lpBuffer = NULL; HMODULE hModule = NULL; // default to system source if (rc >= INTERNET_ERROR_BASE) hModule = LoadLibraryEx(_T("wininet.dll"),NULL,LOAD_LIBRARY_AS_DATAFILE); ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | ((hModule != NULL) ? FORMAT_MESSAGE_FROM_HMODULE : 0), hModule, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), (LPTSTR)&lpBuffer, 0, NULL); if (lpBuffer) { int len = lstrlen(lpBuffer); for (int i=0; i < len; ++i) { if (_istcntrl(lpBuffer[i])) lpBuffer[i] = _T(' '); } } msg += lpBuffer; LocalFree(lpBuffer); if (hModule != NULL) FreeLibrary(hModule); return msg;}HRESULT CXMLHttpRequest::InitializeVarFromByte(VARIANT &varOut, const PBYTE pByte, long lSize){ ::VariantInit(&varOut); V_VT(&varOut) = VT_NULL; HRESULT hr = S_OK; SAFEARRAYBOUND rgsabound[1]; rgsabound[0].cElements = lSize; rgsabound[0].lLbound = 0; SAFEARRAY *psa = ::SafeArrayCreate( VT_VARIANT, 1, rgsabound); if (psa == NULL) return E_FAIL; if (pByte != NULL) { long ix[1]; for (ULONG i = 0; i < rgsabound[0].cElements; ++i) { ix[0] = i; VARIANT var; ::VariantInit(&var); V_VT(&var) = VT_UI1; V_UI1(&var) = pByte[i]; hr = ::SafeArrayPutElement(psa, ix, &var); if (S_OK != hr) { ::SafeArrayDestroy(psa); break; } } } if (S_OK == hr) { V_VT(&varOut) = VT_ARRAY | VT_VARIANT; V_ARRAY(&varOut) = psa; } return hr;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?