Fix a potential fd leak in AbstractDiskHttpData.setContent (#10198)

Motivation:

`RandomAccessFile.setLength` may throw an IOException. We must deal with this in case of the occurrence of `I/O` error.

Modification:

Place the `RandomAccessFile.setLength` method call in the `try-finally` block.

Result:

Avoid fd leak.
This commit is contained in:
feijermu 2020-04-21 16:54:09 +08:00 committed by GitHub
parent 37948bc9de
commit 32e32fe98f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 2 deletions

View File

@ -124,8 +124,8 @@ public abstract class AbstractDiskHttpData extends AbstractHttpData {
return;
}
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
accessFile.setLength(0);
try {
accessFile.setLength(0);
FileChannel localfileChannel = accessFile.getChannel();
ByteBuffer byteBuffer = buffer.nioBuffer();
int written = 0;
@ -216,9 +216,9 @@ public abstract class AbstractDiskHttpData extends AbstractHttpData {
}
file = tempFile();
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
accessFile.setLength(0);
int written = 0;
try {
accessFile.setLength(0);
FileChannel localfileChannel = accessFile.getChannel();
byte[] bytes = new byte[4096 * 4];
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);

View File

@ -15,6 +15,8 @@
*/
package io.netty.handler.codec.http.multipart;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
@ -23,6 +25,7 @@ import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@ -130,4 +133,65 @@ public class DiskFileUploadTest {
f1.delete();
}
}
@Test
public void testSetContentFromByteBuf() throws Exception {
DiskFileUpload f1 = new DiskFileUpload("file2", "file2", "application/json", null, null, 0);
try {
String json = "{\"hello\":\"world\"}";
byte[] bytes = json.getBytes(CharsetUtil.UTF_8);
f1.setContent(Unpooled.wrappedBuffer(bytes));
assertEquals(json, f1.getString());
assertArrayEquals(bytes, f1.get());
File file = f1.getFile();
assertEquals((long) bytes.length, file.length());
assertArrayEquals(bytes, doReadFile(file, bytes.length));
} finally {
f1.delete();
}
}
@Test
public void testSetContentFromInputStream() throws Exception {
String json = "{\"hello\":\"world\",\"foo\":\"bar\"}";
DiskFileUpload f1 = new DiskFileUpload("file3", "file3", "application/json", null, null, 0);
try {
byte[] bytes = json.getBytes(CharsetUtil.UTF_8);
ByteBuf buf = Unpooled.wrappedBuffer(bytes);
InputStream is = new ByteBufInputStream(buf);
try {
f1.setContent(is);
assertEquals(json, f1.getString());
assertArrayEquals(bytes, f1.get());
File file = f1.getFile();
assertEquals((long) bytes.length, file.length());
assertArrayEquals(bytes, doReadFile(file, bytes.length));
} finally {
buf.release();
is.close();
}
} finally {
f1.delete();
}
}
private static byte[] doReadFile(File file, int maxRead) throws Exception {
FileInputStream fis = new FileInputStream(file);
try {
byte[] buf = new byte[maxRead];
int offset = 0;
int read = 0;
int len = buf.length;
while ((read = fis.read(buf, offset, len)) > 0) {
len -= read;
offset += read;
if (len <= 0 || offset >= buf.length) {
break;
}
}
return buf;
} finally {
fis.close();
}
}
}