Fix a potential fd leak in AbstractDiskHttpData.delete (#10212)

Motivation:

An unexpected IOException may be thrown from `FileChannel.force`. If it happens, the `FileChannel.close` may not be invoked.

Modification:

Place the `FileChannel.close` in a finally block.

Result:

Avoid fd leak.
This commit is contained in:
feijermu 2020-04-27 13:03:45 +08:00 committed by GitHub
parent 9778f05e14
commit eb3721b971
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 2 deletions

View File

@ -250,9 +250,14 @@ public abstract class AbstractDiskHttpData extends AbstractHttpData {
if (fileChannel != null) { if (fileChannel != null) {
try { try {
fileChannel.force(false); fileChannel.force(false);
fileChannel.close();
} catch (IOException e) { } catch (IOException e) {
logger.warn("Failed to close a file.", e); logger.warn("Failed to force.", e);
} finally {
try {
fileChannel.close();
} catch (IOException e) {
logger.warn("Failed to close a file.", e);
}
} }
fileChannel = null; fileChannel = null;
} }

View File

@ -29,6 +29,9 @@ import java.io.InputStream;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class DiskFileUploadTest { public class DiskFileUploadTest {
@ -194,4 +197,22 @@ public class DiskFileUploadTest {
fis.close(); fis.close();
} }
} }
@Test
public void testDelete() throws Exception {
String json = "{\"foo\":\"bar\"}";
byte[] bytes = json.getBytes(CharsetUtil.UTF_8);
File tmpFile = null;
DiskFileUpload f1 = new DiskFileUpload("file4", "file4", "application/json", null, null, 0);
try {
assertNull(f1.getFile());
f1.setContent(Unpooled.wrappedBuffer(bytes));
assertNotNull(tmpFile = f1.getFile());
} finally {
f1.delete();
assertNull(f1.getFile());
assertNotNull(tmpFile);
assertFalse(tmpFile.exists());
}
}
} }