xmlhttprequest.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,107 行 · 第 1/2 页
CPP
1,107 行
/* * Copyright 1999-2000,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Log: XMLHTTPRequest.cpp,v $ * Revision 1.2 2004/09/08 13:55:36 peiyongz * Apache License Version 2.0 * * Revision 1.1.1.1 2002/02/01 22:21:42 peiyongz * sane_include * * Revision 1.3 2000/06/03 00:29:03 andyh * COM Wrapper changes from Curt Arnold * * Revision 1.2 2000/03/30 02:00:09 abagchi * Initial checkin of working code with Copyright Notice * */#include "stdafx.h"#include "xml4com.h"#include "XMLHttpRequest.h"#include "XMLDOMDocument.h"// I need to make sure the file is registered with long filenamesHRESULT WINAPI CXMLHttpRequest::UpdateRegistry(BOOL bRegister){ USES_CONVERSION; TCHAR file[MAX_PATH]; if (::GetModuleFileName(_Module.m_hInst, file, MAX_PATH)) { WIN32_FIND_DATA d; memset(&d,0,sizeof(WIN32_FIND_DATA)); HANDLE h = FindFirstFile(file,&d); if (h != INVALID_HANDLE_VALUE) { TCHAR *name = _tcsrchr(file,_T('\\')); TCHAR newFile[MAX_PATH] = _T(""); _tcsncpy(newFile,file,name-file); _tcscat(newFile,_T("\\")); _tcscat(newFile,d.cFileName); FindClose(h); _ATL_REGMAP_ENTRY regmap[2] = {{NULL,NULL},{NULL,NULL}}; regmap[0].szKey = OLESTR("XMLMODULE"); regmap[0].szData = T2OLE(newFile); return _Module.UpdateRegistryFromResource((UINT) IDR_XMLHTTPREQUEST, bRegister,regmap); } } return E_FAIL;}CXMLHttpRequest::CXMLHttpRequest() :m_pOnReadyStateChange (NULL) ,m_bAbort (false) ,m_hThread (NULL) ,m_lReadyState (0) ,m_bAsync (false) ,m_Method (_T("")) ,m_HostName (_T("")) ,m_Port (INTERNET_DEFAULT_HTTP_PORT) ,m_URLPath (_T("")) ,m_User (_T("")) ,m_Password (_T("")) ,m_dwStatus (0) ,m_StatusText (_T("")) ,m_ResponseHeaders (_T("")) ,m_HwndParent (NULL) ,m_pBody (NULL) ,m_lBodyLength (0) ,m_pResponseBody (NULL) ,m_lResponseBodyLength (0) ,m_Error (_T("")) ,m_bSuccess (true){}HRESULT CXMLHttpRequest::FinalConstruct(){ // create monitor window RECT rc; memset(&rc,0,sizeof(RECT)); if (NULL == Create(NULL, rc, _T("XML HTTP Request Monitor Window"), 0)) return E_FAIL; return S_OK;}void CXMLHttpRequest::FinalRelease(){ if (NULL != m_hThread) { m_bAbort = true; ::WaitForSingleObject(m_hThread, INFINITE); ::CloseHandle(m_hThread); m_hThread = NULL; } if (m_pOnReadyStateChange != NULL) { m_pOnReadyStateChange->Release(); m_pOnReadyStateChange = NULL; } DestroyWindow(); delete [] m_pBody; m_pBody = NULL; m_lBodyLength = 0; delete [] m_pResponseBody; m_pResponseBody = NULL; m_lResponseBodyLength = 0;}LRESULT CXMLHttpRequest::OnReadyStateChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){ ATLTRACE(_T("CXMLHttpRequest::OnReadyStateChange\n")); bHandled = TRUE; m_lReadyState = wParam; if (NULL != m_pOnReadyStateChange) { CComVariant varResult; DISPPARAMS disp = { NULL, NULL, 0, 0 }; m_pOnReadyStateChange->Invoke(DISPID_VALUE, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL); } return 1L;}STDMETHODIMP CXMLHttpRequest::InterfaceSupportsErrorInfo(REFIID riid){ if (IsEqualGUID(IID_IXMLHttpRequest,riid)) return S_OK; return S_FALSE;}STDMETHODIMP CXMLHttpRequest::open(BSTR bstrMethod, BSTR bstrUrl,VARIANT varAsync,VARIANT bstrUser,VARIANT bstrPassword){ ATLTRACE(_T("CXMLHttpRequest::open\n")); // do not open 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_FAIL; ::CloseHandle(m_hThread); m_hThread = NULL; } if (V_VT(&varAsync) != VT_BOOL) return E_INVALIDARG; _bstr_t method = bstrMethod; if (0 == method.length()) return E_INVALIDARG; _bstr_t url = bstrUrl; if (0 == url.length()) return E_INVALIDARG; TCHAR hostName[INTERNET_MAX_PATH_LENGTH] = _T(""); TCHAR strPathName[INTERNET_MAX_PATH_LENGTH] = _T(""); URL_COMPONENTS urlComponents; memset(&urlComponents, 0, sizeof(URL_COMPONENTS)); urlComponents.dwStructSize = sizeof(URL_COMPONENTS); urlComponents.lpszHostName = hostName; urlComponents.dwHostNameLength = INTERNET_MAX_PATH_LENGTH; urlComponents.lpszUrlPath = strPathName; urlComponents.dwUrlPathLength = INTERNET_MAX_PATH_LENGTH; if (!InternetCrackUrl(url, url.length(), 0, &urlComponents)) return E_INVALIDARG; m_Method = method; m_HostName = hostName; if (urlComponents.nPort != 0) m_Port = urlComponents.nPort; m_URLPath = strPathName; m_bAsync = (VARIANT_TRUE == V_BOOL(&varAsync)) ? true : false; if (VT_BSTR == V_VT(&bstrUser)) m_User = V_BSTR(&bstrUser); else m_User = _T(""); if (VT_BSTR == V_VT(&bstrPassword) && m_User.length() > 0) m_Password = V_BSTR(&bstrPassword); else m_Password = _T(""); return S_OK;}STDMETHODIMP CXMLHttpRequest::setRequestHeader(BSTR bstrHeader, BSTR bstrValue){ ATLTRACE(_T("CXMLHttpRequest::setRequestHeader\n")); if (NULL == bstrHeader || NULL == bstrValue) return E_INVALIDARG; // 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; } m_RequestHeaderMap.Remove(bstrHeader); m_RequestHeaderMap.Add(bstrHeader,bstrValue); return S_OK;}STDMETHODIMP CXMLHttpRequest::getResponseHeader(BSTR bstrHeader, BSTR * pbstrValue){ ATLTRACE(_T("CXMLHttpRequest::getResponseHeader\n")); if (NULL == pbstrValue) return E_POINTER; *pbstrValue = NULL; if (NULL == bstrHeader) return E_INVALIDARG; // 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 (0 == m_ResponseHeaders.length()) return S_FALSE; _bstr_t value; _bstr_t header(bstrHeader); header += _T(": "); _tcslwr(header); TCHAR *pHeaders = new TCHAR[m_ResponseHeaders.length() + sizeof(TCHAR)]; _tcscpy(pHeaders,m_ResponseHeaders); _tcslwr(pHeaders); TCHAR *pStart = _tcsstr(pHeaders,header); if (pStart) { pStart += header.length(); TCHAR *pEnd = _tcsstr(pStart,_T("\r\n")); if (pEnd) { TCHAR *pHeader = new TCHAR[pEnd-pStart + sizeof(TCHAR)]; _tcsncpy(pHeader,static_cast<LPCTSTR> (m_ResponseHeaders) + (pStart-pHeaders),pEnd-pStart); value = pHeader; delete [] pHeader; } } delete[] pHeaders; if (0 == value.length()) return S_FALSE; *pbstrValue = value.copy(); return S_OK;}STDMETHODIMP CXMLHttpRequest::getAllResponseHeaders(BSTR * pbstrHeaders){ ATLTRACE(_T("CXMLHttpRequest::getAllResponseHeaders\n")); if (NULL == pbstrHeaders) return E_POINTER; *pbstrHeaders = NULL; if (NULL == pbstrHeaders) return E_INVALIDARG; // 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; } *pbstrHeaders = m_ResponseHeaders.copy(); return S_OK;}STDMETHODIMP CXMLHttpRequest::send(VARIANT varBody){ ATLTRACE(_T("CXMLHttpRequest::send\n")); if (V_VT(&varBody) != VT_BSTR && V_VT(&varBody) != VT_DISPATCH && V_VT(&varBody) != (VT_ARRAY | VT_VARIANT) && V_VT(&varBody) != (VT_ARRAY | VT_UI1) && V_VT(&varBody) != VT_UNKNOWN) return E_INVALIDARG; // do not start another thread if there is another 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; } HRESULT hr = S_OK; m_bSuccess = true; m_bAbort = false; delete [] m_pBody; m_pBody = NULL; m_lBodyLength = 0; delete [] m_pResponseBody; m_pResponseBody = NULL; m_lResponseBodyLength = 0; m_dwStatus = 0; m_StatusText = _T(""); m_ResponseHeaders = _T(""); if (V_VT(&varBody) == VT_BSTR) { _bstr_t body = V_BSTR(&varBody); m_lBodyLength = body.length() + 1; m_pBody = new BYTE[m_lBodyLength]; memset(m_pBody,0,m_lBodyLength); memcpy(m_pBody,static_cast<char*> (body),body.length()); } else if (V_VT(&varBody) == VT_UNKNOWN) { CComQIPtr<IStream,&IID_IStream> pS(V_UNKNOWN(&varBody)); if (!pS) return E_INVALIDARG; CComBSTR b; hr = b.ReadFromStream(pS); if (S_OK != hr) return hr; _bstr_t body = b; m_lBodyLength = body.length() + 1; m_pBody = new BYTE[m_lBodyLength]; memset(m_pBody,0,m_lBodyLength); memcpy(m_pBody,static_cast<char*> (body),body.length()); } else if (V_VT(&varBody) == VT_DISPATCH) { CComQIPtr<IXMLDOMDocument,&IID_IXMLDOMDocument> pDoc(V_DISPATCH(&varBody)); if (!pDoc) return E_INVALIDARG; BSTR b = NULL; hr = pDoc->get_xml(&b); if (S_OK != hr) return hr; _bstr_t body = b; ::SysFreeString(b); m_lBodyLength = body.length() + 1; m_pBody = new BYTE[m_lBodyLength]; memset(m_pBody,0,m_lBodyLength); memcpy(m_pBody,static_cast<char*> (body),body.length()); } else if (V_VT(&varBody) == (VT_ARRAY | VT_VARIANT)) { SAFEARRAY *pArray = reinterpret_cast<SAFEARRAY *> (varBody.byref); if (NULL == pArray) return E_INVALIDARG; long lLBoundVar = 0; long lUBoundVar = 0; UINT dims = ::SafeArrayGetDim(pArray); if (dims == 0) return E_INVALIDARG; hr = ::SafeArrayGetLBound(pArray, dims, &lLBoundVar); if (S_OK != hr) return hr; hr = ::SafeArrayGetUBound(pArray, dims, &lUBoundVar); if (S_OK != hr) return hr; if (lUBoundVar >= lLBoundVar) { VARIANT *pIndex = NULL; hr = ::SafeArrayAccessData(pArray, reinterpret_cast<void **> (&pIndex)); if (S_OK != hr) return hr; m_lBodyLength = lUBoundVar-lLBoundVar+1; m_pBody = new BYTE[m_lBodyLength]; for (long i = 0; i <= lUBoundVar-lLBoundVar; ++i) { VARIANT var = pIndex[i]; if (V_VT(&var) != VT_UI1) { hr = E_INVALIDARG; break; } m_pBody[i] = V_UI1(&var); } ::SafeArrayUnaccessData(pArray); if (S_OK != hr) { delete [] m_pBody; m_pBody = NULL; m_lBodyLength = 0; return hr; } } } else if (V_VT(&varBody) == (VT_ARRAY | VT_UI1)) { SAFEARRAY *pArray = reinterpret_cast<SAFEARRAY *> (varBody.byref); if (NULL == pArray) return E_INVALIDARG; long lLBoundVar = 0; long lUBoundVar = 0; UINT dims = ::SafeArrayGetDim(pArray); if (dims == 0) return E_INVALIDARG; hr = ::SafeArrayGetLBound(pArray, dims, &lLBoundVar); if (S_OK != hr) return hr; hr = ::SafeArrayGetUBound(pArray, dims, &lUBoundVar); if (S_OK != hr) return hr; if (lUBoundVar >= lLBoundVar) { BYTE *pIndex = NULL; hr = ::SafeArrayAccessData(pArray, reinterpret_cast<void **> (&pIndex)); if (S_OK != hr) return hr; m_lBodyLength = lUBoundVar-lLBoundVar+1; m_pBody = new BYTE[m_lBodyLength]; for (long i = 0; i <= lUBoundVar-lLBoundVar; ++i) m_pBody[i] = pIndex[i]; ::SafeArrayUnaccessData(pArray); } } m_HwndParent = GetParentWindow(); UINT nthreadID = 0; m_hThread = reinterpret_cast<HANDLE> (_beginthreadex(NULL, 0, CXMLHttpRequest::SendThread, (void *) this, 0, &nthreadID)); if (NULL == m_hThread) return E_FAIL; if (m_bAsync) return S_OK; bool bWait = true; while (bWait) { DWORD dwEvt = MsgWaitForMultipleObjects(1,&m_hThread,FALSE,INFINITE,QS_ALLINPUT); switch(dwEvt) { case WAIT_OBJECT_0: bWait = false; break; case WAIT_OBJECT_0 + 1: { MSG msg; while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (WM_CLOSE == msg.message || WM_QUIT == msg.message) { bWait = false; m_bAbort = true; break; } else { PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); TranslateMessage(&msg); DispatchMessage(&msg); } } break; } default: m_bAbort = true; bWait = false; break; } } return S_OK;}UINT APIENTRY CXMLHttpRequest::SendThread(void *pParm){ ATLTRACE(_T("CXMLHttpRequest::SendThread\n")); CXMLHttpRequest *pCtx = reinterpret_cast<CXMLHttpRequest *> (pParm); if (NULL == pCtx) return 0; HINTERNET hOpen = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; hOpen = InternetOpen(_T("XMLHTTP/1.0"),INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0); if (NULL == hOpen) { DWORD res = GetLastError(); pCtx->m_Error = CXMLHttpRequest::GetErrorMsg(res); pCtx->m_bSuccess = false; } if (!pCtx->m_bAbort && pCtx->m_bSuccess) { if (INTERNET_INVALID_STATUS_CALLBACK == InternetSetStatusCallback(hOpen, CXMLHttpRequest::InternetStatusCallback)) { pCtx->m_Error = _T("Invalid Internet Status Callback function."); pCtx->m_bSuccess = false; } } bool bPromptForAuthentication = true; if (!pCtx->m_bAbort && pCtx->m_bSuccess) { LPTSTR lpszUserName = NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?