Search code examples
javarestcurlmultipart

Comma(,) specified in file name makes curl processor fail to send a request


I have a Curl processor class which is used to send requests and get response as a plain string.

It worked like a charm, however recently I've encountered a problem. The problem has to do with sending multipart data. So, if there's a comma (perphaps other special character) specified in multipart body, it doesn't even send any request.

Here's what I mean (main method below)

public static String buildCurlProcessBuilderExecuteAndGetResponse(String httpMethod, String URL, List<String> headers, List<String> body, boolean includeResponseHeaders) throws IOException 
{
        List<String> finalCommands = new ArrayList<String>();

        finalCommands.add("/usr/local/bin/curl");
        finalCommands.add("-s");
        finalCommands.add("-k");

        if (includeResponseHeaders) 
        {
            finalCommands.add("-i");
        }

        finalCommands.add("-X");
        finalCommands.add(httpMethod);

        finalCommands.add(URL);

        if (headers != null) 
        {
            finalCommands.addAll(headers);
        }

        if (body != null) 
        {
            finalCommands.addAll(body);
        }

        ProcessBuilder pb = new ProcessBuilder(finalCommands);
        pb.redirectErrorStream(true);       
        Process p = pb.start();
        return getResponseAsString(p.getInputStream());
}

I add multipart body like so:

public static List<String> addMultipartBodyToCurlRequest(Map<String, String> mapOfheadersToAdd) 
{
        Iterator<Entry<String, String>> multipartBodyIt = mapOfheadersToAdd.entrySet().iterator();
        List<String> bodyCommand = new ArrayList<String>();

        while (multipartBodyIt.hasNext())
        {       
            Map.Entry pair = (Map.Entry) multipartBodyIt.next();

            bodyCommand.add(CURL_MULTIPART_BODY_IDENTIFIER); // "-F";
            bodyCommand.add((String) pair.getKey() + "=" + (String) pair.getValue());
        }

        return bodyCommand;
}

I put the following properties to the body:

generatedBody.put("entityId", entityId);
generatedBody.put("SystemFolderID", systemFolderId);
generatedBody.put("resumableTotalSize", fileSize);
generatedBody.put("resumableFilename", fileName);
generatedBody.put("resumableRelativePath", fileName);
generatedBody.put("resumableIdentifier", fileUUID);
generatedBody.put("entityName", entityName);
generatedBody.put("resumableType", resumableType);
generatedBody.put("resumableTotalChunks", totalChunksSize);

And also

generatedBody.put("resumableChunkNumber", String.valueOf(i + 1));
generatedBody.put("resumableChunkSize", String.valueOf(chunkByteArray.length));
generatedBody.put("resumableCurrentChunkSize", String.valueOf(chunkByteArray.length));
generatedBody.put("file", "@" + currentChunk.getAbsolutePath() + ";" + "filename=" + fileName);

Then I call the method:

List<String> fileBody = CURLRequestProcessor.addMultipartBodyToCurlRequest(generatedBody);

And finally call

CURLRequestProcessor.buildCurlProcessBuilderExecuteAndGetResponse("POST", finalURL, generatedHeaders, fileBody, false)

But I don't get printed anything... It seems like one simple comma in the name of the file screwed everything up... It's used in the resumableFilename, resumableRelativePath and file parts.

Without comma in the name everything works. Is there a way to escape or do anything?

Btw, it's run on Ubuntu.

Almost forgot, PLEASE DON'T ASK ME WHY I'M USING CURL OVER any other HTTP client. I have to due to TLS

Thank you very much in advance!


Solution

  • The solution turned out to be simple yet peculiar.

    The problem had to do with this line:

    generatedBody.put("file", "@" + currentChunk.getAbsolutePath() + ";" + "filename=" + fileName);
    

    I changed it to:

    generatedBody.put("file", "@" + currentChunk.getAbsolutePath());
    

    Since I send the name of the file in 2 additional body parts called resumableFilename and resumableRelativePath, so specifying filename is redundant. In the latter comma screws up, while with these two parts comma doesn't matter

    I wonder what if didn't have these though...