cURL
Haxx ad
libcurl

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curlpp mailing list Archives

Re: [cURLpp] HTTP POST and WriteCallback

From: Nazario Cipriani <NazarioCipriani_at_web.de>
Date: Fri, 05 Aug 2005 12:13:46 +0200

Jean-Philippe Barrette-LaPierre wrote:
> On July 28, 2005 11:31 am, Nazario Cipriani wrote:
>
>>There is a strange problem I encountered with the WriteCallback.
>>The class I'm using looks like this (as posted in my previous mail, I
>>put it here for better understanding):
>
>
> Can shoot me a complete example and a procedure that will cause the problem?
>
If you take my WriteCallback Class and try to send an HTTP POST request,
you will probably get the same error.

Well the problem is, the project I'm working on is quite vast.
So its hard to shoot you an example. But I'll try anyway...
This is the ReaderCallback and the WriteCallback Class I use to send my
HTTP POST to the host and get the result:

     class WriterMemoryClass
     {
     public:
         // Helper Class for reading result from remote host
         WriterMemoryClass()
         {
             this->m_pBuffer = NULL;
             this->m_pBuffer = (char*) malloc(MAX_FILE_LENGTH *
sizeof(char));
             this->m_Size = 0;
         };
         ~WriterMemoryClass()
         {
             if (this->m_pBuffer)
                 free(this->m_pBuffer);
         };
         static void* Realloc(void* ptr, size_t size)
         {
             if(ptr)
                 return realloc(ptr, size);
             else
                 return malloc(size);
         };
         // Callback must be declared static, otherwise it won't link...
         static size_t WriteMemoryCallback(char* ptr, size_t size,
size_t nmemb, void* data)
         {
             // Calculate the real size of the incoming buffer
             size_t realsize = size * nmemb;

             // Cast the void* data pointer to WriterMemoryClass...
             WriterMemoryClass* Memory = (WriterMemoryClass*) data;

             // (Re)Allocate memory for the buffer
             Memory->m_pBuffer = (char*)
Memory->Realloc(Memory->m_pBuffer, Memory->m_Size + realsize + 1);

             // Test if Buffer is initialized correctly & copy memory
             if (Memory->m_pBuffer)
             {
                 memcpy(&(Memory->m_pBuffer[Memory->m_Size]), ptr,
realsize);
                 Memory->m_Size += realsize;
                 Memory->m_pBuffer[Memory->m_Size] = 0;
             }

             // return the real size of the buffer...
             return realsize;
         };

         // Public member vars
         char* m_pBuffer;
         size_t m_Size;
     };

        class ReaderMemoryClass
        {
        public:
                ReaderMemoryClass()
                {
                        this->m_pBuffer = NULL;
                        this->m_pBuffer = (char*) malloc(MAX_FILE_LENGTH * sizeof(char));
                        this->m_Size = 0;
                };
                ~ReaderMemoryClass()
                {
                        if (this->m_pBuffer)
                        {
                                free(this->m_pBuffer);
// delete[] this->m_pBuffer;
                        }
                };
                char* GetBuffer(void)
                {
                        return this->m_pBuffer;
                };
                size_t GetSize(void)
                {
                        return this->m_Size;
                };
                void SetBuffer(char* pBuffer)
                {
                        strcpy(this->m_pBuffer, pBuffer);
                        this->m_pBuffer[strlen(pBuffer) + 1] = 0;
                };
                static void* Realloc(void* ptr, size_t size)
                {
                        if(ptr)
                        {
                                return realloc(ptr, size);
                        }
                        else
                        {
                                return malloc(size);
                        }
                };
                // Callback must be declared static, otherwise it won't link...
                static size_t ReadMemoryCallback(char* buffer, size_t size, size_t
nitems, void* instream)
                {
                        ReaderMemoryClass* Memory = (ReaderMemoryClass*) instream;

                        Memory->m_Size = size * nitems;
                        strncpy(buffer, Memory->m_pBuffer, Memory->m_Size);

                        return size * nitems;
                };

                // Public member vars

        protected:
                char* m_pBuffer;
                size_t m_Size;
        };

Now, I construct a HTTP POST request to be sent to the host. After that
I set the ReaderCallback Buffer ans invoke the request.

        std::string SOAPString;
        std::list<std::string> HeaderData;
        char ContLength[50];

        HeaderData.push_back("SOAPAction: \r");
        HeaderData.push_back("Accept: text/html, image/gif, image/jpeg, *;
q=.2, */*; q=.2\r");
        HeaderData.push_back("Connection: keep-alive\r");
        HeaderData.push_back("Content-Type: application/x-www-form-urlencoded\r");

        // Construct the final SOAP envelope to send to the server...
        SOAPString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        SOAPString.append("<soapenv:Envelope
xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" \
                                                xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \
                                                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
        SOAPString.append("<soapenv:Body>");
        SOAPString.append(this->m_pArg); // <- The data to be sent!
        SOAPString.append("</soapenv:Body>");
        SOAPString.append("</soapenv:Envelope>");

        sprintf(ContLength, "Content-Length: %d\r", strlen(SOAPString.c_str()));
        HeaderData.push_back(ContLength);
        HeaderData.push_back("\r");
        HeaderData.push_back("\r");

        // Set the String to uploaded in the ReaderMemoryClass -> Uploading
must be enabled!!!
        this->m_pReaderChunk->SetBuffer((char*) SOAPString.c_str());

        try
        {
                this->m_pRequest->setOpt(new cURLpp::Options::HttpHeader(HeaderData));
                this->m_pRequest->setOpt(new cURLpp::Options::HeaderData((void*)
&HeaderData));
                this->m_pRequest->setOpt(new
cURLpp::Options::InfileSize(strlen(this->m_pReaderChunk->GetBuffer())));
        }

The request reaches the server and sends a result too!
I know this, because I've catched the outgoing and incoming packets with
"Etherreal". So I'm sure the host sends a result (and is the expected too).
But the WriterCallback doesn't work. In the "WriteMemoryCallback" the
"data" pointer is the problem. Here something seems not to be right.

I don't know if it's my fault or not... Can you please help me?
Thank you for your help!

Regards, Nazario.

-- 
Spanne den Bogen, aber schieße nicht los!
Noch gefürchtet zu sein ist wirksamer!
(altes chinesisches Sprichwort)
_______________________________________________
cURLpp mailing list
cURLpp_at_rrette.com
http://www.rrette.com/mailman/listinfo/curlpp
Received on 2005-08-05

These mail archives are generated by hypermail.

donate! Page updated November 12, 2010.
web site info

File upload with ASP.NET