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 + -
显示快捷键?