// wmwsrouter2Obj.cpp : Implementation of Cwmwsrouter2Obj // // Copyright (c) 2002 Robert Cunnings. All rights reserved. // // You may copy, modify, distribute or publish this code free of charge. // // NO WARRANTY: This software is provided AS IS, without warranty of any kind. // ////////////////////////////////////////////////////////////////////// // // Cwmwsrouter2Obj class - implementation of Web Services Routing Protocol. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "wmwsrouter2Obj.h" #include "..\soap_source\xmlparser.h" #include "..\soap_source\SOAPDIMEHTTPClient.h" #include "..\soap_source\charencode.h" #include "..\wmsoapmsg\wmsoapmsg_i.c" #include "..\wmsoapmsg\wmsoapmsg.h" #include "..\soap_source\soap.h" // this version of namespace conforms to prose in WS-Routing spec static wchar_t *g_pwszHeaderNS = L"http://schemas.xmlsoap.org/rp"; //static wchar_t *g_pwszHeaderNS = L"http://schemas.xmlsoap.org/rp/"; static char *g_pszUserAgent = "White Mesa WS-Routing Agent/1.2"; // Cwmwsrouter2Obj bool Cwmwsrouter2Obj::ReadFault(WMXMLElement *pFaultElement) { // initialize flags m_bNeedEndpoint = false; m_bNeedFound = false; m_bNeedMaxsize = false; m_bNeedMaxtime = false; m_bNeedRetryAfter = false; // get 'faultcode' element WMXMLElement *pChild = pFaultElement->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"code")); // WMXMLElement *pChild = pFaultElement->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"faultcode")); if (pChild != NULL) { m_wstrFaultcode = pChild->GetContent(); } // get 'faultreason' element pChild = pFaultElement->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"reason")); // pChild = pFaultElement->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"faultreason")); if (pChild != NULL) { m_wstrFaultreason = pChild->GetContent(); } // get 'endpoint' element pChild = pFaultElement->GetChildElement(wstring(L""), wstring(L"endpoint")); if (pChild != NULL) { m_wstrEndpoint = pChild->GetContent(); m_bNeedEndpoint = true; } // get 'found' element pChild = pFaultElement->GetChildElement(wstring(L""), wstring(L"found")); if (pChild != NULL) { ReadFoundList(pChild, m_listFound); m_bNeedFound = true; } // get 'maxsize' element pChild = pFaultElement->GetChildElement(wstring(L""), wstring(L"maxsize")); if (pChild != NULL) { m_wstrMaxsize = pChild->GetContent(); m_bNeedMaxsize = true; } // get 'maxtime' element pChild = pFaultElement->GetChildElement(wstring(L""), wstring(L"maxtime")); if (pChild != NULL) { m_wstrMaxtime = pChild->GetContent(); m_bNeedMaxtime = true; } // get 'retryAfter' element pChild = pFaultElement->GetChildElement(wstring(L""), wstring(L"retryAfter")); if (pChild != NULL) { m_wstrRetryAfter = pChild->GetContent(); m_bNeedRetryAfter = true; } return true; } bool Cwmwsrouter2Obj::PopulateAtList(list& listAtList, WMXMLElement *pListElem) { list::iterator iter; for (iter = listAtList.begin(); iter != listAtList.end(); iter++) { // "at" member element WMXMLElement *pChild = new WMXMLElement(wstring(L"at")); if (pChild != NULL) { pListElem->AddChildElement(pChild); pChild->AppendContent(*iter); } else { return false; } } return true; } WMXMLElement *Cwmwsrouter2Obj::CreateSOAPFault(int nCode, Iwmsoapmsg2 *pIwmsoapmsg) { // determine SOAP version long lSOAPVersion; pIwmsoapmsg->GetSOAPVersion(&lSOAPVersion); // create new header entry WMXMLElement *pBody = new WMXMLElement(wstring(L"SOAP-ENV:Body")); if (pBody != NULL) { if (lSOAPVersion == SOAP_VERSION_1_1) { pBody->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoapEnvelopeNS)); } else { pBody->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoap12EnvelopeNS)); } } else { return NULL; } // 'SOAP-ENV:Fault' element WMXMLElement *pFault = new WMXMLElement(wstring(L"SOAP-ENV:Fault")); if (pFault != NULL) { pBody->AddChildElement(pFault); } else { delete pBody; return NULL; } if (lSOAPVersion == SOAP_VERSION_1_1) { wstring wstrFaultcode, wstrFaultstring; if (nCode < 800) { wstrFaultcode = L"SOAP-ENV:Client"; wstrFaultstring = L"WS-Routing Sender fault."; } else { wstrFaultcode = L"SOAP-ENV:Server"; wstrFaultstring = L"WS-Routing Receiver fault."; } // 'faultcode' element WMXMLElement *pChild = new WMXMLElement(wstring(L"faultcode")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(wstrFaultcode); } else { delete pBody; return NULL; } // 'faultstring' element pChild = new WMXMLElement(wstring(L"faultstring")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(wstrFaultstring); } else { delete pBody; return NULL; } // 'faultactor' element pChild = new WMXMLElement(wstring(L"faultactor")); if (pChild != NULL) { pFault->AddChildElement(pChild); BSTR bstrNodeURI; pIwmsoapmsg->GetNodeURI(&bstrNodeURI); pChild->AppendContent(wstring(bstrNodeURI)); SysFreeString(bstrNodeURI); } else { delete pBody; return NULL; } } else { wstring wstrCode, wstrReason; if (nCode < 800) { wstrCode = L"SOAP-ENV:Sender"; wstrReason = L"WS-Routing Sender fault."; } else { wstrCode = L"SOAP-ENV:Receiver"; wstrReason = L"WS-Routing Receiver fault."; } // 'Code' element WMXMLElement *pChild = new WMXMLElement(wstring(L"SOAP-ENV:Code")); if (pChild != NULL) { WMXMLElement *pValue = new WMXMLElement(wstring(L"SOAP-ENV:Value")); pValue->AppendContent(wstrCode); pChild->AddChildElement(pValue); pFault->AddChildElement(pChild); } else { delete pBody; return NULL; } // 'Reason' element pChild = new WMXMLElement(wstring(L"SOAP-ENV:Reason")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(wstrReason); } else { delete pBody; return NULL; } // 'Node' element pChild = new WMXMLElement(wstring(L"SOAP-ENV:Node")); if (pChild != NULL) { pFault->AddChildElement(pChild); BSTR bstrNodeURI; pIwmsoapmsg->GetNodeURI(&bstrNodeURI); pChild->AppendContent(wstring(bstrNodeURI)); SysFreeString(bstrNodeURI); } else { delete pBody; return NULL; } } return pBody; } WMXMLElement *Cwmwsrouter2Obj::CreateFaultElem() { // create new header entry WMXMLElement *pFault = new WMXMLElement(wstring(L"rp:fault")); if (pFault != NULL) { pFault->SetNSPrefix(wstring(L"rp"), wstring(g_pwszHeaderNS)); } else { return NULL; } // 'faultcode' element WMXMLElement *pChild = new WMXMLElement(wstring(L"rp:code")); // WMXMLElement *pChild = new WMXMLElement(wstring(L"rp:faultcode")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(m_wstrFaultcode); } else { delete pFault; return NULL; } // 'faultreason' element pChild = new WMXMLElement(wstring(L"rp:reason")); // pChild = new WMXMLElement(wstring(L"rp:faultreason")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(m_wstrFaultreason); } else { delete pFault; return NULL; } // 'endpoint' element if (m_bNeedEndpoint == true) { pChild = new WMXMLElement(wstring(L"endpoint")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(m_wstrEndpoint); } else { delete pFault; return NULL; } } // 'found' element if (m_bNeedFound == true) { pChild = new WMXMLElement(wstring(L"found")); if (pChild != NULL) { pFault->AddChildElement(pChild); // populate with member elements if (PopulateAtList(m_listFound, pChild) == false) { delete pFault; return NULL; } } else { delete pFault; return NULL; } } // 'maxsize' element if (m_bNeedMaxsize == true) { pChild = new WMXMLElement(wstring(L"maxsize")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(m_wstrMaxsize); } else { delete pFault; return NULL; } } // 'maxtime' element if (m_bNeedMaxtime == true) { pChild = new WMXMLElement(wstring(L"maxtime")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(m_wstrMaxtime); } else { delete pFault; return NULL; } } // 'retryAfter' element if (m_bNeedRetryAfter == true) { pChild = new WMXMLElement(wstring(L"retryAfter")); if (pChild != NULL) { pFault->AddChildElement(pChild); pChild->AppendContent(m_wstrRetryAfter); } else { delete pFault; return NULL; } } return pFault; } wstring Cwmwsrouter2Obj::GenerateId() { GUID g; CoCreateGuid(&g); OLECHAR wszBuffer1[64]; OLECHAR wszBuffer2[64]; StringFromGUID2(g, wszBuffer1, 64); wszBuffer1[37] = 0; swprintf(wszBuffer2, L"uuid:%s", &wszBuffer1[1]); return wstring(wszBuffer2); } wstring Cwmwsrouter2Obj::GetFromURI() { char szBuffer[128]; CRegKey key; long lRes = key.Create(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\White Mesa Software\\White Mesa WS-RP\\1.0")); if (lRes == ERROR_SUCCESS) { unsigned long len = 128; lRes = key.QueryStringValue(_T("FromURI"), szBuffer, &len); USES_CONVERSION; if (lRes == ERROR_SUCCESS) { return wstring(A2BSTR(szBuffer)); } else { key.SetStringValue(_T("FromURI"), _T("endpoint@example.org")); } } return wstring(L"endpoint@example.org"); } bool Cwmwsrouter2Obj::PopulateViaList(list& listViaList, WMXMLElement *pListElem) { list::iterator iter; for (iter = listViaList.begin(); iter != listViaList.end(); iter++) { // "via" member element WMXMLElement *pChild = new WMXMLElement(wstring(L"rp:via")); if (pChild != NULL) { pListElem->AddChildElement(pChild); pChild->AppendContent(*iter); } else { return false; } } return true; } bool Cwmwsrouter2Obj::CheckIdentity(const wstring& wstrURL, Iwmsoapmsg2 *pIwmsoapmsg) { BSTR bstrURI; pIwmsoapmsg->GetNodeURI(&bstrURI); bool bRtn = (wstrURL == bstrURI ? true : false); SysFreeString(bstrURI); return bRtn; } bool Cwmwsrouter2Obj::CheckURLScheme(const wstring& wstrURL) { if (wstrURL.find(L"http://") != 0) { return false; } return true; } bool Cwmwsrouter2Obj::ReadViaList(WMXMLElement *pListElem, list& listViaList) { // components of qname wstring wstrChildElemName(L"via"); wstring wstrChildElemNS(g_pwszHeaderNS); // clear list listViaList.clear(); // iterate over elements in list ChildElementsList::iterator iL; for (iL = pListElem->GetChildElements().begin(); iL != pListElem->GetChildElements().end(); iL++) { if(*iL != NULL && (*iL)->GetLocalName() == wstrChildElemName && (*iL)->GetURI() == wstrChildElemNS) { // add to list listViaList.push_back((*iL)->GetContent()); } } return true; } bool Cwmwsrouter2Obj::ReadFoundList(WMXMLElement *pListElem, list& listFoundList) { // components of qname wstring wstrChildElemName(L"at"); wstring wstrChildElemNS(L""); // iterate over elements in list ChildElementsList::iterator iL; for (iL = pListElem->GetChildElements().begin(); iL != pListElem->GetChildElements().end(); iL++) { if(*iL != NULL && (*iL)->GetLocalName() == wstrChildElemName && (*iL)->GetURI() == wstrChildElemNS) { // add to list listFoundList.push_back((*iL)->GetContent()); } } return true; } bool Cwmwsrouter2Obj::ReadHeader(Iwmsoapmsg2 *pIwmsoapmsg) { BSTR bstrNamespaceURI = SysAllocString(g_pwszHeaderNS); BSTR bstrLocalName = SysAllocString(L"path"); BSTR bstrXML; wstring wstrXML; VARIANT_BOOL bResult; HRESULT hRes = pIwmsoapmsg->GetHeaderElemLiteral(bstrNamespaceURI, bstrLocalName, &bstrXML, &bResult); SysFreeString(bstrLocalName); SysFreeString(bstrNamespaceURI); if (hRes != S_OK || bResult == VARIANT_FALSE) { return false; } wstrXML = bstrXML; SysFreeString(bstrXML); // set up for parsing WMXMLParser Parser; Parser.SetBuildTree(true); bool bRtn = true; // parse the XML fragment representing the header entry try { Parser.ParseXML_WideString(wstrXML, NULL); } catch(int e) { int x = e; return false; } // get the WMXMLElement pointer representing root node of parse tree WMXMLElement *pRoot = Parser.DetachDocRoot(); if (pRoot == NULL) { return false; } // reset flags m_bActionElemFound = false; m_bToElemFound = false; m_bFwdElemFound = false; m_bRevElemFound = false; m_bFromElemFound = false; m_bIdElemFound = false; m_bRelatesToElemFound = false; m_bFaultElemFound = false; // get 'action' element WMXMLElement *pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"action")); if (pChild != NULL) { m_wstrAction = pChild->GetContent(); m_bActionElemFound = true; } // get 'to' element pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"to")); if (pChild != NULL) { m_wstrTo = pChild->GetContent(); m_bToElemFound = true; } // get 'fwd' element pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"fwd")); if (pChild != NULL) { ReadViaList(pChild, m_listFwd); m_bFwdElemFound = true; } // get 'rev' element pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"rev")); if (pChild != NULL) { ReadViaList(pChild, m_listRev); m_bRevElemFound = true; } // get 'from' element pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"from")); if (pChild != NULL) { m_wstrFrom = pChild->GetContent(); m_bFromElemFound = true; } // get 'id' element pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"id")); if (pChild != NULL) { m_wstrId = pChild->GetContent(); m_bIdElemFound = true; } // get 'relatesTo' element pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"relatesTo")); if (pChild != NULL) { m_wstrRelatesTo = pChild->GetContent(); m_bRelatesToElemFound = true; } // capture 'fault' element contents pChild = pRoot->GetChildElement(wstring(g_pwszHeaderNS), wstring(L"fault")); if (pChild != NULL) { ReadFault(pChild); m_bFaultElemFound = true; } delete pRoot; return true; } bool Cwmwsrouter2Obj::ProcessFault(int nCode, Iwmsoapmsg2 *pIwmsoapmsg) { // initialize flags m_bNeedEndpoint = false; m_bNeedFound = false; m_bNeedMaxsize = false; m_bNeedMaxtime = false; m_bNeedRetryAfter = false; // determine SOAP version long lSOAPVersion; pIwmsoapmsg->GetSOAPVersion(&lSOAPVersion); switch(nCode) { case 700: { // INVALID SOAP-RP HEADER m_wstrFaultcode = L"700"; m_wstrFaultreason = L"Invalid WS-Routing Header"; } break; case 701: { // SOAP-RP HEADER REQUIRED m_wstrFaultcode = L"701"; m_wstrFaultreason = L"WS-Routing Header Required"; } break; case 710: { // ENDPOINT NOT FOUND m_wstrFaultcode = L"710"; m_wstrFaultreason = L"Endpoint Not Found"; m_wstrEndpoint = m_wstrURI; m_bNeedEndpoint = true; } break; case 712: { // ENDPOINT NOT SUPPORTED m_wstrFaultcode = L"712"; m_wstrFaultreason = L"Endpoint Not Supported"; m_wstrEndpoint = m_wstrURI; m_bNeedEndpoint = true; } break; case 800: { // UNKNOWN SOAP-RP FAULT m_wstrFaultcode = L"800"; m_wstrFaultreason = L"Unknown WS-Routing Fault"; } break; case 810: { // ELEMENT NOT IMPLEMENTED m_wstrFaultcode = L"810"; m_wstrFaultreason = L"Element Not Implemented"; } break; case 811: { // SERVICE UNAVAILABLE m_wstrFaultcode = L"811"; m_wstrFaultreason = L"Service Unavailable"; } break; case 812: { // SERVICE TOO BUSY m_wstrFaultcode = L"812"; m_wstrFaultreason = L"Service Too Busy"; } break; case 820: { // ENDPOINT NOT REACHABLE m_wstrFaultcode = L"820"; m_wstrFaultreason = L"Endpoint Not Reachable"; m_wstrEndpoint = m_wstrURI; m_bNeedEndpoint = true; } break; default: { // SHOULD NEVER HAPPEN m_wstrFaultcode = L"000"; m_wstrFaultreason = L"Invalid Fault Code"; m_wstrEndpoint = m_wstrURI; m_bNeedEndpoint = true; } } // create new header entry WMXMLElement *pPath = new WMXMLElement(wstring(L"rp:path")); if (pPath != NULL) { pPath->SetNSPrefix(wstring(L"rp"), wstring(g_pwszHeaderNS)); if (lSOAPVersion == SOAP_VERSION_1_1) { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoapEnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:actor"), wstring(g_pwszSoapActorNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"1")); } else { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoap12EnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:role"), wstring(g_pwszSoap12RoleNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"true")); } } else { return false; } // 'action' element WMXMLElement *pChild = new WMXMLElement(wstring(L"rp:action")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(wstring(L"http://schemas.xmlsoap.org/soap/fault")); } else { delete pPath; return false; } // 'fwd' element (derived from 'rev' path received) pChild = new WMXMLElement(wstring(L"rp:fwd")); if (pChild != NULL) { pPath->AddChildElement(pChild); if (m_bRevElemFound == true) { // use contents of "rev" element received PopulateViaList(m_listRev, pChild); } } else { delete pPath; return false; } // 'from' element (only from endpoint) if (m_bIntermediary == false) { pChild = new WMXMLElement(wstring(L"rp:from")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(GetFromURI()); } else { delete pPath; return false; } } // 'id' element pChild = new WMXMLElement(wstring(L"rp:id")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(GenerateId()); } else { delete pPath; return false; } // 'relatesTo' element (value is id of request message) pChild = new WMXMLElement(wstring(L"rp:relatesTo")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrId); } else { delete pPath; return false; } // 'fault' element pChild = CreateFaultElem(); if (pChild != NULL) { pPath->AddChildElement(pChild); } else { delete pPath; return false; } // now serialize wstring wstrBuffer; pPath->Serialize(NULL, wstrBuffer); delete pPath; BSTR bstrBuffer = SysAllocString(wstrBuffer.c_str()); BSTR bstrNamespaceURI = SysAllocString(g_pwszHeaderNS); BSTR bstrLocalName = SysAllocString(L"path"); VARIANT_BOOL bMustUnderstand = VARIANT_TRUE; // determine actor URI BSTR bstrActorURI = NULL; if (lSOAPVersion == SOAP_VERSION_1_1) { bstrActorURI = SysAllocString(g_pwszSoapActorNext); } else { bstrActorURI = SysAllocString(g_pwszSoap12RoleNext); } BSTR bstrEncodingStyle = SysAllocString(L""); VARIANT_BOOL bResult; pIwmsoapmsg->AddFaultHeaderElemLiteral( bstrNamespaceURI, bstrLocalName, bstrBuffer, bMustUnderstand, bstrActorURI, bstrEncodingStyle, &bResult); SysFreeString(bstrNamespaceURI); SysFreeString(bstrLocalName); SysFreeString(bstrActorURI); SysFreeString(bstrEncodingStyle); SysFreeString(bstrBuffer); // generate SOAP fault BSTR bstrFaultcode, bstrFaultcodeNS, bstrFaultstring; if (lSOAPVersion == SOAP_VERSION_1_1) { if (nCode < 800) { bstrFaultcode = SysAllocString(L"Client"); bstrFaultstring = SysAllocString(L"WS-Routing Sender fault."); } else { bstrFaultcode = SysAllocString(L"Server"); bstrFaultstring = SysAllocString(L"WS-Routing Receiver fault."); } bstrFaultcodeNS = SysAllocString(g_pwszSoapEnvelopeNS); pIwmsoapmsg->SetSOAPFault(bstrFaultcode, bstrFaultcodeNS, bstrFaultstring, VARIANT_FALSE, &bResult); } else { if (nCode < 800) { bstrFaultcode = SysAllocString(L"Sender"); bstrFaultstring = SysAllocString(L"WS-Routing Sender fault."); } else { bstrFaultcode = SysAllocString(L"Receiver"); bstrFaultstring = SysAllocString(L"WS-Routing Receiver fault."); } bstrFaultcodeNS = SysAllocString(g_pwszSoap12EnvelopeNS); BSTR bstrSubcode = SysAllocString(L""); BSTR bstrSubcodeNS = SysAllocString(L""); BSTR bstrLangId = SysAllocString(L"en"); pIwmsoapmsg->SetSOAP12Fault(bstrFaultcode, bstrFaultcodeNS, bstrSubcode, bstrSubcodeNS, bstrFaultstring, bstrLangId, &bResult); SysFreeString(bstrSubcode); SysFreeString(bstrSubcodeNS); SysFreeString(bstrLangId); } SysFreeString(bstrFaultcode); SysFreeString(bstrFaultcodeNS); SysFreeString(bstrFaultstring); // set flag to disable response processing m_bRequestFault = true; return (bResult == VARIANT_TRUE); } bool Cwmwsrouter2Obj::ProcessReqAsIntermediary(Iwmsoapmsg2 *pIwmsoapmsg) { // determine next hop if (m_listFwd.empty() == true) { // we were the last intermediary m_wstrURI = m_wstrTo; } else { m_wstrURI = m_listFwd.front(); } // is this URL scheme supported? if (CheckURLScheme(m_wstrURI) == false) { ProcessFault(712, pIwmsoapmsg); return true; } // set next hop BSTR bstrTemp = SysAllocString(m_wstrURI.c_str()); pIwmsoapmsg->SetNextHopURL(bstrTemp); SysFreeString(bstrTemp); // determine SOAP version long lSOAPVersion; pIwmsoapmsg->GetSOAPVersion(&lSOAPVersion); // create new header entry WMXMLElement *pPath = new WMXMLElement(wstring(L"rp:path")); if (pPath != NULL) { pPath->SetNSPrefix(wstring(L"rp"), wstring(g_pwszHeaderNS)); if (lSOAPVersion == SOAP_VERSION_1_1) { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoapEnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:actor"), wstring(g_pwszSoapActorNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"1")); } else { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoap12EnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:role"), wstring(g_pwszSoap12RoleNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"true")); } } else { return false; } // 'action' element WMXMLElement *pChild = new WMXMLElement(wstring(L"rp:action")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrAction); } else { delete pPath; return false; } // 'to' element if (m_bToElemFound == true) { pChild = new WMXMLElement(wstring(L"rp:to")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrTo); } else { delete pPath; return false; } } // 'fwd' element if (m_bFwdElemFound == true) { // we have already removed the top "via" element pChild = new WMXMLElement(wstring(L"rp:fwd")); if (pChild != NULL) { pPath->AddChildElement(pChild); PopulateViaList(m_listFwd, pChild); } else { delete pPath; return false; } } // 'rev' element if (m_bRevElemFound == true) { // add empty "via" element to top of list m_listRev.push_front(wstring(L"")); pChild = new WMXMLElement(wstring(L"rp:rev")); if (pChild != NULL) { pPath->AddChildElement(pChild); PopulateViaList(m_listRev, pChild); } else { delete pPath; return false; } } // 'from' element if (m_bFromElemFound == true) { pChild = new WMXMLElement(wstring(L"rp:from")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrFrom); } else { delete pPath; return false; } } // 'id' element if (m_bIdElemFound == true) { pChild = new WMXMLElement(wstring(L"rp:id")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrId); } else { delete pPath; return false; } } // 'relatesTo' element if (m_bRelatesToElemFound == true) { pChild = new WMXMLElement(wstring(L"rp:relatesTo")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrRelatesTo); } else { delete pPath; return false; } } // 'fault' element if (m_bFaultElemFound == true) { pChild = CreateFaultElem(); if (pChild != NULL) { pPath->AddChildElement(pChild); } else { delete pPath; return false; } } // now serialize wstring wstrBuffer; pPath->Serialize(NULL, wstrBuffer); delete pPath; BSTR bstrBuffer = SysAllocString(wstrBuffer.c_str()); BSTR bstrNamespaceURI = SysAllocString(g_pwszHeaderNS); BSTR bstrLocalName = SysAllocString(L"path"); VARIANT_BOOL bMustUnderstand = VARIANT_TRUE; // determine actor URI BSTR bstrActorURI = NULL; if (lSOAPVersion == SOAP_VERSION_1_1) { bstrActorURI = SysAllocString(g_pwszSoapActorNext); } else { bstrActorURI = SysAllocString(g_pwszSoap12RoleNext); } BSTR bstrEncodingStyle = SysAllocString(L""); VARIANT_BOOL bResult; pIwmsoapmsg->AddHeaderElemLiteral( bstrNamespaceURI, bstrLocalName, bstrBuffer, bMustUnderstand, bstrActorURI, bstrEncodingStyle, &bResult); SysFreeString(bstrNamespaceURI); SysFreeString(bstrLocalName); SysFreeString(bstrActorURI); SysFreeString(bstrEncodingStyle); SysFreeString(bstrBuffer); return (bResult == VARIANT_TRUE); } bool Cwmwsrouter2Obj::ProcessReqAsEndpoint(Iwmsoapmsg2 *pIwmsoapmsg) { return true; } bool Cwmwsrouter2Obj::ProcessRespAsIntermediary(Iwmsoapmsg2 *pIwmsoapmsg) { // determine SOAP version long lSOAPVersion; pIwmsoapmsg->GetSOAPVersion(&lSOAPVersion); // create new header entry WMXMLElement *pPath = new WMXMLElement(wstring(L"rp:path")); if (pPath != NULL) { pPath->SetNSPrefix(wstring(L"rp"), wstring(g_pwszHeaderNS)); if (lSOAPVersion == SOAP_VERSION_1_1) { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoapEnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:actor"), wstring(g_pwszSoapActorNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"1")); } else { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoap12EnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:role"), wstring(g_pwszSoap12RoleNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"true")); } } else { return false; } // 'action' element WMXMLElement *pChild = new WMXMLElement(wstring(L"rp:action")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrAction); } else { delete pPath; return false; } // 'fwd' element if (m_bFwdElemFound == true) { // we have already removed the top "via" element pChild = new WMXMLElement(wstring(L"rp:fwd")); if (pChild != NULL) { pPath->AddChildElement(pChild); PopulateViaList(m_listFwd, pChild); } else { delete pPath; return false; } } // 'rev' element if (m_bRevElemFound == true) { // add cached URI indentifying us to top of list m_listRev.push_front(m_wstrIntermediaryURI); pChild = new WMXMLElement(wstring(L"rp:rev")); if (pChild != NULL) { pPath->AddChildElement(pChild); PopulateViaList(m_listRev, pChild); } else { delete pPath; return false; } } // 'from' element if (m_bFromElemFound == true) { pChild = new WMXMLElement(wstring(L"rp:from")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrFrom); } else { delete pPath; return false; } } // 'id' element if (m_bIdElemFound == true) { pChild = new WMXMLElement(wstring(L"rp:id")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrId); } else { delete pPath; return false; } } // 'relatesTo' element if (m_bRelatesToElemFound == true) { pChild = new WMXMLElement(wstring(L"rp:relatesTo")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrRelatesTo); } else { delete pPath; return false; } } // 'fault' element if (m_bFaultElemFound == true) { pChild = CreateFaultElem(); if (pChild != NULL) { pPath->AddChildElement(pChild); } else { delete pPath; return false; } } // now serialize wstring wstrBuffer; pPath->Serialize(NULL, wstrBuffer); delete pPath; BSTR bstrBuffer = SysAllocString(wstrBuffer.c_str()); BSTR bstrNamespaceURI = SysAllocString(g_pwszHeaderNS); BSTR bstrLocalName = SysAllocString(L"path"); VARIANT_BOOL bMustUnderstand = VARIANT_TRUE; // determine actor URI BSTR bstrActorURI = NULL; if (lSOAPVersion == SOAP_VERSION_1_1) { bstrActorURI = SysAllocString(g_pwszSoapActorNext); } else { bstrActorURI = SysAllocString(g_pwszSoap12RoleNext); } BSTR bstrEncodingStyle = SysAllocString(L""); VARIANT_BOOL bResult; // was this a fault response? pIwmsoapmsg->IsSOAPFault(&bResult); if (bResult == VARIANT_TRUE) { pIwmsoapmsg->AddFaultHeaderElemLiteral( bstrNamespaceURI, bstrLocalName, bstrBuffer, bMustUnderstand, bstrActorURI, bstrEncodingStyle, &bResult); } else { pIwmsoapmsg->AddHeaderElemLiteral( bstrNamespaceURI, bstrLocalName, bstrBuffer, bMustUnderstand, bstrActorURI, bstrEncodingStyle, &bResult); } SysFreeString(bstrNamespaceURI); SysFreeString(bstrLocalName); SysFreeString(bstrActorURI); SysFreeString(bstrEncodingStyle); SysFreeString(bstrBuffer); return (bResult == VARIANT_TRUE); } bool Cwmwsrouter2Obj::ProcessRespAsEndpoint(Iwmsoapmsg2 *pIwmsoapmsg) { // determine SOAP version long lSOAPVersion; pIwmsoapmsg->GetSOAPVersion(&lSOAPVersion); // create new header entry WMXMLElement *pPath = new WMXMLElement(wstring(L"rp:path")); if (pPath != NULL) { pPath->SetNSPrefix(wstring(L"rp"), wstring(g_pwszHeaderNS)); if (lSOAPVersion == SOAP_VERSION_1_1) { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoapEnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:actor"), wstring(g_pwszSoapActorNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"1")); } else { pPath->SetNSPrefix(wstring(L"SOAP-ENV"), wstring(g_pwszSoap12EnvelopeNS)); pPath->SetAttribute(wstring(L"SOAP-ENV:role"), wstring(g_pwszSoap12RoleNext)); pPath->SetAttribute(wstring(L"SOAP-ENV:mustUnderstand"), wstring(L"true")); } } else { return false; } // 'action' element WMXMLElement *pChild = new WMXMLElement(wstring(L"rp:action")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrAction); } else { delete pPath; return false; } // 'fwd' element if (m_bRevElemFound == true) { // use contents of "rev" element received pChild = new WMXMLElement(wstring(L"rp:fwd")); if (pChild != NULL) { pPath->AddChildElement(pChild); PopulateViaList(m_listRev, pChild); } else { delete pPath; return false; } } // 'rev' element // we need to insert "via" element with our URI if (m_bToElemFound == true) { // use the "to" value received m_listFwd.push_front(m_wstrTo); } else { // use the value of the "via" element found in "fwd" m_listFwd.push_front(m_wstrURI); } pChild = new WMXMLElement(wstring(L"rp:rev")); if (pChild != NULL) { pPath->AddChildElement(pChild); PopulateViaList(m_listFwd, pChild); } else { delete pPath; return false; } // 'from' element pChild = new WMXMLElement(wstring(L"rp:from")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(GetFromURI()); } else { delete pPath; return false; } // 'id' element pChild = new WMXMLElement(wstring(L"rp:id")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(GenerateId()); } else { delete pPath; return false; } // 'relatesTo' element (value is id of request message) pChild = new WMXMLElement(wstring(L"rp:relatesTo")); if (pChild != NULL) { pPath->AddChildElement(pChild); pChild->AppendContent(m_wstrId); } else { delete pPath; return false; } // 'fault' element if (m_bFaultElemFound == true) { pChild = CreateFaultElem(); if (pChild != NULL) { pPath->AddChildElement(pChild); } else { delete pPath; return false; } } // now serialize wstring wstrBuffer; pPath->Serialize(NULL, wstrBuffer); delete pPath; BSTR bstrBuffer = SysAllocString(wstrBuffer.c_str()); BSTR bstrNamespaceURI = SysAllocString(g_pwszHeaderNS); BSTR bstrLocalName = SysAllocString(L"path"); VARIANT_BOOL bMustUnderstand = VARIANT_TRUE; // determine actor URI BSTR bstrActorURI = NULL; if (lSOAPVersion == SOAP_VERSION_1_1) { bstrActorURI = SysAllocString(g_pwszSoapActorNext); } else { bstrActorURI = SysAllocString(g_pwszSoap12RoleNext); } BSTR bstrEncodingStyle = SysAllocString(L""); VARIANT_BOOL bResult; // was this a fault response? pIwmsoapmsg->IsSOAPFault(&bResult); if (bResult == VARIANT_TRUE) { pIwmsoapmsg->AddFaultHeaderElemLiteral( bstrNamespaceURI, bstrLocalName, bstrBuffer, bMustUnderstand, bstrActorURI, bstrEncodingStyle, &bResult); } else { pIwmsoapmsg->AddHeaderElemLiteral( bstrNamespaceURI, bstrLocalName, bstrBuffer, bMustUnderstand, bstrActorURI, bstrEncodingStyle, &bResult); } SysFreeString(bstrNamespaceURI); SysFreeString(bstrLocalName); SysFreeString(bstrActorURI); SysFreeString(bstrEncodingStyle); SysFreeString(bstrBuffer); return (bResult == VARIANT_TRUE); } bool Cwmwsrouter2Obj::ProcessRequest(Iwmsoapmsg2 *pIwmsoapmsg) { m_bRequestFault = false; m_bIntermediary = true; m_bNoReversePath = false; if (ReadHeader(pIwmsoapmsg) == false) { // missing soap-rp header ProcessFault(701, pIwmsoapmsg); return true; } // is this a fault message? if (m_bFaultElemFound == true || m_wstrAction == L"http://schemas.xmlsoap.org/soap/fault") { // send "no content" response pIwmsoapmsg->SetNoContentResponse(VARIANT_TRUE); // set flag to abort processing m_bAbortProcessing = true; return true; } // was a reverse path specified? if (m_bRevElemFound == false) { // no, set flag, normal processing will proceed m_bNoReversePath = true;; } // were "id" and "action" elements found? if (m_bIdElemFound == false || m_bActionElemFound == false) { { // ill formed header... should have "id" and "action" elements ProcessFault(700, pIwmsoapmsg); return true; } } // was a "fwd" element with entries(s) found? if (m_bFwdElemFound == false || m_listFwd.empty() == true) { // no, so check for "to" element if (m_bToElemFound == false) { // ill formed header... should have "to" element ProcessFault(700, pIwmsoapmsg); return true; } // "to" element found... we are the endpoint m_bIntermediary = false; // check the URI to make sure it's us if (CheckIdentity(m_wstrTo, pIwmsoapmsg) == false) { // not us... "invalid ws-routing header" fault ProcessFault(700, pIwmsoapmsg); return true; } // it's us, so process as endpoint m_wstrURI = m_wstrTo; if (ProcessReqAsEndpoint(pIwmsoapmsg) == false) { ProcessFault(800, pIwmsoapmsg); } return true; } else { // non-empty "fwd" element... get top element m_wstrURI = m_listFwd.front(); m_listFwd.pop_front(); // is it us? if (CheckIdentity(m_wstrURI, pIwmsoapmsg) == false) { // not us... send invalid ws-routing header fault ProcessFault(700, pIwmsoapmsg); return true; } // was this the last one AND no "to" element is present? if (m_listFwd.empty() == true && m_bToElemFound == false) { // we are the endpoint, so process as such m_bIntermediary = false; if (ProcessReqAsEndpoint(pIwmsoapmsg) == false) { ProcessFault(800, pIwmsoapmsg); } return true; } // we are an intermediary... process as such m_wstrIntermediaryURI = m_wstrURI; return ProcessReqAsIntermediary(pIwmsoapmsg); } return true; } bool Cwmwsrouter2Obj::ProcessResponse(Iwmsoapmsg2 *pIwmsoapmsg) { // was a reverse path found in request? if (m_bNoReversePath == true) { // send "no content" response and quit pIwmsoapmsg->SetNoContentResponse(VARIANT_TRUE); return true; } // was a fault generated in request phase? if (m_bRequestFault == true) { // do nothing return true; } VARIANT_BOOL bResult; pIwmsoapmsg->IsIntermediary(&bResult); if (bResult == VARIANT_FALSE) { // we are endpoint, process as such if (ProcessRespAsEndpoint(pIwmsoapmsg) == false) { ProcessFault(800, pIwmsoapmsg); } // will we be using implicit reverse path? wstring wstrFirstRevURL = m_listRev.front(); if (wstrFirstRevURL.empty() == true || CheckURLScheme(wstrFirstRevURL) == false) { // use implicit path return true; } // no, an explicit reverse path return ForwardMsgHTTP(wstrFirstRevURL, pIwmsoapmsg); } // we are intermediary... look for WS-Routing header in response if (ReadHeader(pIwmsoapmsg) == false) { // did attempt to forward message fail? pIwmsoapmsg->IsSOAPFault(&bResult); if (bResult == VARIANT_TRUE) { BSTR bstrFaultString; pIwmsoapmsg->GetSOAPFaultString(&bstrFaultString); if (wcscmp(L"Attempt to forward SOAP message by intermediary failed.", bstrFaultString) == 0) { SysFreeString(bstrFaultString); // was a "rev" element with entries(s) found? if (m_bRevElemFound == true && m_listRev.empty() == false) { // non-empty "rev" element... remove top element added in request phase m_listRev.pop_front(); } ProcessFault(820, pIwmsoapmsg); return true; } SysFreeString(bstrFaultString); } // no forwarding failure, no soap-rp header found... do nothing. return true; } // were "id" and "action" elements found? if (m_bIdElemFound == false || m_bActionElemFound == false) { { // ill formed header... should have "id" and "action" elements ProcessFault(700, pIwmsoapmsg); return true; } } // was a "fwd" element with entries(s) found? if (m_bFwdElemFound == true && m_listFwd.empty() == false) { // non-empty "fwd" element... get top element m_wstrURI = m_listFwd.front(); m_listFwd.pop_front(); // is it us (an empty "via" element means it's for us)? if (m_wstrURI.empty() == false) { // not us... send invalid header fault ProcessFault(700, pIwmsoapmsg); return true; } } // now process as intermediary return ProcessRespAsIntermediary(pIwmsoapmsg); } STDMETHODIMP Cwmwsrouter2Obj::OnProcessHeader(VARIANT SOAPMsgInterface, VARIANT_BOOL *pResult) { // set up, assume success m_bAbortProcessing = false; *pResult = VARIANT_TRUE; // get interface ptr IDispatch *pIDispatch = SOAPMsgInterface.pdispVal; Iwmsoapmsg2 *pIwmsoapmsg; HRESULT hRes = pIDispatch->QueryInterface(IID_Iwmsoapmsg2, (void **)&pIwmsoapmsg); if (hRes != S_OK) { return E_FAIL; } VARIANT_BOOL bResult; pIwmsoapmsg->IsRequestPhase(&bResult); if (bResult == VARIANT_TRUE) { // this is request phase if (ProcessRequest(pIwmsoapmsg) == false) { ProcessFault(800, pIwmsoapmsg); } pIwmsoapmsg->Release(); // abort processing? if (m_bAbortProcessing == true) { // set out parameter to signal abort *pResult = VARIANT_FALSE; } return S_OK; } // response phase if (ProcessResponse(pIwmsoapmsg) == false) { ProcessFault(800, pIwmsoapmsg); } pIwmsoapmsg->Release(); if (m_bAbortProcessing == true) { // set out parameter to signal abort *pResult = VARIANT_FALSE; } return S_OK; } bool Cwmwsrouter2Obj::ForwardMsgHTTP(const wstring& wstrURL, Iwmsoapmsg2 *pIwmsoapmsg) { // toggle to 'response' phase pIwmsoapmsg->SetRequestPhase(VARIANT_FALSE); VARIANT_BOOL bResult; // must forward request, so re-serialize request message pIwmsoapmsg->Serialize(&bResult); if (bResult == VARIANT_FALSE) { // failed return false; } // set up HTTP client string strNextHopURL, strHost, strSvcURI, strTemp; USES_CONVERSION; strNextHopURL = OLE2A(wstrURL.c_str()); int nPortNbr = 80; string::size_type pos; if ((pos = strNextHopURL.find("http://")) != string::npos) { strTemp = strNextHopURL.substr(pos + 7); pos = strTemp.find('/'); if (pos == string::npos) { strSvcURI = "/"; } else { strSvcURI = strTemp.substr(pos); } strTemp = strTemp.substr(0, pos); if ((pos = strTemp.find(':')) != string::npos) { // port specified explicitly nPortNbr = atoi(strTemp.substr(pos + 1).c_str()); strHost = strTemp.substr(0, pos); } else { strHost = strTemp; } } // get serialized message _variant_t varBuffer; pIwmsoapmsg->GetBuffer(&varBuffer, &bResult); SAFEARRAY *pArray = varBuffer.parray; void *pData; if ( bResult == VARIANT_FALSE || !(varBuffer.vt & (VT_ARRAY | VT_UI1)) || pArray == NULL || SafeArrayGetDim(pArray) != 1 || FAILED(SafeArrayAccessData(pArray, &pData))) { return false; } // get soap version long lSOAPVersion; pIwmsoapmsg->GetSOAPVersion(&lSOAPVersion); DIMEParser dimeParser; string strBody; long lNumAttachments = 0; pIwmsoapmsg->GetNumRespAttachments(&lNumAttachments); unsigned long ulMsgLength; if (lNumAttachments > 0) { // try to initialize parser for serialization // accept default record size of 4096 octets try { dimeParser.SerializeInit(); } catch (DIMEParserException *e) { delete e; SafeArrayUnaccessData(pArray); return false; } string strTypeURI; if (lSOAPVersion == SOAP_VERSION_1_1) { strTypeURI = g_pszSoapEnvelopeNS; } else { strTypeURI = g_pszSoap12EnvelopeNS; } // add primary DIME payload if (dimeParser.AddPayload( (const char *)pData, pArray->rgsabound[0].cElements, string(""), strTypeURI, DIME_TYPENAME_FORMAT_URI) == false) { SafeArrayUnaccessData(pArray); return false; } SafeArrayUnaccessData(pArray); // now get secondary payloads long lPosition; BSTR bstrId, bstrType; long lTNF; IUnknown *pIUnknown; _variant_t varOptions; for (pIwmsoapmsg->GetFirstDIMEAttachmentResp(&bstrId, &bstrType, &lTNF, &pIUnknown, &varOptions, &lPosition, &bResult); bResult == VARIANT_TRUE; pIwmsoapmsg->GetNextDIMEAttachmentResp( &bstrId, &bstrType, &lTNF, &pIUnknown, &varOptions, &lPosition, &bResult) ) { string strId, strType; WideStringToUTF8(wstring(bstrId), strId); WideStringToUTF8(wstring(bstrType), strType); SysFreeString(bstrId); SysFreeString(bstrType); IStorage *pIStorage; HRESULT res = pIUnknown->QueryInterface(IID_IStorage, (void **)&pIStorage); if (FAILED(res)) { return false; } SAFEARRAY *pArray = NULL; if ((varOptions.vt & VT_TYPEMASK) & (VT_ARRAY | VT_UI1)) { pArray = varOptions.parray; } if (dimeParser.AddPayload( pIStorage, strId, strType, lTNF, pArray) == false) { // this will result in 500 "Internal Server Error" pIStorage->Release(); return false; } varOptions.Clear(); pIStorage->Release(); } ulMsgLength = dimeParser.CalcSerialLength(); } else { // no attachments, send without DIME packaging strBody.append((char *)pData, pArray->rgsabound[0].cElements); ulMsgLength = pArray->rgsabound[0].cElements; SafeArrayUnaccessData(pArray); } // build HTTP Header char szBuffer[128]; string strHeaders = "Host: "; strHeaders += strHost; sprintf(szBuffer, ":%d\r\n", nPortNbr); strHeaders += szBuffer; strHeaders += "User-Agent: "; strHeaders += string(g_pszUserAgent); if (lNumAttachments > 0) { strHeaders += "\r\nContent-Type: application/dime\r\n"; } else { if (lSOAPVersion == SOAP_VERSION_1_1) { strHeaders += "\r\nContent-Type: text/xml; charset=\"utf-8\"\r\n"; } else { strHeaders += "\r\nContent-Type: application/soap+xml; charset=\"utf-8\"\r\n"; } } sprintf(szBuffer, "Content-Length: %d\r\n", ulMsgLength); strHeaders += szBuffer; // now send message WMDIMERequestSock HTTPClient; bool bSuccess; if (lNumAttachments > 0) { bSuccess = HTTPClient.SendHTTPRequest(nPortNbr, string("POST"), strHost, strSvcURI, string(""), strHeaders, &dimeParser); } else { bSuccess = HTTPClient.SendHTTPRequest(nPortNbr, string("POST"), strHost, strSvcURI, string(""), strHeaders, strBody, &dimeParser); } if (bSuccess == false || HTTPClient.GetStatus() >= 300) { // something went wrong return false; } // set "no content" response pIwmsoapmsg->SetNoContentResponse(VARIANT_TRUE); return true; } STDMETHODIMP Cwmwsrouter2Obj::OnTestMUHeaderBlock(BSTR bstrNamespace, BSTR bstrLocalName, VARIANT_BOOL *pResult) { *pResult = VARIANT_FALSE; if (wcscmp(bstrNamespace, g_pwszHeaderNS) == 0) { if (wcscmp(bstrLocalName, L"path") == 0) { *pResult = VARIANT_TRUE; return S_OK; } } return S_OK; }