W3C home > Mailing lists > Public > www-lib@w3.org > July to September 2002

Multipart MIME Failing - Anyone cast a helpful eye over this sourcecode (embedded within)???

From: Damien Dougan <ddougan@totalise.co.uk>
Date: Wed, 7 Aug 2002 16:57:53 +0100
To: www-lib@w3.org
Message-ID: <3D548539@mail.totalise.co.uk>

Hi All,

I'm at a loss with the Multipart MIME handling - I've been banging my head 
against the wall for too long :(

The code below is a fragment of my program. It takes in a HttpRequestPtr (no 
need to see the details, but it simply encapsulates a URL, and the contents of 
the files that are to be uploaded to the server).

The POST operation is issued, and I get a response from the server so the 
communication is working, but the Server never receives the data (or more 
likely, it has received it but it is not in the correct format). The logging 
appears to look like valid data...

Any help would be much appreciated!

The first part of the code below is simply getting the data into a source 
Anchor for POSTing. I'm not sure if this is where the error is (in building 
the multipart), or if it is in the second part (actually issueing the POST via 
libwww).

Thanks,

Damien



HttpResponsePtr HttpLib::DoMultiPartPost (const HttpRequestPtr& req)
{
	// MimeDataContainerPtr is a pointer to a MimeDataContainer which
	// has a vector of Parts - text, binary etc that are contents of
	// files to be uploaded
     MimeDataContainerPtr spParts = req->Parts();

	// String is a wrapper around std::string
     String baseBoundary = "boundaryString";
     String boundary = "\r\n--" + baseBoundary + "\r\n";
     String endBoundary = "\r\n--" + baseBoundary + "--\r\n";


     // url to be posted to
     String urlMsgId = req->Url();

     // for storing the MIME data
     // a ByteFieldPtr is a pointer to a ByteField which
     // is a vector of Byte (unsigned char)
     ByteFieldPtr spBytes (new Util::ByteField);
     String document = "";
     Byte* data = NULL;


     // we will POST the multipart form via an anchor
     HTParentAnchor* src = HTTmpAnchor(NULL);

    // set content type to multipart
    HTAnchor_setFormat(src,HTAtom_for("multipart/form-data"));
    HTAnchor_addFormatParam (src, "boundary", descBoundary.c_str());


    // used to make the filename for the corresponding name in the form
    int file=1;

    // build the multipart request
    // for each part in the request
    for (MimeDataContainer::iterator itPart = spParts->begin();
         itPart != spParts->end();
         ++itPart
        )
    {
        // add the boundaryStr
        for (unsigned int i=0; i < boundary.size(); i++)
        {
            spBytes->push_back ((Byte)boundary[i]);
        }

        // add the header
        String header ("Content-Disposition: form-data; name=\"file");
        std::stringstream ss;
        Util::String fileStr;
        ss << file;
        ss >> fileStr;
        header += fileStr;
        header = header + "\"\r\n\r\n";

        for (unsigned int i=0; i < header.size(); i++)
        {
            spBytes->push_back ((Util::Byte)header[i]);
        }



        // get the current part data
        if ((*itPart)->IsText())
        {
            unsigned int docSize = (*itPart)->MimeDocument().size();
            String doc ((*itPart)->MimeDocument());

            for (unsigned int i=0; i < docSize; i++)
            {
                spBytes->push_back ((Byte) doc[i]);
            }
        }
        else
        {
            ByteFieldPtr spObj = (*itPart)->MimeObject();
            unsigned int objSize = spObj->size();

            for (unsigned int i=0; i < objSize; i++)
            {
                spBytes->push_back (spObj->at(i));

            }
        }
        file++;

    }

    // add the endBoundary
    for (unsigned int i=0; i < endBoundary.size(); i++)
    {
        spBytes->push_back ((Util::Byte)endBoundary[i]);
    }

    // copy to a Byte* for use with libwww functions
    int byteSize = spBytes->size();
    data = new Byte[byteSize];

    for (int i = 0; i < byteSize; i++)
    {
        data[i] = spBytes->at(i);
    }


    // build the document for the request
    HTAnchor_setDocument(src,(char*)data);
    HTAnchor_setLength(src,byteSize);

    HTNet_addAfter (terminateHandler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
    HTHost_setEventTimeout (m_timeout);

    // make a new request
    HTRequest* request = HTRequest_new();
    HTRequest_setOutputFormat (request, WWW_SOURCE);


    // need to set the format
    HTAnchor_setFormat(src,HTAtom_for("multipart/form-data"));

    // post this part
    HTAnchor* dest = HTAnchor_findAddress(urlMsgId.c_str());

    int status = HTPostAnchor(src,dest,request);

    HTEventList_loop (request);


    HTResponse* response = HTRequest_response (request);

    delete (data);

    // DELETED - stuff to make a HttpResponsePtr
    // ...

    return spHttpResponse;
}

Totalise - the Users ISP
----------------------
To become a member and a shareholder
visit http://www.totalise.net
Received on Wednesday, 7 August 2002 11:53:56 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 23 April 2007 18:18:42 GMT