290 lines
8.4 KiB
C
290 lines
8.4 KiB
C
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// SOAPHelper.h
|
||
|
//
|
||
|
// Helper functions for SOAP
|
||
|
//
|
||
|
// This implementation aims to be SOAP 1.1 compliant. The spec can be
|
||
|
// found here:
|
||
|
// http://msdn.microsoft.com/xml/general/soapspec.asp
|
||
|
//
|
||
|
// Author: Wei Jiang
|
||
|
//
|
||
|
// 10/12/00 weijiang created
|
||
|
// 01/10/01 weijiang update for SOAP 1.1, code clean up
|
||
|
// 01/23/01 jeffstei Rename and add GetSOAPMethod(...)
|
||
|
//
|
||
|
// Copyright <cp> 2000-2001 Microsoft Corporation. All Rights Reserved.
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
#if !defined(_SOAPHELPER_H_)
|
||
|
#define _SOAPHELPER_H_
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#ifndef Assert
|
||
|
#define Assert ATLASSERT
|
||
|
#endif
|
||
|
|
||
|
// SOAP content type
|
||
|
#define CZ_SOAP_CONTENTTYPE "text/xml; charset=\"utf-8\""
|
||
|
#define CZ_SOAP_CONTENTTYPEBASIC "text/xml"
|
||
|
|
||
|
|
||
|
#define ERR_XML_FORMAT "Incorrect xml data"
|
||
|
#define ERR_SOAP_ENVELOPE "Incorrect SOAP envelope, or SOAP envelope is missing "
|
||
|
#define ERR_SOAP_BODY "Incorrect SOAP body, or SOAP body is missing"
|
||
|
#define ERR_SOAP_METHOD "Incorrect method, or SOAP method is missing"
|
||
|
#define ERR_SOAP_PARAM "Incorrect parameter: "
|
||
|
|
||
|
|
||
|
#define SOAP_FAULT "Fault"
|
||
|
#define SOAP_FAULT_CODE "faultcode"
|
||
|
#define SOAP_FAULT_STRING "faultstring"
|
||
|
#define SOAP_FAULT_DETAIL "detail"
|
||
|
|
||
|
#define SOAP_ENV_URI "http://schemas.xmlsoap.org/soap/envelope/"
|
||
|
#define SOAP_ENC_URI "http://schemas.xmlsoap.org/soap/encoding/"
|
||
|
#define SOAP_ENV_NS "SOAP-ENV"
|
||
|
#define SOAP_ENV_NAME "Envelope"
|
||
|
#define SOAP_ENV_BODY "Body"
|
||
|
|
||
|
#define SOAP_ENV_NAME_TAG SOAP_ENV_NS ":" SOAP_ENV_NAME
|
||
|
#define SOAP_ENV_BODY_TAG SOAP_ENV_NS ":" SOAP_ENV_BODY
|
||
|
|
||
|
#define XML_V10 "<?xml version=\"1.0\"?>"
|
||
|
|
||
|
/*
|
||
|
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||
|
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/
|
||
|
*/
|
||
|
#define SOAP_NS_URI "xmlns:" SOAP_ENV_NS "=\'" SOAP_ENV_URI "\'\n" \
|
||
|
SOAP_ENV_NS ":encodingStyle=\'" SOAP_ENC_URI "\'"
|
||
|
|
||
|
// change string to unicode
|
||
|
#define W(n) __WIDECHAR__(n)
|
||
|
#define __WIDECHAR__(n) L ## n
|
||
|
|
||
|
// open & close tag string macros
|
||
|
#define OPENTAG_NS(nm,ns) "<" ## nm ## " " ## ns ">"
|
||
|
#define OPENTAG(t) "<" ## t ## ">"
|
||
|
#define CLOSETAG(t) "</" ## t ## ">"
|
||
|
|
||
|
/*
|
||
|
<?xml version="1.0"?>\r\n
|
||
|
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" SOAP:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\r\n
|
||
|
<SOAP:Body>
|
||
|
*/
|
||
|
#define SOAPEnvelope_Body_Open XML_V10 OPENTAG_NS(SOAP_ENV_NAME_TAG, SOAP_NS_URI) OPENTAG(SOAP_ENV_BODY_TAG)
|
||
|
|
||
|
/*
|
||
|
</SOAP:Body>
|
||
|
</SOAP:Envelope>
|
||
|
*/
|
||
|
#define SOAPEnvelope_Body_Close CLOSETAG(SOAP_ENV_BODY_TAG) CLOSETAG(SOAP_ENV_NAME_TAG)
|
||
|
|
||
|
|
||
|
class SOAPHelper;
|
||
|
|
||
|
#define MAX_PARAM_LENGTH 64
|
||
|
#define MAX_PARAM_COUNT 64
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CLASS ParamMap
|
||
|
//
|
||
|
// Class to contain a mapping of parameters read from a SOAP Request and written
|
||
|
// to a response.
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////////////
|
||
|
class ParamMap
|
||
|
{
|
||
|
private:
|
||
|
friend class SOAPHelper;
|
||
|
struct Param
|
||
|
{
|
||
|
WCHAR name[MAX_PARAM_LENGTH + 1];
|
||
|
VARIANT value;
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
UINT Size() { return cnt;};
|
||
|
BOOL Get(UINT index, LPCWSTR* pName, VARIANT** pVal)
|
||
|
{
|
||
|
if ( index >= cnt ) return FALSE;
|
||
|
|
||
|
*pName = params[index].name;
|
||
|
*pVal = ¶ms[index].value;
|
||
|
|
||
|
return TRUE;
|
||
|
};
|
||
|
|
||
|
VARIANT* Find(LPCWSTR name)
|
||
|
{
|
||
|
for(UINT i = 0; i < cnt; ++i)
|
||
|
{
|
||
|
if(wcsncmp(params[i].name, name, MAX_PARAM_LENGTH) == 0)
|
||
|
return ¶ms[i].value;
|
||
|
|
||
|
};
|
||
|
|
||
|
return NULL;
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
// note: parameter pVar will be skin level copied, NOT VariantCopied ...
|
||
|
// note: parameter pVar will be set to VT_EMPTY after this call
|
||
|
HRESULT AddParam(LPCWSTR name, VARIANT* pVar)
|
||
|
{
|
||
|
Assert(name);
|
||
|
Assert(pVar);
|
||
|
|
||
|
if(cnt >= MAX_PARAM_COUNT) return S_FALSE;
|
||
|
|
||
|
wcsncpy(params[cnt].name, name, MAX_PARAM_LENGTH);
|
||
|
params[cnt].value = *pVar;
|
||
|
++cnt;
|
||
|
|
||
|
VariantInit(pVar);
|
||
|
|
||
|
return S_OK;
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
ParamMap() : cnt(0) { };
|
||
|
virtual ~ParamMap()
|
||
|
{
|
||
|
for (UINT i = 0; i < cnt; ++i)
|
||
|
{
|
||
|
VariantClear(¶ms[i].value);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
private:
|
||
|
Param params[MAX_PARAM_COUNT];
|
||
|
UINT cnt;
|
||
|
};
|
||
|
///////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CLASS SOAPHelper
|
||
|
//
|
||
|
// Class of static methods and definitions to help in processing
|
||
|
// SOAP requests and responses
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////////////
|
||
|
class SOAPHelper
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
//
|
||
|
// GetParameters(...)
|
||
|
//
|
||
|
// retrieve the parameters from a given ECB
|
||
|
//the method name, content type are checked
|
||
|
//
|
||
|
static HRESULT GetParameters(IN EXTENSION_CONTROL_BLOCK* pECB,
|
||
|
IN LPCWSTR pcwszMethodName,
|
||
|
OUT ParamMap& mapParams,
|
||
|
OUT VARIANT_BOOL& bParsedOK,
|
||
|
OUT CStringW& strParseErr);
|
||
|
|
||
|
//
|
||
|
// GenerateResponse(...)
|
||
|
//
|
||
|
// generate soap response package with given paramters
|
||
|
// content type is returned from this call
|
||
|
//
|
||
|
static HRESULT GenerateResponse(
|
||
|
IN LPCWSTR pcwszMethodName,
|
||
|
IN ParamMap& mapParams,
|
||
|
OUT CHeapPtr<char>& body,
|
||
|
OUT CStringA& contentType);
|
||
|
|
||
|
|
||
|
//
|
||
|
// GenerateFaultSOAPEnvelope (...)
|
||
|
//
|
||
|
// generate soap fault package with the passed in parameters.
|
||
|
//
|
||
|
static HRESULT GenerateFaultSOAPEnvelope(IN DWORD dwFaultCode,
|
||
|
IN LPCSTR pcszFaultString,
|
||
|
IN LPCSTR pcszFaultActor,
|
||
|
IN LPCSTR pcszDetail,
|
||
|
OUT CStringA& faultEnvelope);
|
||
|
|
||
|
//
|
||
|
// GetFaultSOAPEnvelopeDetail(...)
|
||
|
//
|
||
|
// get error details from a soap fault package
|
||
|
//
|
||
|
static HRESULT GetFaultSOAPEnvelopeDetail(IN BSTR faultEnvelope,
|
||
|
OUT CStringW& faultCode,
|
||
|
OUT CStringW& faultString,
|
||
|
OUT CStringW& faultDetail);
|
||
|
|
||
|
//
|
||
|
// GenerateSOAPEnvelope(...)
|
||
|
//
|
||
|
static HRESULT GenerateSOAPEnvelope(ParamMap& mapParams,
|
||
|
LPCWSTR pcwszMethodName,
|
||
|
BSTR* envelope);
|
||
|
|
||
|
//
|
||
|
// ParseSOAPEnvelope(...)
|
||
|
//
|
||
|
static HRESULT ParseSOAPEnvelope(ParamMap& mapParams,
|
||
|
LPCWSTR pcwszMethodName,
|
||
|
BSTR bstrSoapEnvelope,
|
||
|
VARIANT_BOOL* pbParsedOK,
|
||
|
BSTR* pbstrErrorMsg);
|
||
|
//
|
||
|
// GetSOAPMethod(...)
|
||
|
//
|
||
|
// Returns the full SOAP method name.
|
||
|
//
|
||
|
static HRESULT GetSOAPMethod(EXTENSION_CONTROL_BLOCK* pECB,
|
||
|
LPCSTR path,
|
||
|
CStringW& out_cszMethod);
|
||
|
|
||
|
//
|
||
|
// GetShortSOAPMethod(...)
|
||
|
//
|
||
|
// Returns the abbreviated method name, all in lowercase. The abbreviated name consists
|
||
|
// of everything in the full name (see above function) after the "#"
|
||
|
//
|
||
|
static HRESULT GetShortSOAPMethod(EXTENSION_CONTROL_BLOCK* pECB,
|
||
|
LPCSTR path,
|
||
|
CStringW& out_cszMethod);
|
||
|
|
||
|
//
|
||
|
// CheckSOAPMethod(...)
|
||
|
//
|
||
|
// Checks to determine presence of the passed in method.
|
||
|
// pRet will contain TRUE of the method exists, and FALSE otherwize.
|
||
|
//
|
||
|
static HRESULT CheckSOAPMethod(EXTENSION_CONTROL_BLOCK* pECB,
|
||
|
LPCSTR pcszMethod,
|
||
|
LPCSTR pcszPath,
|
||
|
BOOL* pRet);
|
||
|
|
||
|
// SOAP Fault codes. Taken from SOAP 1.1 specification.
|
||
|
// The numbers associated are arbitrary (i think). Either way
|
||
|
// they're never shown to the user
|
||
|
static const UINT SOAP_FAULT_NONE = 0; // This is NOT a SOAP code, but we needed an "unset" value.
|
||
|
static const UINT SOAP_FAULT_VERSIONMISMATCH = 100;
|
||
|
static const UINT SOAP_FAULT_MUSTUNDERSTAND = 200;
|
||
|
static const UINT SOAP_FAULT_CLIENT = 300;
|
||
|
static const UINT SOAP_FAULT_SERVER = 400;
|
||
|
|
||
|
};
|
||
|
///////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#endif //!defined(_SOAPHELPER_H_)
|
||
|
|
||
|
|