Split out of the review of #811, where it was confirmed as pre-existing.
What happens
DSMLServlet.doPost() creates a single BatchResponse before it walks the SOAP body:
ObjectFactory objFactory = new ObjectFactory();
BatchResponse batchResponse = objFactory.createBatchResponse();
List<JAXBElement<?>> batchResponses = batchResponse.getBatchResponses();
and then, once per batchRequest of that body:
// set requestID in response
batchResponse.setRequestID(batchRequest.getRequestID());
Every response element of every batch request is appended to the same list and the requestID is overwritten on each iteration, so a SOAP body holding two batchRequest elements is answered with one batchResponse carrying the requestID of the last one and the elements of both:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body>
<ns0:batchResponse xmlns:ns0="urn:oasis:names:tc:DSML:2:0:core" requestID="2">
<ns0:authResponse><ns0:resultCode code="0" descr="success"/></ns0:authResponse>
<ns0:authResponse><ns0:resultCode code="0" descr="success"/></ns0:authResponse>
</ns0:batchResponse>
</SOAP-ENV:Body></SOAP-ENV:Envelope>
(the reply of DSMLServletTestCase.testAuthzIdIsNotAccumulatedAcrossBatchRequests, whose body carries <batchRequest requestID="1"> and <batchRequest requestID="2">).
A client cannot tell which element answers which batch request, and the requestID of every batch request but the last is lost.
Why it shows up now
The defect is as old as the imported code, but it was unobservable: the connection was reused across the loop, so the second and later batchRequest of a body were silently skipped and never produced a response element. #811 gives each batch request its own connection, so they all run — and their responses all land in the same batchResponse.
Where
opendj-dsml-servlet/src/main/java/org/opends/dsml/protocol/DSMLServlet.java, doPost().
Fix direction
Build one BatchResponse per batchRequest and marshal each into the SOAP body. The three malformed-request paths (createXMLParsingErrorResponse() and the credentials errors) build their response before the body is walked, so they need a batchResponse of their own; that is also the only reason the current single instance exists.
Split out of the review of #811, where it was confirmed as pre-existing.
What happens
DSMLServlet.doPost()creates a singleBatchResponsebefore it walks the SOAP body:and then, once per
batchRequestof that body:Every response element of every batch request is appended to the same list and the
requestIDis overwritten on each iteration, so a SOAP body holding twobatchRequestelements is answered with onebatchResponsecarrying therequestIDof the last one and the elements of both:(the reply of
DSMLServletTestCase.testAuthzIdIsNotAccumulatedAcrossBatchRequests, whose body carries<batchRequest requestID="1">and<batchRequest requestID="2">).A client cannot tell which element answers which batch request, and the
requestIDof every batch request but the last is lost.Why it shows up now
The defect is as old as the imported code, but it was unobservable: the connection was reused across the loop, so the second and later
batchRequestof a body were silently skipped and never produced a response element. #811 gives each batch request its own connection, so they all run — and their responses all land in the samebatchResponse.Where
opendj-dsml-servlet/src/main/java/org/opends/dsml/protocol/DSMLServlet.java,doPost().Fix direction
Build one
BatchResponseperbatchRequestand marshal each into the SOAP body. The three malformed-request paths (createXMLParsingErrorResponse()and the credentials errors) build their response before the body is walked, so they need abatchResponseof their own; that is also the only reason the current single instance exists.