[BUG] URL withPOSTData and withFileToUpload


#1
URL testUrl( ... );
testUrl = testUrl.withPOSTData( ... );
testUrl = testUrl.withFileToUpload( ... );

The post data is not received on the other side.  It should be possible to send both.

https://github.com/julianstorer/JUCE/blob/4889822eaf7d7d45f9f0c02fe5c298efff764bd5/modules/juce_core/network/juce_URL.cpp#L159 

Edit: better formatting


#2

Hmm.. Yes, it looks like it just needs a minor tweak:

    static void createHeadersAndPostData (const URL& url, String& headers, MemoryBlock& postData)
    {
        MemoryOutputStream data (postData, false);

        data << getMangledParameters (url);

        if (url.getFilesToUpload().size() > 0)
        {
            // need to upload some files, so do it as multi-part...
            const String boundary (String::toHexString (Random::getSystemRandom().nextInt64()));

            headers << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n";

            data << "--" << boundary;

            for (int i = 0; i < url.getParameterNames().size(); ++i)
            {
                data << "\r\nContent-Disposition: form-data; name=\""
                     << url.getParameterNames() [i]
                     << "\"\r\n\r\n"
                     << url.getParameterValues() [i]
                     << "\r\n--"
                     << boundary;
            }

            for (int i = 0; i < url.getFilesToUpload().size(); ++i)
            {
                const File file (url.getFilesToUpload().getAllValues() [i]);
                const String paramName (url.getFilesToUpload().getAllKeys() [i]);

                data << "\r\nContent-Disposition: form-data; name=\"" << paramName
                     << "\"; filename=\"" << file.getFileName() << "\"\r\n";

                const String mimeType (url.getMimeTypesOfUploadFiles()
                                          .getValue (paramName, String()));

                if (mimeType.isNotEmpty())
                    data << "Content-Type: " << mimeType << "\r\n";

                data << "Content-Transfer-Encoding: binary\r\n\r\n"
                     << file << "\r\n--" << boundary;
            }

            data << "--\r\n";
        }
        else
        {
            data << url.getPostData();

            // if the user-supplied headers didn't contain a content-type, add one now..
            if (! headers.containsIgnoreCase ("Content-Type"))
                headers << "Content-Type: application/x-www-form-urlencoded\r\n";

            headers << "Content-length: " << (int) data.getDataSize() << "\r\n";
        }
    }

..but I don't have a server target that I could actually test that with, so would be good to know if it works for you!


#3

That creates an invalid form.  I believe we're more after url.getPostData(); anyway.


#4

Ok, well after I posted this I actually changed a bunch of other stuff, so take a look at that.

And if you have some example code I could try that demonstrates the problems you're having, that'd make it easier for me to get this right.