📄 srmpfwd.cxx
字号:
CSrmpEnvelopeHeader *pSrmpEnvelopeHeader = pPacketImage->sect.pSrmpEnvelopeHeader;
int iStatusCode = 503;
CHAR *szSoapStart = NULL;
CHAR *szSoapEnd = NULL;
// note: if I don't have pCompoundMessageHeader (ie user generated fwd) need to do something more intelligent!
const char *szOrigHttpHeaders = (CHAR*) pCompoundMessageHeader->GetPointerToData();
CHAR *pszRead;
CHAR *pszWrite;
DWORD ccHeaderBuf = 0;
DWORD ccBodyBuf = 0;
SrmpIOCTLPacket ioPacket;
ISAXXMLReader* pReader = NULL;
VARIANT varInput;
BOOL fSecure = (qType == SCFILE_QP_FORMAT_HTTPS);
CHAR cSave;
CHAR *szURL = NULL;
DWORD cbMime = 0;
DWORD cbSoapEnv;
DWORD cp = CP_UTF8;
CHAR *szBoundary = NULL;
CONTENT_TYPE contentType = CONTENT_TYPE_UNKNOWN;
HRESULT hr;
BOOL fCoUninit = FALSE;
memset(&ioPacket,0,sizeof(ioPacket));
memset(&varInput,0,sizeof(varInput));
SVSUTIL_ASSERT(pSrmpEnvelopeHeader && pSrmpEnvelopeHeader->GetData());
//
// Build HTTP headers up based on original values.
//
const CHAR *szHeaderEnd = strstr(szOrigHttpHeaders,cszCRLF2);
if (!szHeaderEnd) {
SVSUTIL_ASSERT(0); // message won't be stored unless in valid format.
goto done;
}
if (NULL == (ioPacket.pszHeaders = (CHAR*) g_funcAlloc((szHeaderEnd - szOrigHttpHeaders),g_pvAllocData)))
goto done;
pszWrite = ioPacket.pszHeaders;
pszRead = (CHAR*)szOrigHttpHeaders;
// copy headers to send straight along to next hop, except excluded ones.
while (pszRead < szHeaderEnd) {
if (!SkipHeader(pszRead)) {
// copy header
CHAR *pszReadEnd = strstr(pszRead,"\r\n") + 2;
memcpy(pszWrite,pszRead,pszReadEnd-pszRead);
pszWrite += (pszReadEnd - pszRead);
// look for content-type to determine how to handle next stage.
if (0 == _strnicmp(pszRead,cszContentType, ccContentType)) {
CHAR *szContentType = pszRead + ccContentType + 1;
while ((*szContentType == ' ') || (*szContentType == '\t'))
szContentType++;
if (0 == _strnicmp(szContentType,cszTextXML,SVSUTIL_CONSTSTRLEN(cszTextXML)))
contentType = CONTENT_TYPE_XML;
else {
#if defined (DEBUG) || defined (_DEBUG)
// our HTTP processing in SrmpIsapi is only capable of handeling "text/xml" and "multipart/related";
// any errors should've been caught long before we reach this stage.
static const char cszMime[] = "multipart/related";
SVSUTIL_ASSERT(0 == _strnicmp(szContentType,cszMime,SVSUTIL_CONSTSTRLEN(cszMime)));
#endif
contentType = CONTENT_TYPE_MIME;
}
}
pszRead = pszReadEnd;
}
else {
pszRead = strstr(pszRead,"\r\n") + 2;
}
}
SVSUTIL_ASSERT(contentType != CONTENT_TYPE_UNKNOWN);
ioPacket.cbHeaders = pszWrite - ioPacket.pszHeaders;
//
// Build POST body. Keep everything the same except for updating the
// <fwd> and <rev> fields, as appropriate.
//
if (contentType == CONTENT_TYPE_MIME) {
if (NULL == (szBoundary = pSrmpFwd->SetupMIMEBuffer(pPacketImage,&szSoapStart,&szSoapEnd,&cbMime)))
goto done;
// make a temporary string.
cSave = *szSoapEnd;
*szSoapEnd = 0;
}
else {
// text/xml begins immediatly in POST data.
CHAR *szHttpData = (CHAR*) pCompoundMessageHeader->GetPointerToData();
if (NULL == (szSoapStart = strstr(szHttpData,cszCRLF2))) {
SVSUTIL_ASSERT(0);
goto done;
}
}
// Initialize SAX
if (FAILED(CoInitializeEx(NULL,COINIT_MULTITHREADED)))
goto done;
fCoUninit = TRUE;
if (FAILED(CoCreateInstance(CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER, IID_ISAXXMLReader, (void**)&pReader)))
goto done;
if (FAILED(pReader->putContentHandler(pSrmpFwd)))
goto done;
memset(&varInput,0,sizeof(varInput));
varInput.vt = VT_BSTR;
varInput.bstrVal = (BSTR) svsutil_MultiByteToWideChar(szSoapStart,CP_UTF8,TRUE);
if (!varInput.bstrVal)
goto done;
if (szSoapEnd) // reset the string.
*szSoapEnd = cSave;
if (FAILED(hr = pReader->parse(varInput))) {
SVSUTIL_ASSERT(0);
scerror_DebugOutM(VERBOSE_MASK_SRMP,(L"SRMP: SAX Parse error on attempt to forward message, error=0x%08x\r\n",hr));
goto done;
}
SVSUTIL_ASSERT(S_OK == svsutil_validateXML((BSTR)pSrmpFwd->writeBuffer.pBuffer));
if (0 == (cbSoapEnv = WideCharToMultiByte(cp, 0, (WCHAR*)pSrmpFwd->writeBuffer.pBuffer, -1, NULL, 0, 0, 0))) {
cp = CP_ACP;
if (0 == (cbSoapEnv = WideCharToMultiByte(cp, 0, (WCHAR*)pSrmpFwd->writeBuffer.pBuffer, -1, NULL, 0, 0, 0)))
goto done;
}
// +1024 to contain the initial MIME headers.
if (NULL == (ioPacket.pszPost = (CHAR*)g_funcAlloc(cbMime+cbSoapEnv+1024,g_pvAllocData)))
goto done;
if (NULL == (szURL = AllocURL(wszURL)))
goto done;
// write out MIME information for SOAP envelope.
// use (cbSoapEnv-1) because we don't write out NULL character in pSrmpFwd->writeBuffer.pBuffer.
if (contentType == CONTENT_TYPE_MIME) {
pszWrite = ioPacket.pszPost + sprintf(ioPacket.pszPost,BOUNDARY_HYPHEN "%s\r\n"
"Content-Type: %s; charset=UTF-8\r\nContent-Length: %d\r\n\r\n",
szBoundary,cszTextXML,cbSoapEnv-1);
WideCharToMultiByte(cp, 0, (WCHAR*)pSrmpFwd->writeBuffer.pBuffer, -1, pszWrite, cbSoapEnv, 0, 0);
memcpy(pszWrite + cbSoapEnv-1,szSoapEnd,cbMime);
ioPacket.cbPost = (pszWrite + cbSoapEnv - 1 + cbMime - ioPacket.pszPost);
}
else {
// simple "text/xml" case.
WideCharToMultiByte(cp, 0, (WCHAR*)pSrmpFwd->writeBuffer.pBuffer, -1, ioPacket.pszPost, cbSoapEnv, 0, 0);
ioPacket.cbPost = cbSoapEnv;
}
iStatusCode = SendHttpMsg(szURL,fSecure,&ioPacket);
done:
if (pReader)
pReader->Release();
if (ioPacket.pszHeaders)
g_funcFree(ioPacket.pszHeaders,g_pvFreeData);
if (varInput.bstrVal)
g_funcFree(varInput.bstrVal,g_pvFreeData);
if (ioPacket.pszPost)
g_funcFree(ioPacket.pszPost,g_pvFreeData);
if (szBoundary)
g_funcFree(szBoundary,g_pvFreeData);
if (szURL)
g_funcFree(szURL,g_pvFreeData);
if (fCoUninit)
CoUninitialize();
return iStatusCode;
}
CHAR* CSrmpFwd::SetupMIMEBuffer(ScPacketImage *pPacketImage, CHAR **ppszSoapStart, CHAR **ppszSoapEnd, DWORD *pcbMime) {
CSrmpEnvelopeHeader *pSrmpEnvelopeHeader = pPacketImage->sect.pSrmpEnvelopeHeader;
CCompoundMessageHeader *pCompoundMessageHeader = pPacketImage->sect.pCompoundMessageHeader;
CHAR *szHttpHeaders = (CHAR*) pCompoundMessageHeader->GetPointerToData();
CHAR *szPost;
CHAR *szBoundary = NULL;
DWORD cbPost;
BOOL fRet = FALSE;
// allocate an large enough buffer in hopes we can save a realloc.
DWORD cbAlloc = (wcslen(szQueueName)+pSrmpEnvelopeHeader->GetDataLengthInWCHARs()+1024)*sizeof(WCHAR);
if (! writeBuffer.AllocMem(cbAlloc))
goto done;
szPost = strstr(szHttpHeaders,cszCRLF2);
if (!szPost) {
SVSUTIL_ASSERT(0); // shouldn't have made it this far with corrupt data
goto done;
}
szPost = szPost + ccCRLF2;
if (! pCompoundMessageHeader->GetBodySizeInBytes()) {
// simple SOAP envelope (no MIME body). Should've had "content-type: text/xml" set already.
SVSUTIL_ASSERT(0);
goto done;
}
// MIME message. Since we're forwarding directly we want to perserve
// all the original information except SOAP headers, which are modified.
szBoundary = FindMimeBoundary(szHttpHeaders);
if (!szBoundary)
goto done;
cbPost = pCompoundMessageHeader->GetDataSizeInBytes() - (szPost - szHttpHeaders);
if (! ReadSoapEnvelopeFromMIME(szBoundary,strlen(szBoundary),szPost,cbPost,ppszSoapStart,ppszSoapEnd)) {
SVSUTIL_ASSERT(0);
goto done;
}
*pcbMime = cbPost - (*ppszSoapEnd-szPost);
fRet = TRUE;
done:
if (!fRet && szBoundary) {
g_funcFree(szBoundary,g_pvFreeData);
return NULL;
}
return szBoundary;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -