From 83c22beaa90abd7be3d5fb94596cd576f61ed90b Mon Sep 17 00:00:00 2001 From: Karl Mueller Date: Thu, 16 Dec 2021 11:10:02 -0800 Subject: [PATCH] use configured timeout in socket connection as well as reads --- .../java/fi/solita/clamav/ClamAVClient.java | 93 ++++++++++--------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/src/main/java/fi/solita/clamav/ClamAVClient.java b/src/main/java/fi/solita/clamav/ClamAVClient.java index 7f14e11..4e1f8ec 100644 --- a/src/main/java/fi/solita/clamav/ClamAVClient.java +++ b/src/main/java/fi/solita/clamav/ClamAVClient.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.nio.ByteBuffer; @@ -50,19 +51,22 @@ public ClamAVClient(String hostName, int port) { * @return true if the server responded with proper ping reply. */ public boolean ping() throws IOException { - try (Socket s = new Socket(hostName,port); OutputStream outs = s.getOutputStream()) { - s.setSoTimeout(timeout); - outs.write(asBytes("zPING\0")); - outs.flush(); - byte[] b = new byte[PONG_REPLY_LEN]; - InputStream inputStream = s.getInputStream(); - int copyIndex = 0; - int readResult; - do { - readResult = inputStream.read(b, copyIndex, Math.max(b.length - copyIndex, 0)); - copyIndex += readResult; - } while (readResult > 0); - return Arrays.equals(b, asBytes("PONG")); + try (Socket s = new Socket()) { + s.connect(new InetSocketAddress(hostName, port), timeout); + try (OutputStream outs = s.getOutputStream()) { + s.setSoTimeout(timeout); + outs.write(asBytes("zPING\0")); + outs.flush(); + byte[] b = new byte[PONG_REPLY_LEN]; + InputStream inputStream = s.getInputStream(); + int copyIndex = 0; + int readResult; + do { + readResult = inputStream.read(b, copyIndex, Math.max(b.length - copyIndex, 0)); + copyIndex += readResult; + } while (readResult > 0); + return Arrays.equals(b, asBytes("PONG")); + } } } @@ -78,39 +82,42 @@ public boolean ping() throws IOException { * @return server reply */ public byte[] scan(InputStream is) throws IOException { - try (Socket s = new Socket(hostName,port); OutputStream outs = new BufferedOutputStream(s.getOutputStream())) { - s.setSoTimeout(timeout); - - // handshake - outs.write(asBytes("zINSTREAM\0")); - outs.flush(); - byte[] chunk = new byte[CHUNK_SIZE]; - - try (InputStream clamIs = s.getInputStream()) { - // send data - int read = is.read(chunk); - while (read >= 0) { - // The format of the chunk is: '' where is the size of the following data in bytes expressed as a 4 byte unsigned - // integer in network byte order and is the actual chunk. Streaming is terminated by sending a zero-length chunk. - byte[] chunkSize = ByteBuffer.allocate(4).putInt(read).array(); - - outs.write(chunkSize); - outs.write(chunk, 0, read); - if (clamIs.available() > 0) { - // reply from server before scan command has been terminated. - byte[] reply = assertSizeLimit(readAll(clamIs)); - throw new IOException("Scan aborted. Reply from server: " + new String(reply, StandardCharsets.US_ASCII)); - } - read = is.read(chunk); - } + try (Socket s = new Socket()) { + s.connect(new InetSocketAddress(hostName, port), timeout); + try (OutputStream outs = new BufferedOutputStream(s.getOutputStream())) { + s.setSoTimeout(timeout); - // terminate scan - outs.write(new byte[]{0,0,0,0}); + // handshake + outs.write(asBytes("zINSTREAM\0")); outs.flush(); - // read reply - return assertSizeLimit(readAll(clamIs)); + byte[] chunk = new byte[CHUNK_SIZE]; + + try (InputStream clamIs = s.getInputStream()) { + // send data + int read = is.read(chunk); + while (read >= 0) { + // The format of the chunk is: '' where is the size of the following data in bytes expressed as a 4 byte unsigned + // integer in network byte order and is the actual chunk. Streaming is terminated by sending a zero-length chunk. + byte[] chunkSize = ByteBuffer.allocate(4).putInt(read).array(); + + outs.write(chunkSize); + outs.write(chunk, 0, read); + if (clamIs.available() > 0) { + // reply from server before scan command has been terminated. + byte[] reply = assertSizeLimit(readAll(clamIs)); + throw new IOException("Scan aborted. Reply from server: " + new String(reply, StandardCharsets.US_ASCII)); + } + read = is.read(chunk); + } + + // terminate scan + outs.write(new byte[]{0,0,0,0}); + outs.flush(); + // read reply + return assertSizeLimit(readAll(clamIs)); + } } - } + } } /**