Search code examples
javajmeterbase64beanshell

JMeter not decoding base64 correctly - Results in blank PDF


In JMeter, I get a base64 encoded PDF in a Response that I extract using the RegEx Extractor. That is all working great.

Then I need to decode that base64 encoded document and write it out to a file, which I'm doing with the following in a BeanShell Post Processor:

import org.apache.commons.io.FileUtils;
import org.apache.commons.codec.binary.Base64;

// Set the response variable
String response = vars.get("documentText");

// Remove the carriage return hex code and condense to single string
String encodedFile = response.replace("
","").replaceAll("[\n]+","");

// Decode the encoded string
vars.put("decodedFile",new String(Base64.decodeBase64(encodedFile)));

// Write out the decoded file
Output = vars.get("decodedFile");
f = new FileOutputStream("C:\\Users\\user\\Desktop\\decodedFile.pdf");
p = new PrintStream(f); 
this.interpreter.setOut(p); 
print(Output);
p.flush();
f.close();

My problem is that the file that gets decoded and written out opens as a blank PDF.

In troubleshooting this, I wrote out a file with the encoded string from JMeter and then manually decoded it using this base64 tool. When I manually decoded the file, it opened as expected.

I then compared the text of the file that was produced by JMeter and the one I decoded with the tool and noticed that the file produced by JMeter included random ?'s throughout

I am assuming this must be the culprit, however, I do not know what is causing these to show up or how to fix it.


Solution

  • JMeter is not decoding Base64 correctly because JMeter cannot decode Base64. If you are using some custom code to do it I would suggest look into this code first.

    1. Given you need to do this magic:

      String encodedFile = response.replace("
","").replaceAll("[\n]+","");
      

      my expectation is that your either your regular expression or server response is shitty

    2. Given you use scripting-based post-processor you ain't gonna need this "regex" interim step, you should be able to access parent sampler response from Beanshell PostProcessor via data shorthand

    So your great script can be optimized into something like:

    FileUtils.writeByteArrayToFile(new File("C:\\Users\\user\\Desktop\\decodedFile.pdf"), Base64.decodeBase64(data));
    

    As a fallback option you can execute this decb64.exe program using OS Process Sampler.