use of org.apache.jmeter.protocol.http.util.DirectAccessByteArrayOutputStream in project jmeter by apache.
the class HTTPSamplerBase method readResponse.
/**
* Read response from the input stream, converting to MD5 digest if the useMD5 property is set.
* <p>
* For the MD5 case, the result byte count is set to the size of the original response.
* <p>
* Closes the inputStream
*
* @param sampleResult sample to store information about the response into
* @param in input stream from which to read the response
* @param length expected input length or zero
* @return the response or the MD5 of the response
* @throws IOException if reading the result fails
*/
public byte[] readResponse(SampleResult sampleResult, InputStream in, long length) throws IOException {
OutputStream w = null;
try (Closeable ignore = in) {
// NOSONAR No try with resource as performance is critical here
// 8kB is the (max) size to have the latency ('the first packet')
byte[] readBuffer = new byte[8192];
// Enough for MD5
int bufferSize = 32;
MessageDigest md = null;
// may also happen if long value > int.max
boolean knownResponseLength = length > 0;
if (useMD5()) {
try {
// $NON-NLS-1$
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
log.error("Should not happen - could not find MD5 digest", e);
}
} else {
if (!knownResponseLength) {
bufferSize = 4 * 1024;
} else {
bufferSize = (int) Math.min(MAX_BUFFER_SIZE, length);
}
}
int bytesReadInBuffer = 0;
long totalBytes = 0;
boolean first = true;
boolean storeInBOS = true;
while ((bytesReadInBuffer = in.read(readBuffer)) > -1) {
if (first) {
sampleResult.latencyEnd();
first = false;
if (md == null) {
if (!knownResponseLength) {
w = new org.apache.commons.io.output.ByteArrayOutputStream(bufferSize);
} else {
w = new DirectAccessByteArrayOutputStream(bufferSize);
}
}
}
if (md == null) {
if (storeInBOS) {
if (MAX_BYTES_TO_STORE_PER_REQUEST <= 0 || (totalBytes + bytesReadInBuffer <= MAX_BYTES_TO_STORE_PER_REQUEST) || JMeterContextService.getContext().isRecording()) {
w.write(readBuffer, 0, bytesReadInBuffer);
} else {
log.debug("Big response, truncating it to {} bytes", MAX_BYTES_TO_STORE_PER_REQUEST);
w.write(readBuffer, 0, (int) (MAX_BYTES_TO_STORE_PER_REQUEST - totalBytes));
storeInBOS = false;
}
}
} else {
md.update(readBuffer, 0, bytesReadInBuffer);
}
totalBytes += bytesReadInBuffer;
}
if (first) {
// Bug 46838 - if there was no data, still need to set latency
sampleResult.latencyEnd();
return new byte[0];
}
if (md == null) {
return toByteArray(w);
} else {
byte[] md5Result = md.digest();
sampleResult.setBytes(totalBytes);
return JOrphanUtils.baToHexBytes(md5Result);
}
} finally {
IOUtils.closeQuietly(w, null);
}
}
Aggregations