in src/main/java/org/apache/sling/commons/clam/internal/ClamdService.java [185:230]
private ScanResult doInstream(final InputStream inputStream) throws IOException, InstreamSizeLimitExceededException {
logger.info("connecting to clam daemon at {}:{} for scanning", configuration.clamd_host(), configuration.clamd_port());
final long started = System.currentTimeMillis();
try (Socket socket = new Socket(configuration.clamd_host(), configuration.clamd_port());
OutputStream out = new BufferedOutputStream(socket.getOutputStream());
InputStream in = socket.getInputStream()) {
socket.setSoTimeout(configuration.connection_timeout());
// send command
out.write(INSTREAM_COMMAND);
out.flush();
// send data in chunks
final byte[] data = new byte[configuration.chunk_length()];
long total = 0;
int read = inputStream.read(data);
while (read >= 0) {
logger.trace("current chunk length: {}", read);
total = total + read;
final byte[] length = ByteBuffer.allocate(CHUNK_LENGTH_DATUM_SIZE).putInt(read).array();
out.write(length);
out.write(data, 0, read);
// handle premature reply
if (in.available() > 0) {
logger.info("total bytes sent: {}", total);
final byte[] reply = IOUtils.toByteArray(in);
throw new InstreamSizeLimitExceededException(reply, started, total);
}
read = inputStream.read(data);
}
logger.info("total bytes sent: {}", total);
// terminate by sending a zero-length chunk
out.write(new byte[]{0, 0, 0, 0});
out.flush();
// return reply on complete
final byte[] reply = IOUtils.toByteArray(in);
return parseClamdReply(reply, started, total);
}
}