Hello, I'm trying to mock an DMS API. For this, I ...
# help
o
Hello, I'm trying to mock an DMS API. For this, I upload a PDF and save the data as Base64-data in memory using the wiremock-state-extension. Something like this:
Copy code
"serveEventListeners": [
  {
    "name": "recordState",
    "parameters": {
      "context": "{{response.headers.DocumentId}}",
      "state": {
        "blob": "{{{request.bodyAsBase64}}}"
      }
    }
  }
]
Now I want to download the same data, but I can't use base64Body (see below), because base64Body doesn't support templating and I only can enter real base64 data there.
Copy code
"response": {
  "status": 200,
  "base64Body": "{{state context=(state context=request.path.documentId property='contentLocationUri') property='blob'}}",
  "headers": {
    "Content-Type": "application/octet-stream",
    "D3-Filename": "{{state context=request.path.documentId property='filename'}}"
  }
}
Neither Base64 decoding works, because it produces illegal chars.
Copy code
"response": {
  "status": 200,
  "body": "{{#base64 decode=true}}{{state context=(state context=request.path.documentId property='contentLocationUri') property='blob'}}{{/base64}}",
  "headers": {
    "Content-Type": "application/pdf",
    "D3-Filename": "{{state context=request.path.documentId property='filename'}}"
  }
}
Can someone please help me? Thanks in advance Oliver
👀 1
d
ad-hoc I can't see anything you can do different. Have to reproduce it.
The following worked for me (adapted to your examples, hopefully I did it correctly):
Copy code
"serveEventListeners": [
  {
    "name": "recordState",
    "parameters": {
      "context": "{{response.headers.DocumentId}}",
      "state": {
        "blob": "{{request.body}}"
      }
    }
  }
]
Copy code
"response": {
  "status": 200,
  "body": "{{state context=(state context=request.path.documentId property='contentLocationUri') property='blob'}}",
  "headers": {
    "Content-Type": "application/octet-stream",
    "D3-Filename": "{{state context=request.path.documentId property='filename'}}"
  }
}
o
This doesn't work for me. I still have problems with illegal / unprintable chars in the downloaded data. My uploaded PDF was 30.125 bytes, the downloaded file is 48.966 bytes.
d
did you change the config from
bodyAsBase64
to
body
as well? (that resulted in a growth in my case) . Otherwise if you have a chance to push a small repro somewhere in github? Would help me to find differences to my setup.
o
d
I used the following PDF - and it worked with your setup.
o
Your PDF has no unprintable chars. I generate a simple PDF wird Word, which has alot of unprintable chars.
d
working on a repro/manual/fix
@Lee Turnermaybe you can help me on this. I think there is an issue with the base64 handlebar helper. It works fine with the example provided in https://docs.wiremock.io/response-templating/string-encodings . However when providing the initial 24 byte of a generated PDF which include non-printable characters, the resulting binary doesn't fit anymore.
Copy code
{
  "request": {
    "method": "GET",
    "urlPathTemplate": "/download"
  },
  "response": {
    "status": 200,
    "body": "{{# base64 decode=true}}JVBERi0xLjMKJcTl8uXrp/Og0MTGCjMg{{/ base64}}",
    "headers": {
      "Content-Type": "application/pdf"
    }
  }
}
When encoding the reponse to base64 again, I get:
JVBERi0xLjMKJe+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/ve+/vQozIA==
. A rough guess would be that
com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.Base64Helper
converts the result to
String
which results in the conversion issues for non-printable characters. Can you check whether my assessment is somewhat sensible? I wonder whether a fix would be remove the String creation and simply returning the byte array but I'm not sure about the full impact of it.
l
Hey, thanks for the investigation. I am on holiday at the moment but will pick this up when I get back in the office tomorrow or the day after
👍 1
Yeah, looks like you are correct on the string conversion side of things
Copy code
public class Base64Helper implements Helper<Object> {

  @Override
  public Object apply(Object context, Options options) throws IOException {
    String value =
        options.tagType == TagType.SECTION ? options.fn(context).toString() : context.toString();

    if (Boolean.TRUE.equals(options.hash.get("decode"))) {
      return new String(decodeBase64(value));
    }

    Object paddingOption = options.hash.get("padding");
    boolean padding = paddingOption == null || Boolean.TRUE.equals(paddingOption);
    return encodeBase64(value.getBytes(), padding);
  }
}
@Oliver Jankowski Would you be able to create an issue here so we can track this and look into a fix - https://github.com/wiremock/wiremock/issues
o
Thanks for your help.