Hello everyone once again. I can't seem to read POST content using this xpage/xAgent:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false"
viewState="nostate" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.beforeRenderResponse>
<![CDATA[#{javascript:
var xagentprocessor = new com.my.test.XagentProcessor;
xagentprocessor.process();
}]]>
</xp:this.beforeRenderResponse>
</xp:view>
Which is running this code to simply reflect back to the browser the data that was submitted:
public class XagentProcessor {
public void process() {
try {
byte[] body = Util.getPostRequestBytes();
Util.sendResponseBytes(body);
} catch (Exception e) {
System.out.println("Error in XagentProcessor process() method:"+e.toString());
}
}
}
Which invokes this static method in my utility class (thanks John Dalsgaard for the tip there) which uses code I pinched from here.
public static byte[] getPostRequestBytes() {
HttpServletRequest request = getHttpRequest();
try {
ServletInputStream is = request.getInputStream();
int length=request.getContentLength(); //This is definitely nonzero
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
} catch (IOException e) {
System.out.print("Error in Util.getPostRequestText() method:" + e.toString());
}
return new byte[0];
}
My issue is that this returns no content, the first read of the inputstream returns -1. This might be related to this post in that if I don't put a $$viewid field in the POST request then it throws an error. This leads me to believe that domino has already read the input stream (as it knows about the missing field) so it's not available to the getPostRequestBytes
method.
Any ideas anyone? My options are to either read the stream again, which I don't think is possible or get Domino not to read it to check for the $$viewid field. I'm really scratching my head now. All help very much appreciated indeed!
As per this post, the issue when submitting forms with xsp.csrf.protection
setting equals to true
causes domino to capture the stream and look for the $$viewid field, thus preventing any data from the ServletInputStream being read (as it's been read once already). This now works for all content types other than multipart/form-data
. To work around this, set xsp.csrf.protection=false
in the application configuration -> Xsp Properties. Set Content-Type
to application/octet-stream
in the client side script when building the request (e.g. using the Fetch API) and the request body is then made available to the agent.
Any CSRF protection would have to be baked in manually, however.