Best way to keep plus signs in URL


#1

I am building an tool that passes JSONs to a server. This JSON sometimes contains plus signs, for example in the form of a base64 encoded png. The JSON is stored in a database on the server side for later use. If I use a juce::URL for passing data to the server, the plus signs are replaced with spaces like this in juce_URL.cpp and it is thus not possible to decode the image.

String URL::removeEscapeChars (const String& s)
{
    String result (s.replaceCharacter ('+', ' '));
    // ...
}

This is in compliance with standards and all, but poses a little issue for me. I seem to have a few solutions, all with a few drawbacks. The tool is internal only.

  1. Parse the JSON on the server side and replace spaces with plus signs. This will mean a lot of unpretty code on my side and the code is likely to be error prone. The structure and length of the JSON is not known up front.
  2. Do not use juce::URL and build the URL on my own. This is of course possible, but kinda defeats the purpose of the URL class. This may also be error prone.
  3. Just skip the replacing of plus signs above (i.e. replace with String result = s;). This actually works for my current JSONs, but it might have unknown side effects at a later stage. It could also become an issue when upgrading the Juce library later and then forgetting to perform this change again.
  4. Before decoding an image, just replace all spaces with a plus sign. This also works, but might have unknown side effects, although I cannot really think of anyone at this point.

Of these solutions, 3 and 4 seems best to me, but is there a better solution to this problem? I could not really find a way in the juce:URL class to skip the replacing of plus signs.


#2

I'm having one of those days today so forgive me if I'm way off beam here, but can't you pass the JSON data in a MemoryBlock using withDataToUpload()?


#3

Ok, so i fiddled around with this and it seems to work, except that I am seemingly creating the MemoryBlock in the wrong way. Using sizeof makes it too short, while using something random, like 4096, makes it too long. What did I not understand of the MemoryBlock?

void HTTP::sendQAResultJson(const juce::String& qaJsonString)
{
    juce::URL url = juce::URL("http://192.168.98.2:3000/add_qa_results_json");
    juce::String* requestString = new String(qaJsonString);
    //url = url.withDataToUpload("qa_results_json", "", juce::MemoryBlock(requestString, sizeof(requestString)), "json");
    url = url.withDataToUpload("qa_results_json", "", juce::MemoryBlock(requestString, 4096), "json");
    mThreadPool->addJob(new SendQAResultsThreadPoolJob(url), true);
}

#4
MemoryBlock(qaJsonString.toUTF8().getAddress(),qaJsonString.getNumBytesAsUTF8());

 

No need to new a string(as it'll leak), and you need to get a string representation out of the memory block. Your first sizeof would be the size of a pointer. The getNumBytesAsUTF8 function returns the number of bytes needed to store the string


#5

Perfect! Thanks for helping out yes