Close the file when IOException occurs in AbstractMemoryHttpData. (#10157)

Motivation:

An IOException may be thrown from FileChannel.read, and cause the fd leak.

Modification:

Close the file when IOException occurs.

Result:
Avoid fd leak.
This commit is contained in:
feijermu 2020-04-02 20:16:01 +08:00 committed by GitHub
parent ea31b59037
commit d4c268ae3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 10 deletions

View File

@ -132,15 +132,22 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
}
checkSize(newsize);
RandomAccessFile accessFile = new RandomAccessFile(file, "r");
FileChannel fileChannel = accessFile.getChannel();
byte[] array = new byte[(int) newsize];
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
int read = 0;
while (read < newsize) {
read += fileChannel.read(byteBuffer);
ByteBuffer byteBuffer;
try {
FileChannel fileChannel = accessFile.getChannel();
try {
byte[] array = new byte[(int) newsize];
byteBuffer = ByteBuffer.wrap(array);
int read = 0;
while (read < newsize) {
read += fileChannel.read(byteBuffer);
}
} finally {
fileChannel.close();
}
} finally {
accessFile.close();
}
fileChannel.close();
accessFile.close();
byteBuffer.flip();
if (byteBuf != null) {
byteBuf.release();

View File

@ -19,22 +19,51 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.util.internal.PlatformDependent;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Random;
import java.util.UUID;
import static io.netty.util.CharsetUtil.*;
import static org.junit.Assert.*;
/** {@link AbstractMemoryHttpData} test cases. */
public class AbstractMemoryHttpDataTest {
@Test
public void testSetContentFromFile() throws Exception {
TestHttpData test = new TestHttpData("test", UTF_8, 0);
try {
File tmpFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp");
tmpFile.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tmpFile);
byte[] bytes = new byte[4096];
PlatformDependent.threadLocalRandom().nextBytes(bytes);
try {
fos.write(bytes);
fos.flush();
} finally {
fos.close();
}
test.setContent(tmpFile);
ByteBuf buf = test.getByteBuf();
assertEquals(buf.readerIndex(), 0);
assertEquals(buf.writerIndex(), bytes.length);
assertArrayEquals(bytes, test.get());
assertArrayEquals(bytes, ByteBufUtil.getBytes(buf));
} finally {
//release the ByteBuf
test.delete();
}
}
/**
* Provide content into HTTP data with input stream.
*