Skip to content

Commit

Permalink
Issue #1337 Use either absolute or relative multipart file location
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Bartel <[email protected]>
  • Loading branch information
janbartel committed Aug 5, 2020
1 parent 062878f commit 42b9e8b
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
Expand Down Expand Up @@ -99,7 +100,7 @@ private enum State
private final File _contextTmpDir;
private final String _contentType;
private volatile Throwable _err;
private volatile File _tmpDir;
private volatile Path _tmpDir;
private volatile boolean _deleteOnExit;
private volatile boolean _writeFilesWithFilenames;
private volatile int _bufferSize = 16 * 1024;
Expand Down Expand Up @@ -185,12 +186,17 @@ protected void write(byte[] bytes, int offset, int length) throws IOException
@Override
public void write(String fileName) throws IOException
{
Path p = FileSystems.getDefault().getPath(fileName);

if (_file == null)
{
_temporary = false;

// part data is only in the ByteArrayOutputStream and never been written to disk
_file = new File(_tmpDir, fileName);
if (p.isAbsolute())
_file = Files.createFile(p).toFile();
else
_file = Files.createFile(_tmpDir.resolve(p)).toFile();

try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(_file)))
{
Expand All @@ -208,7 +214,7 @@ public void write(String fileName) throws IOException
_temporary = false;

Path src = _file.toPath();
Path target = src.resolveSibling(fileName);
Path target = (p.isAbsolute() ? p : _tmpDir.resolve(p));
Files.move(src, target, StandardCopyOption.REPLACE_EXISTING);
_file = target.toFile();
}
Expand All @@ -222,7 +228,7 @@ protected void createFile() throws IOException
final boolean USER = true;
final boolean WORLD = false;

_file = File.createTempFile("MultiPart", "", MultiPartFormInputStream.this._tmpDir);
_file = Files.createTempFile(MultiPartFormInputStream.this._tmpDir, "MultiPart", "").toFile();
_file.setReadable(false, WORLD); // (reset) disable it for everyone first
_file.setReadable(true, USER); // enable for user only

Expand Down Expand Up @@ -535,20 +541,20 @@ protected void parse()
{
// sort out the location to which to write the files
if (_config.getLocation() == null)
_tmpDir = _contextTmpDir;
_tmpDir = _contextTmpDir.toPath();
else if ("".equals(_config.getLocation()))
_tmpDir = _contextTmpDir;
_tmpDir = _contextTmpDir.toPath();
else
{
File f = new File(_config.getLocation());
if (f.isAbsolute())
_tmpDir = f;
Path location = FileSystems.getDefault().getPath(_config.getLocation());
if (location.isAbsolute())
_tmpDir = location;
else
_tmpDir = new File(_contextTmpDir, _config.getLocation());
_tmpDir = _contextTmpDir.toPath().resolve(location);
}

if (!_tmpDir.exists())
_tmpDir.mkdirs();
if (!Files.exists(_tmpDir))
Files.createDirectories(_tmpDir);

String contentTypeBoundary = "";
int bstart = _contentType.indexOf("boundary=");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Base64;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -453,7 +454,7 @@ public void testFileTooBigThrowsErrorOnGetParts()
}

@Test
public void testPartFileNotDeleted() throws Exception
public void testPartFileRelative() throws Exception
{
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(createMultipartRequestString("tptfd").getBytes()),
Expand All @@ -465,7 +466,7 @@ public void testPartFileNotDeleted() throws Exception

MultiPart part = (MultiPart)mpis.getPart("stuff");
File stuff = part.getFile();
assertThat(stuff, notNullValue()); // longer than 100 bytes, should already be a tmp file
assertThat(stuff, notNullValue()); // longer than 50 bytes, should already be a tmp file
part.write("tptfd.txt");
File tptfd = new File(_dirname + File.separator + "tptfd.txt");
assertThat(tptfd.exists(), is(true));
Expand All @@ -474,7 +475,77 @@ public void testPartFileNotDeleted() throws Exception
assertThat(tptfd.exists(), is(true)); //explicitly written file did not get removed after cleanup
tptfd.deleteOnExit(); //clean up test
}

@Test
public void testPartFileAbsolute() throws Exception
{
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 50);
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(createMultipartRequestString("tpfa").getBytes()),
_contentType,
config,
_tmpDir);
mpis.setDeleteOnExit(true);
mpis.getParts();

MultiPart part = (MultiPart)mpis.getPart("stuff");
File stuff = part.getFile();
assertThat(stuff, notNullValue()); // longer than 50 bytes, should already be a tmp file
Path path = MavenTestingUtils.getTargetTestingPath().resolve("tpfa.txt");
part.write(path.toFile().getAbsolutePath());
File tpfa = path.toFile();
assertThat(tpfa.exists(), is(true));
assertThat(stuff.exists(), is(false)); //got renamed
part.cleanUp();
assertThat(tpfa.exists(), is(true)); //explicitly written file did not get removed after cleanup
tpfa.deleteOnExit(); //clean up test
}

@Test
public void testPartFileAbsoluteFromBuffer() throws Exception
{
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 5000);
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(createMultipartRequestString("tpfafb").getBytes()),
_contentType,
config,
_tmpDir);
mpis.setDeleteOnExit(true);
mpis.getParts();

MultiPart part = (MultiPart)mpis.getPart("stuff");
//Content should still be in the buffer, because the length is < 5000,
assertNull(part.getFile());
//test writing to an absolute filename
Path path = MavenTestingUtils.getTargetTestingPath().resolve("tpfafb.txt");
part.write(path.toFile().getAbsolutePath());
File tpfafb = path.toFile();
assertThat(tpfafb.exists(), is(true));
part.cleanUp();
assertThat(tpfafb.exists(), is(true)); //explicitly written file did not get removed after cleanup
tpfafb.deleteOnExit(); //clean up test
}

@Test
public void testPartFileRelativeFromBuffer() throws Exception
{
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 3072, 5000);
MultiPartFormInputStream mpis = new MultiPartFormInputStream(new ByteArrayInputStream(createMultipartRequestString("tpfrfb").getBytes()),
_contentType,
config,
_tmpDir);
mpis.setDeleteOnExit(true);
mpis.getParts();

MultiPart part = (MultiPart)mpis.getPart("stuff");
//Content should still be in the buffer, because the length is < 5000,
assertNull(part.getFile());
//test writing to a relative filename
part.write("tpfrfb.txt");
File tpfrfb = new File(_tmpDir, "tpfrfb.txt");
assertThat(tpfrfb.exists(), is(true));
part.cleanUp();
assertThat(tpfrfb.exists(), is(true)); //explicitly written file did not get removed after cleanup
tpfrfb.deleteOnExit(); //clean up test
}
@Test
public void testPartTmpFileDeletion() throws Exception
{
Expand All @@ -488,7 +559,7 @@ public void testPartTmpFileDeletion() throws Exception

MultiPart part = (MultiPart)mpis.getPart("stuff");
File stuff = part.getFile();
assertThat(stuff, notNullValue()); // longer than 100 bytes, should already be a tmp file
assertThat(stuff, notNullValue()); // longer than 50 bytes, should already be a tmp file
assertThat(stuff.exists(), is(true));
part.cleanUp();
assertThat(stuff.exists(), is(false)); //tmp file was removed after cleanup
Expand Down

0 comments on commit 42b9e8b

Please sign in to comment.