package org.fnppl.opensdx.file_transfer.commands;
/*
* Copyright (C) 2010-2015
* fine people e.V. <opensdx@fnppl.org>
* Henning Thieß <ht@fnppl.org>
*
* http://fnppl.org
*/
/*
* Software license
*
* As far as this file or parts of this file is/are software, rather than documentation, this software-license applies / shall be applied.
*
* This file is part of openSDX
* openSDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* openSDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* and GNU General Public License along with openSDX.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Documentation license
*
* As far as this file or parts of this file is/are documentation, rather than software, this documentation-license applies / shall be applied.
*
* This file is part of openSDX.
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation;
* with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License" resp. in the file called "FDL.txt".
*
*/
import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;
import org.fnppl.opensdx.common.Util;
import org.fnppl.opensdx.file_transfer.OSDXFileTransferClient;
import org.fnppl.opensdx.file_transfer.SecureConnection;
import org.fnppl.opensdx.helper.Logger;
import org.fnppl.opensdx.security.SecurityHelper;
public class OSDXFileTransferUploadOldStyleCommand extends OSDXFileTransferCommand {
private File file = null;
private String remoteName = null;
private long filePos = 0;
private long fileLen = 0;
private FileInputStream fileIn = null;
private byte[] data = null;
private long maxFilelengthForMD5 = 100*1024*1024L; //100 MB
private boolean hasNext = true;
private OSDXFileTransferClient client = null;
private boolean resume = false;
public OSDXFileTransferUploadOldStyleCommand(long id, File file, String absolutePathname, boolean resume, OSDXFileTransferClient client) {
super();
fileLen = file.length();
this.resume = resume;
this.filePos = -1L;
this.remoteName = absolutePathname;
this.id = id;
String[] param;
if (fileLen>0) {
byte[] md5 = null;
if (fileLen<maxFilelengthForMD5) {
try {
md5 = SecurityHelper.getMD5(file);
} catch (Exception e) {
System.out.println("Error calculating md5 hash of "+file.getAbsolutePath());
e.printStackTrace();
md5 = null;
}
}
if (md5!=null) {
param = new String[] {absolutePathname,""+fileLen,SecurityHelper.HexDecoder.encode(md5)};
} else {
param = new String[] {absolutePathname,""+fileLen};
}
this.file = file;
} else {
fileLen = 0L;
param = new String[] {absolutePathname,""+fileLen};
this.file = null;
this.data = new byte[0];
}
if (resume) {
this.command = "RESUMEPUT "+Util.makeParamsString(param);
} else {
this.command = "PUT "+Util.makeParamsString(param);
}
}
public OSDXFileTransferUploadOldStyleCommand(long id,byte[] data, String absolutePathname, OSDXFileTransferClient client) {
super();
this.data = data;
fileLen = data.length;
byte[] md5 = null;
if (fileLen<maxFilelengthForMD5) {
try {
md5 = SecurityHelper.getMD5(data);
} catch (Exception e) {
System.out.println("Error calculating md5 hash of "+absolutePathname);
e.printStackTrace();
md5 = null;
}
}
String[] param;
if (md5!=null) {
param = new String[] {absolutePathname,""+fileLen,SecurityHelper.HexDecoder.encode(md5)};
} else {
param = new String[] {absolutePathname,""+fileLen};
}
this.command = "PUT "+Util.makeParamsString(param);
this.filePos = -1L;
this.file = null;
this.remoteName = absolutePathname;
this.id = id;
}
public void onProcessStart() throws Exception {
//if (DEBUG) System.out.println("Command upload start.");
hasNext = true;
if (fileLen>0 && data==null) {
fileIn = new FileInputStream(file);
}
}
public void onProcessCancel() {
//stop upload
hasNext = false;
if (client!=null) {
client.removeCommandFromInProgress(id);
}
if (data==null) {
try {
fileIn.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
data = null;
}
}
public void onProcessEnd() {
//if (DEBUG) System.out.println("Command upload end.");
}
public boolean hasNextPackage() {
return hasNext;
}
public void onResponseReceived(int num, byte code, byte[] content) throws Exception {
if (!SecureConnection.isError(code)) {
if (code == SecureConnection.TYPE_ACK) {
//System.out.println("ACK upload of file: "+remoteName);
if (fileLen<=0) {
notifySucces();
}
if (resume) {
String msg = getMessageFromContent(content);
System.out.println("resume msg :: "+msg+" filePos before = "+filePos);
if (msg!=null && msg.equals("upload already complete")) {
hasNext = false;
System.out.println(msg);
notifyUpdate(fileLen-1, fileLen, null);
notifySucces();
} else {
try {
filePos = Long.parseLong(getMessageFromContent(content));
System.out.println("file pos = "+filePos);
fileIn.skip(filePos);//skip forward to filepos
} catch (Exception ex) {
//notifyError(OSDXErrorCode.UPLOAD_ERROR_WRONG_FORMAT);
notifyError("wrong format: file upload resume position not parseable");
//ex.printStackTrace();
}
}
goOn = true;
}
}
else if (code == SecureConnection.TYPE_ACK_COMPLETE) {
if (data==null) {
try {
fileIn.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
data = null;
}
notifySucces();
}
} else {
//stop upload
hasNext = false;
if (client!=null) {
client.removeCommandFromInProgress(id);
}
if (data==null) {
try {
fileIn.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
data = null;
}
notifyErrorFromContent(getMessageFromContent(content));
}
}
public void onSendNextPackage(SecureConnection con) throws Exception {
if (filePos<0) {
con.setCommand(id, command);
if (DEBUG) {
//System.out.println("SENDING :: "+command+" fileLen = "+fileLen);
Logger.getFileTransferLogger().logMsg("SEND CMD: "+command);
}
filePos = 0L;
num = 1;
if (fileLen<=0) {
hasNext = false;
} else {
if (resume) {
goOn = false;
}
}
notifyUpdate(filePos, fileLen, null);
} else {
byte[] content = new byte[maxPacketSize];
if (data==null) {
//read from file
int read = fileIn.read(content);
if (read<maxPacketSize) {
con.setData(id, num, Arrays.copyOf(content, read));
} else {
con.setData(id, num, content);
}
filePos += read;
notifyUpdate(filePos, fileLen, null);
if (filePos>=fileLen) {
hasNext = false;
}
num++;
} else {
//read from data
int nextPackSize = (int)(fileLen-filePos);
if (nextPackSize>maxPacketSize) {
nextPackSize = maxPacketSize;
}
con.setData(id, num, Arrays.copyOfRange(data, (int)filePos, (int)filePos+nextPackSize));
filePos += nextPackSize;
notifyUpdate(filePos, fileLen, null);
if (filePos>=fileLen) {
hasNext = false;
}
num++;
}
}
con.sendPackage();
}
public long getFileLength() {
return fileLen;
}
}