Skip to content

Commit

Permalink
minor I/O improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Stenzel committed Mar 1, 2015
1 parent 5bd38d3 commit 9433c22
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 23 deletions.
Expand Up @@ -11,6 +11,7 @@
import java.io.IOException;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -78,17 +79,16 @@ private void addMemberDir(DavResource resource, InputContext inputContext) throw

private void addMemberFile(DavResource resource, InputContext inputContext) throws DavException {
final Path childPath = ResourcePathUtils.getPhysicalPath(resource);
SeekableByteChannel channel = null;
try {
channel = Files.newByteChannel(childPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
try (final SeekableByteChannel channel = Files.newByteChannel(childPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)) {
cryptor.encryptFile(inputContext.getInputStream(), channel);
} catch (SecurityException e) {
throw new DavException(DavServletResponse.SC_FORBIDDEN, e);
} catch (FileAlreadyExistsException e) {
throw new DavException(DavServletResponse.SC_CONFLICT, e);
} catch (IOException e) {
LOG.error("Failed to create file.", e);
throw new IORuntimeException(e);
} finally {
IOUtils.closeQuietly(channel);
IOUtils.closeQuietly(inputContext.getInputStream());
}
}
Expand Down
Expand Up @@ -16,7 +16,6 @@
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;

import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavResource;
import org.apache.jackrabbit.webdav.DavResourceFactory;
Expand Down Expand Up @@ -70,9 +69,7 @@ public void spool(OutputContext outputContext) throws IOException {
if (Files.exists(path)) {
outputContext.setModificationTime(Files.getLastModifiedTime(path).toMillis());
outputContext.setProperty(HttpHeader.ACCEPT_RANGES.asString(), HttpHeaderValue.BYTES.asString());
SeekableByteChannel channel = null;
try {
channel = Files.newByteChannel(path, StandardOpenOption.READ);
try (final SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ)) {
outputContext.setContentLength(cryptor.decryptedContentLength(channel));
if (outputContext.hasStream()) {
cryptor.decryptedFile(channel, outputContext.getOutputStream());
Expand All @@ -81,8 +78,6 @@ public void spool(OutputContext outputContext) throws IOException {
LOG.warn("Unexpected end of stream (possibly client hung up).");
} catch (DecryptFailedException e) {
throw new IOException("Error decrypting file " + path.toString(), e);
} finally {
IOUtils.closeQuietly(channel);
}
}
}
Expand All @@ -91,21 +86,22 @@ public void spool(OutputContext outputContext) throws IOException {
protected void determineProperties() {
final Path path = ResourcePathUtils.getPhysicalPath(this);
if (Files.exists(path)) {
SeekableByteChannel channel = null;
try {
channel = Files.newByteChannel(path, StandardOpenOption.READ);
try (final SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ)) {
final Long contentLength = cryptor.decryptedContentLength(channel);
properties.add(new DefaultDavProperty<Long>(DavPropertyName.GETCONTENTLENGTH, contentLength));
} catch (IOException e) {
LOG.error("Error reading filesize " + path.toString(), e);
throw new IORuntimeException(e);
}

try {
final BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
properties.add(new DefaultDavProperty<String>(DavPropertyName.CREATIONDATE, FileTimeUtils.toRfc1123String(attrs.creationTime())));
properties.add(new DefaultDavProperty<String>(DavPropertyName.GETLASTMODIFIED, FileTimeUtils.toRfc1123String(attrs.lastModifiedTime())));
properties.add(new HttpHeaderProperty(HttpHeader.ACCEPT_RANGES.asString(), HttpHeaderValue.BYTES.asString()));
} catch (IOException e) {
LOG.error("Error determining metadata " + path.toString(), e);
throw new IORuntimeException(e);
} finally {
IOUtils.closeQuietly(channel);
}
}
}
Expand Down
Expand Up @@ -9,7 +9,6 @@
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.MutablePair;
Expand Down Expand Up @@ -113,9 +112,7 @@ public void spool(OutputContext outputContext) throws IOException {
final Path path = ResourcePathUtils.getPhysicalPath(this);
if (Files.exists(path)) {
outputContext.setModificationTime(Files.getLastModifiedTime(path).toMillis());
SeekableByteChannel channel = null;
try {
channel = Files.newByteChannel(path, StandardOpenOption.READ);
try (final SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ)) {
final Long fileSize = cryptor.decryptedContentLength(channel);
final Pair<Long, Long> range = getUnionRange(fileSize);
final Long rangeLength = range.getRight() - range.getLeft() + 1;
Expand All @@ -130,8 +127,6 @@ public void spool(OutputContext outputContext) throws IOException {
}
} catch (DecryptFailedException e) {
throw new IOException("Error decrypting file " + path.toString(), e);
} finally {
IOUtils.closeQuietly(channel);
}
}
}
Expand Down
Expand Up @@ -504,9 +504,20 @@ public Long encryptFile(InputStream plaintextFile, SeekableByteChannel encrypted
final ByteBuffer macBuffer = ByteBuffer.allocate(mac.getMacLength());
encryptedFile.write(macBuffer);

// init filesize buffer and skip 16 bytes
// write initial file size = 0 into the next 16 bytes
final ByteBuffer encryptedFileSizeBuffer = ByteBuffer.allocate(AES_BLOCK_LENGTH);
encryptedFile.write(encryptedFileSizeBuffer);
try {
final ByteBuffer fileSizeBuffer = ByteBuffer.allocate(Long.BYTES);
fileSizeBuffer.putLong(0l);
final Cipher sizeCipher = aesEcbCipher(primaryMasterKey, Cipher.ENCRYPT_MODE);
final byte[] encryptedFileSize = sizeCipher.doFinal(fileSizeBuffer.array());
encryptedFileSizeBuffer.position(0);
encryptedFileSizeBuffer.put(encryptedFileSize);
encryptedFileSizeBuffer.position(0);
encryptedFile.write(encryptedFileSizeBuffer);
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new IllegalStateException("Block size must be valid, as padding is requested. BadPaddingException not possible in encrypt mode.", e);
}

// write content:
final OutputStream out = new SeekableByteChannelOutputStream(encryptedFile);
Expand Down

0 comments on commit 9433c22

Please sign in to comment.