From d05168ce96faaad75d79671e1cdf2eaccb884ed9 Mon Sep 17 00:00:00 2001 From: Nils Schwabe Date: Thu, 28 Aug 2014 15:14:26 +0200 Subject: Undo refactoring.. Classes are working again. Could not find the mistake :/ --- .../java/org/openslx/filetransfer/Uploader.java | 327 ++++++++++++++++++--- 1 file changed, 294 insertions(+), 33 deletions(-) (limited to 'src/main/java/org/openslx/filetransfer/Uploader.java') diff --git a/src/main/java/org/openslx/filetransfer/Uploader.java b/src/main/java/org/openslx/filetransfer/Uploader.java index 90d9ba2..1aea702 100644 --- a/src/main/java/org/openslx/filetransfer/Uploader.java +++ b/src/main/java/org/openslx/filetransfer/Uploader.java @@ -1,33 +1,65 @@ package org.openslx.filetransfer; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; import org.apache.log4j.Logger; -public class Uploader extends Transfer +public class Uploader { + // Some member variables. + private SSLSocketFactory sslSocketFactory; + private SSLSocket satelliteSocket; + private DataOutputStream dataToServer; + private DataInputStream dataFromServer; + private String TOKEN = null; + private String RANGE = null; + private String ERROR = null; - private static final Logger log = Logger.getLogger( Uploader.class ); + private static Logger log = Logger.getLogger( Uploader.class ); /***********************************************************************/ /** - * Actively establish upload connection to given peer. + * Constructor for satellite uploader. + * Tries to connect to specific ip and port and sending type of action. * - * @param host Host name or address to connect to - * @param port Port to connect to - * @param context ssl context for establishing a secure connection + * @param ip + * @param port * @throws IOException + * @throws KeyStoreException + * @throws CertificateException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + * @throws UnknownHostException */ - public Uploader( String host, int port, SSLContext context ) throws IOException + public Uploader( String ip, int port, SSLContext context ) { - super( host, port, context, log ); - dataToServer.writeByte( 'U' ); + try { + sslSocketFactory = context.getSocketFactory(); + + satelliteSocket = (SSLSocket)sslSocketFactory.createSocket( ip, port ); + satelliteSocket.setSoTimeout( 2000 ); // set socket timeout. + + dataToServer = new DataOutputStream( satelliteSocket.getOutputStream() ); + dataToServer.writeByte( 'U' ); + dataFromServer = new DataInputStream( satelliteSocket.getInputStream() ); + } catch ( Exception e ) { + e.printStackTrace(); + } } /***********************************************************************/ @@ -37,23 +69,217 @@ public class Uploader extends Transfer * * @throws IOException */ - public Uploader( SSLSocket socket ) throws IOException + public Uploader( SSLSocket socket ) + { + try { + satelliteSocket = socket; + dataToServer = new DataOutputStream( satelliteSocket.getOutputStream() ); + dataFromServer = new DataInputStream( satelliteSocket.getInputStream() ); + } catch ( IOException e ) { + e.printStackTrace(); + } + } + + /***********************************************************************/ + /** + * Method for sending token from satellite to master. + * Needfull for getting to know what should happens over connection. + * + * @param t + */ + public Boolean sendToken( String token ) + { + try { + TOKEN = token; + String sendToken = "TOKEN=" + TOKEN; + byte[] data = sendToken.getBytes( StandardCharsets.UTF_8 ); + dataToServer.writeByte( data.length ); + dataToServer.write( data ); + } catch ( SocketTimeoutException ste ) { + ste.printStackTrace(); + log.info( "Socket timeout occured ... close connection." ); + this.close(); + return false; + } catch ( IOException e ) { + e.printStackTrace(); + readMetaData(); + if ( ERROR != null ) { + if ( ERROR == "timeout" ) { + log.info( "Socket timeout occured ... close connection." ); + this.close(); + } + } + log.info( "Sending TOKEN in Uploader failed..." ); + return false; + } + return true; + } + + /***********************************************************************/ + /** + * Getter for TOKEN. + */ + public String getToken() { - super( socket, log ); + return TOKEN; } /***********************************************************************/ /** - * Used by the peer that initiated the connection to tell the remote - * peer which part of the file is being uploaded + * Method to send range of the file, which should be uploaded. + * Helpful for knowing how much was already uploaded if + * connection aborts. + * + * @param actual + * @param l + */ + public Boolean sendRange( long actual, long l ) + { + try { + RANGE = actual + ":" + l; + String sendRange = "RANGE=" + RANGE; + byte[] data = sendRange.getBytes( StandardCharsets.UTF_8 ); + dataToServer.writeByte( data.length ); + dataToServer.write( data ); + dataToServer.writeByte( 0 ); + } catch ( SocketTimeoutException ste ) { + ste.printStackTrace(); + log.info( "Socket timeout occured ... close connection." ); + this.close(); + } catch ( IOException e ) { + e.printStackTrace(); + readMetaData(); + if ( ERROR != null ) { + if ( ERROR == "timeout" ) { + log.info( "Socket timeout occured ... close connection." ); + this.close(); + } + } + log.info( "Sending RANGE in Uploader failed..." ); + return false; + } + return true; + } + + /***********************************************************************/ + /** + * Getter for RANGE. * - * @param startOffset start offset in bytes in the file (inclusive) - * @param endOffset end offset in file (exclusive) * @return */ - public boolean prepareSendRange( long startOffset, long endOffset ) + public String getRange() { - return super.sendRange( startOffset, endOffset ); + return RANGE; + } + + /***********************************************************************/ + /** + * Getter for beginning of RANGE. + * + * @return + */ + public int getStartOfRange() + { + if ( RANGE != null ) { + String[] splitted = RANGE.split( ":" ); + return Integer.parseInt( splitted[0] ); + } + return -1; + } + + /***********************************************************************/ + /** + * Getter for end of RANGE. + * + * @return + */ + public int getEndOfRange() + { + if ( RANGE != null ) { + String[] splitted = RANGE.split( ":" ); + return Integer.parseInt( splitted[1] ); + } + return -1; + } + + /***********************************************************************/ + /** + * Method for returning difference of current Range. + * + * @return + */ + public int getDiffOfRange() + { + if ( getStartOfRange() == -1 || getEndOfRange() == -1 ) { + return -1; + } + int diff = Math.abs( getEndOfRange() - getStartOfRange() ); + return diff; + } + + /***********************************************************************/ + /** + * Method for reading MetaData, like TOKEN and FileRange. + * Split incoming bytes after first '=' and store value to specific + * variable. + * + */ + public Boolean readMetaData() + { + try { + while ( true ) { + byte[] incoming = new byte[ 255 ]; + + // First get length. + dataFromServer.read( incoming, 0, 1 ); + int length = incoming[0] & 0xFF; + + if ( length == 0 ) // Stop if 0 was read. + break; + + /** + * Read the next available bytes and split by '=' for + * getting TOKEN or RANGE. + */ + int hasRead = 0; + while ( hasRead < length ) { + int ret = dataFromServer.read( incoming, hasRead, length - hasRead ); + if ( ret == -1 ) { + log.info( "Error in reading Metadata occured!" ); + return false; + } + hasRead += ret; + } + String data = new String( incoming, "UTF-8" ); + + String[] splitted = data.split( "=" ); + if ( splitted[0] != null && splitted[0].equals( "TOKEN" ) ) { + if ( splitted[1] != null ) + TOKEN = splitted[1]; + log.info( "TOKEN: " + TOKEN ); + } + else if ( splitted[0].equals( "RANGE" ) ) { + if ( splitted[1] != null ) + RANGE = splitted[1]; + log.info( "RANGE: " + RANGE ); + } + else if ( splitted[0].equals( "ERROR" ) ) { + if ( splitted[1] != null ) + ERROR = splitted[1]; + log.info( "ERROR: " + ERROR ); + return false; + } + } + } catch ( SocketTimeoutException ste ) { + ste.printStackTrace(); + sendErrorCode( "timeout" ); + log.info( "Socket timeout occured ... close connection" ); + this.close(); + } catch ( Exception e ) { + e.printStackTrace(); + return false; + } + return true; } /***********************************************************************/ @@ -62,28 +288,26 @@ public class Uploader extends Transfer * * @param filename */ - public boolean sendFile( String filename ) + public Boolean sendFile( String filename ) { RandomAccessFile file = null; try { file = new RandomAccessFile( new File( filename ), "r" ); if ( getStartOfRange() == -1 ) { - this.close(); return false; } file.seek( getStartOfRange() ); - byte[] data = new byte[ 64000 ]; + byte[] data = new byte[ 4000 ]; int hasRead = 0; int length = getDiffOfRange(); - // System.out.println( "diff of Range: " + length ); +// System.out.println( "diff of Range: " + length ); while ( hasRead < length ) { int ret = file.read( data, 0, Math.min( length - hasRead, data.length ) ); if ( ret == -1 ) { - log.warn( "Error occured in Uploader.sendFile()," + log.info( "Error occured in Uploader.sendFile()," + " while reading from File to send." ); - this.close(); return false; } hasRead += ret; @@ -92,7 +316,7 @@ public class Uploader extends Transfer } catch ( SocketTimeoutException ste ) { ste.printStackTrace(); sendErrorCode( "timeout" ); - log.warn( "Socket timeout occured ... close connection." ); + log.info( "Socket timeout occured ... close connection." ); this.close(); return false; } catch ( IOException ioe ) { @@ -100,27 +324,64 @@ public class Uploader extends Transfer readMetaData(); if ( ERROR != null ) { if ( ERROR == "timeout" ) { - log.warn( "Socket timeout occured ... close connection." ); + log.info( "Socket timeout occured ... close connection." ); this.close(); } } - log.warn( "Sending RANGE " + getStartOfRange() + ":" + getEndOfRange() + " of File " + log.info( "Sending RANGE " + getStartOfRange() + ":" + getEndOfRange() + " of File " + filename + " failed..." ); - this.close(); return false; } catch ( Exception e ) { e.printStackTrace(); - this.close(); return false; } finally { - if ( file != null ) { - try { - file.close(); - } catch ( IOException e ) { - } + try { + file.close(); + } catch ( IOException e ) { } } return true; } + /***********************************************************************/ + /** + * Method for sending error Code to server. For example in case of wrong + * token, send code for wrong token. + * + */ + public Boolean sendErrorCode( String errString ) + { + try { + String sendError = "ERROR=" + errString; + byte[] data = sendError.getBytes( StandardCharsets.UTF_8 ); + dataToServer.writeByte( data.length ); + dataToServer.write( data ); + } catch ( IOException e ) { + e.printStackTrace(); + this.close(); + return false; + } + return true; + } + + /***********************************************************************/ + /** + * Method for closing connection, if upload has finished. + * + */ + public void close() + { + try { + if ( satelliteSocket != null ) { + this.satelliteSocket.close(); + satelliteSocket = null; + } + if ( dataFromServer != null ) + dataFromServer.close(); + if ( dataToServer != null ) + dataToServer.close(); + } catch ( IOException e ) { + e.printStackTrace(); + } + } } -- cgit v1.2.3-55-g7522