diff --git a/source/ch/cyberduck/core/AbstractPath.java b/source/ch/cyberduck/core/AbstractPath.java index 3407282cf3f..74336c0642a 100644 --- a/source/ch/cyberduck/core/AbstractPath.java +++ b/source/ch/cyberduck/core/AbstractPath.java @@ -440,4 +440,9 @@ public boolean isWritable() { || perm.getGroupPermissions()[Permission.WRITE] || perm.getOtherPermissions()[Permission.WRITE]; } + + /** + * Calculate the MD5 sum as Hex-encoded string or null if failure + */ + public abstract void readChecksum(); } \ No newline at end of file diff --git a/source/ch/cyberduck/core/Attributes.java b/source/ch/cyberduck/core/Attributes.java index 2775e32349e..ae13da58fed 100644 --- a/source/ch/cyberduck/core/Attributes.java +++ b/source/ch/cyberduck/core/Attributes.java @@ -96,4 +96,8 @@ public interface Attributes { public abstract String getOwner(); public abstract String getGroup(); + + public abstract String getChecksum(); + + public abstract void setChecksum(String md5); } \ No newline at end of file diff --git a/source/ch/cyberduck/core/Local.java b/source/ch/cyberduck/core/Local.java index 832877d0c5d..1d07229d3ac 100644 --- a/source/ch/cyberduck/core/Local.java +++ b/source/ch/cyberduck/core/Local.java @@ -24,9 +24,11 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import org.jets3t.service.utils.ServiceUtils; import java.io.*; import java.net.MalformedURLException; +import java.security.NoSuchAlgorithmException; import java.util.Collections; import java.util.List; @@ -100,10 +102,18 @@ public void setGroup(String group) { ; } + /** + * + * @return Always null + */ public String getOwner() { return null; } + /** + * + * @return Always null + */ public String getGroup() { return null; } @@ -435,8 +445,30 @@ public String toURL() { } } + private String checksum; + + @Override + public void readChecksum() { + try { + ServiceUtils.toHex(ServiceUtils.computeMD5Hash(new InputStream(this))); + } + catch(NoSuchAlgorithmException e) { + log.error("MD5 failed:" + e.getMessage()); + } + catch(IOException e) { + log.error("MD5 failed:" + e.getMessage()); + } + } + + public String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } + /** - * * @return True if application was found to open the file with */ public abstract boolean open(); diff --git a/source/ch/cyberduck/core/Path.java b/source/ch/cyberduck/core/Path.java index 25d21798804..10e03e60cc0 100644 --- a/source/ch/cyberduck/core/Path.java +++ b/source/ch/cyberduck/core/Path.java @@ -295,6 +295,11 @@ public void writeGroup(String group, boolean recursive) { throw new UnsupportedOperationException(); } + @Override + public void readChecksum() { + ; + } + /** * Read the size of the file * diff --git a/source/ch/cyberduck/core/PathAttributes.java b/source/ch/cyberduck/core/PathAttributes.java index afa2d061071..6295bcaaf83 100644 --- a/source/ch/cyberduck/core/PathAttributes.java +++ b/source/ch/cyberduck/core/PathAttributes.java @@ -52,6 +52,7 @@ public class PathAttributes implements Attributes, Serializable { private int type = Path.FILE_TYPE; protected Permission permission = null; + private String checksum; public PathAttributes() { super(); @@ -200,4 +201,12 @@ public String getGroup() { } return this.group; } + + public String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } } diff --git a/source/ch/cyberduck/core/cf/CFPath.java b/source/ch/cyberduck/core/cf/CFPath.java index cfd4e4db1df..b4da299eba2 100644 --- a/source/ch/cyberduck/core/cf/CFPath.java +++ b/source/ch/cyberduck/core/cf/CFPath.java @@ -37,7 +37,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.security.NoSuchAlgorithmException; import java.text.MessageFormat; import java.text.ParseException; import java.util.Date; @@ -234,6 +233,7 @@ public AttributedList list() { file.setParent(this); if(file.attributes.getType() == Path.FILE_TYPE) { file.attributes.setSize(object.getSize()); + file.attributes.setChecksum(object.getMd5sum()); } try { final Date modified = DateParser.parse(object.getLastModified()); @@ -311,15 +311,9 @@ protected void upload(final BandwidthThrottle throttle, final StreamListener lis final InputStream in = new Local.InputStream(this.getLocal()); this.getSession().message(MessageFormat.format(Locale.localizedString("Compute MD5 hash of {0}", "Status"), this.getName())); - String md5sum = null; - try { - md5sum = ServiceUtils.toHex(ServiceUtils.computeMD5Hash(new Local.InputStream(this.getLocal()))); - this.getSession().message(MessageFormat.format(Locale.localizedString("Uploading {0}", "Status"), - this.getName())); - } - catch(NoSuchAlgorithmException e) { - log.error(e.getMessage(), e); - } + String md5sum = this.getLocal().getChecksum(); + this.getSession().message(MessageFormat.format(Locale.localizedString("Uploading {0}", "Status"), + this.getName())); final HashMap metadata = new HashMap(); diff --git a/source/ch/cyberduck/core/s3/S3Path.java b/source/ch/cyberduck/core/s3/S3Path.java index 3a52977dac0..858f8287286 100644 --- a/source/ch/cyberduck/core/s3/S3Path.java +++ b/source/ch/cyberduck/core/s3/S3Path.java @@ -395,6 +395,32 @@ public boolean isRequesterPays() { return false; } + @Override + public void readChecksum() { + if(attributes.isFile()) { + try { + this.getSession().check(); + this.getSession().message(MessageFormat.format(Locale.localizedString("Compute MD5 hash of {0}", "Status"), + this.getName())); + + final S3Object details = this.getDetails(); + if(StringUtils.isNotEmpty(details.getMd5HashAsHex())) { + attributes.setChecksum(details.getMd5HashAsHex()); + } + else { + log.debug("Setting ETag Header as checksum for:" + this.toString()); + attributes.setChecksum(details.getETag()); + } + } + catch(S3ServiceException e) { + this.error("Cannot read file attributes", e); + } + catch(IOException e) { + this.error("Cannot read file attributes", e); + } + } + } + @Override public void readSize() { if(attributes.isFile()) {