You need to sign in to do that
Don't have an account?
professore
Anyone gotten C++ MSXML SOAP + gzip to work ?
Hi,
Not sure if anyone can help, but I am trying to send a gzip encoded POST request and failing miserably. Below is my code ...
I think someone who has done this would be able to tell me a .if it's possible and b if so how to do it.
Thanks
Bob
IXMLDOMDocument2Ptr pXMLDoc = NULL;
EVAL_HR(pXMLDoc.CreateInstance("Msxml2.DOMDocument.6.0"));
// Load the document asynchronously
pXMLDoc->async = true;
MyApp* pApp = ((CSyntaxis2App*)AfxGetApp());
string source_file;
source_file = pApp->GetWorkingDirectory() + "\\SOAPCall.xml";
//Check the content type
// Step 3: Create XMLHTTP and send a POST request to the Web service
IXMLHTTPRequestPtr pXH = NULL;
EVAL_HR (pXH.CreateInstance("Msxml2.XMLHTTP.5.0"));
COleVariant vPostURL(m_csEndpointURL + m_csEndpointSuffix,VT_BSTR);
EVAL_HR (pXH->open("POST", vPostURL.bstrVal,
_variant_t(VARIANT_FALSE), _variant_t(""), _variant_t("")));
string dest_file = source_file + ".gz";
if(m_bUseCompression)
{
EVAL_HR (pXH->setRequestHeader("Content-Encoding", "gzip"));
GZip gzip;
FILE* source = fopen(source_file.c_str(),"rb");
FILE* dest = fopen(dest_file.c_str(),"wb");
if(gzip.compress(source,dest,-1) != Z_OK)
{
m_csLastError = "Failed compressing source file in SOAPAPIBase::Execute()";
fclose(source);
fclose(dest);
return FALSE;
}
fclose(source);
fclose(dest);
unlink(source_file.c_str());
source_file = dest_file;
}
_bstr_t btSourceFile(source_file.c_str());
pXMLDoc->load(btSourceFile);
unlink(source_file.c_str());
vector<CSOAPAPIParameterPair>::iterator iter;
iter = m_vCustomHTTPHeaders.begin();
CString strHeader,strHeaders;
iter = m_vCustomHTTPHeaders.begin();
while(iter != m_vCustomHTTPHeaders.end())
{
COleVariant vtName(iter->m_csName,VT_BSTR);
COleVariant vtValue(iter->m_csValue,VT_BSTR);
EVAL_HR (pXH->setRequestHeader(vtName.bstrVal,vtValue.bstrVal));
iter++;
}
if(m_bUseCompression)
EVAL_HR (pXH->send(btSourceFile));
else
EVAL_HR (pXH->send(pXMLDoc->xml));
Near the end you have
EVAL_HR (pXH->send(btSourceFile));
This is going to send the name of the file, not the actual file contents, you'll need to open an IStream * for the file, and pass that to the send call.
Thanks Simon.
Unfortunately the only way I can see of doing it is by using SHCreateStreamOnFile() and that's not supported in Visual C++ 6.
As its an interface, you don't need to use a system provided implementation, its pretty trivial to implement yourself, e.g. see http://code.google.com/p/pocketsoap/source/browse/trunk/pockethttp/core/FileReaderFactory.cpp?r=8
I have rewritten to use PocketSOAP. I am sure I am missing something simple. Can you have a look ? Thanks
I now use the Send function of IHTTPTransportAdv2 t as follows :
char *buffer;
.... Load gzip envelope that works fine uncompressed into the buffer here ...
_bstr_t bstr_buffer(buffer);
//"compression.enabled"
COleVariant True = (short)TRUE;
True.vt = VT_BOOL;
t->put_Option(CComBSTR("compression.enabled"),True);
hr = t->Send ( CComBSTR(m_csEndpointURL + m_csEndpointSuffix), bstr_buffer ) ;
free(buffer);
Output is as follows ....
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:XS="http://www.w3.org/2001/XMLSchema"
xmlns:XI="http://www.w3.org/2001/XMLSchema-instance"
xmlns:a="urn:fault.enterprise.soap.sforce.com"><S:Body><S:Fault XI:type="S:Fault"><faultcode XI:type="XS:QName">UNKNOWN_EXCEPTION</faultcode><faultstring XI:type="XS:string">UNKNOWN_EXCEPTION: Content is not allowed in prolog.</faultstring><detail><a:UnexpectedErrorFault XI:type="a:UnexpectedErrorFault"><a:exceptionCode XI:type="XS:string">UNKNOWN_EXCEPTION</a:exceptionCode><a:exceptionMessage XI:type="XS:string">Content is not allowed in prolog.</a:exceptionMessage></a:UnexpectedErrorFault></detail></S:Fault></S:Body></S:Envelope>
pocketHTTP will compress the request for you, you don't need to compress it yourself, just pass in the xml string you want to send.