package org.commcare.network;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MIME;
import org.apache.http.entity.mime.content.AbstractContentBody;
import org.javarosa.core.io.StreamsUtil;
import org.javarosa.core.io.StreamsUtil.InputIOException;
import org.javarosa.core.io.StreamsUtil.OutputIOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
/**
* @author ctsims
*/
public class EncryptedFileBody extends AbstractContentBody {
private final File file;
private final Cipher cipher;
public EncryptedFileBody(File file, Cipher cipher, ContentType contentType) {
super(contentType);
this.file = file;
this.cipher = cipher;
}
@Override
public String getFilename() {
return file.getName();
}
@Override
public String getCharset() {
return MIME.DEFAULT_CHARSET.name();
}
@Override
public long getContentLength() {
return -1;
}
@Override
public String getTransferEncoding() {
return MIME.ENC_BINARY;
}
@Override
public void writeTo(OutputStream out) throws IOException {
//The only time this can cause issues is if the body has disappeared since construction. Don't worry about that, since
//it'll get caught when we initialize.
CipherInputStream cis = new CipherInputStream(new FileInputStream(file), cipher);
try {
StreamsUtil.writeFromInputToOutputUnmanaged(cis, out);
} catch (InputIOException iioe) {
//Here we want to retain the fundamental problem of the _input_ being responsible for the issue
//so we can differentiate between bad reads and bad network
throw iioe;
} catch (OutputIOException oe) {
//We want the original exception here.
throw oe.getWrapped();
} finally {
cis.close();
}
}
}