diff --git a/pom.xml b/pom.xml
index 16fcbcea4..257e9d13a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.tonikelope
MegaBasterd
- 3.0
+ 3.1
jar
diff --git a/src/main/java/com/tonikelope/megabasterd/Chunk.java b/src/main/java/com/tonikelope/megabasterd/Chunk.java
index 95e563a0a..8526865f2 100644
--- a/src/main/java/com/tonikelope/megabasterd/Chunk.java
+++ b/src/main/java/com/tonikelope/megabasterd/Chunk.java
@@ -2,6 +2,8 @@ package com.tonikelope.megabasterd;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import static java.lang.String.valueOf;
/**
@@ -10,14 +12,35 @@ import static java.lang.String.valueOf;
*/
public final class Chunk {
+ public class ByteArrayOutInputStream extends ByteArrayOutputStream {
+
+ public ByteArrayOutInputStream(int size) {
+ super(size);
+ }
+
+ /**
+ * Get an input stream based on the contents of this output stream. Do
+ * not use the output stream after calling this method.
+ *
+ * @return an {@link InputStream}
+ */
+ public ByteArrayInputStream toInputStream() {
+ return new ByteArrayInputStream(this.buf, 0, this.count);
+ }
+ }
+
private final long _id;
private final long _offset;
private final long _size;
- private final ByteArrayOutputStream _data_os;
+ private final ByteArrayOutInputStream _data_os;
private final String _url;
private final int _size_multi;
+ private boolean _can_write;
+
+ public Chunk(long id, long file_size, String file_url) throws ChunkInvalidException, IOException {
+
+ _can_write = true;
- public Chunk(long id, long file_size, String file_url) throws ChunkInvalidException {
_size_multi = 1;
_id = id;
@@ -41,10 +64,13 @@ public final class Chunk {
_url = file_url != null ? file_url + "/" + _offset + "-" + (_offset + _size - 1) : null;
- _data_os = new ByteArrayOutputStream((int) _size);
+ _data_os = new ByteArrayOutInputStream((int) _size);
}
public Chunk(long id, long file_size, String file_url, int size_multi) throws ChunkInvalidException {
+
+ _can_write = true;
+
_size_multi = size_multi;
_id = id;
@@ -68,7 +94,7 @@ public final class Chunk {
_url = file_url != null ? file_url + "/" + _offset + "-" + (_offset + _size - 1) : null;
- _data_os = new ByteArrayOutputStream((int) _size);
+ _data_os = new ByteArrayOutInputStream((int) _size);
}
public int getSize_multi() {
@@ -79,7 +105,13 @@ public final class Chunk {
return _offset;
}
- public ByteArrayOutputStream getOutputStream() {
+ public ByteArrayOutputStream getOutputStream() throws IOException {
+
+ if (!_can_write) {
+
+ throw new IOException("Chunk outputstream is not available!");
+ }
+
return _data_os;
}
@@ -96,7 +128,8 @@ public final class Chunk {
}
public ByteArrayInputStream getInputStream() {
- return new ByteArrayInputStream(_data_os.toByteArray());
+ _can_write = false;
+ return _data_os.toInputStream();
}
private long calculateSize(long file_size) {
diff --git a/src/main/java/com/tonikelope/megabasterd/ChunkDownloader.java b/src/main/java/com/tonikelope/megabasterd/ChunkDownloader.java
index 987dad1a0..56d28aaca 100644
--- a/src/main/java/com/tonikelope/megabasterd/ChunkDownloader.java
+++ b/src/main/java/com/tonikelope/megabasterd/ChunkDownloader.java
@@ -4,7 +4,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.URI;
-import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.tonikelope.megabasterd.MiscTools.*;
@@ -93,23 +92,15 @@ public class ChunkDownloader implements Runnable, SecureSingleThreadNotifiable {
@Override
public void run() {
- String worker_url = null;
- Chunk chunk;
- int reads, conta_error, http_status;
- InputStream is;
- boolean error, error509;
- String current_proxy = null;
- CloseableHttpClient httpclient = null;
-
Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Worker [{1}]: let''s do some work!", new Object[]{Thread.currentThread().getName(), _id});
+ CloseableHttpClient httpclient = null;
+
try {
- conta_error = 0;
-
- error = false;
-
- error509 = false;
+ int conta_error = 0;
+ String worker_url = null, current_proxy = null;;
+ boolean error = false, error509 = false;
while (!_exit && !_download.isStopped() && (error509 || conta_error < MAX_SLOT_ERROR || _download.getMain_panel().isUse_smart_proxy())) {
@@ -159,7 +150,7 @@ public class ChunkDownloader implements Runnable, SecureSingleThreadNotifiable {
worker_url = _download.getDownloadUrlForWorker();
}
- chunk = new Chunk(_download.nextChunkId(), _download.getFile_size(), worker_url, Download.CHUNK_SIZE_MULTI);
+ Chunk chunk = new Chunk(_download.nextChunkId(), _download.getFile_size(), worker_url, Download.CHUNK_SIZE_MULTI);
HttpGet httpget = new HttpGet(new URI(chunk.getUrl()));
@@ -175,51 +166,53 @@ public class ChunkDownloader implements Runnable, SecureSingleThreadNotifiable {
if (!_exit && !_download.isStopped()) {
- is = new ThrottledInputStream(httpresponse.getEntity().getContent(), _download.getMain_panel().getStream_supervisor());
+ try (InputStream is = new ThrottledInputStream(httpresponse.getEntity().getContent(), _download.getMain_panel().getStream_supervisor())) {
- http_status = httpresponse.getStatusLine().getStatusCode();
+ int http_status = httpresponse.getStatusLine().getStatusCode();
- if (http_status != HttpStatus.SC_OK) {
- Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Failed : HTTP error code : {1}", new Object[]{Thread.currentThread().getName(), http_status});
+ if (http_status != HttpStatus.SC_OK) {
+ Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Failed : HTTP error code : {1}", new Object[]{Thread.currentThread().getName(), http_status});
- error = true;
+ error = true;
- if (http_status == 509) {
+ if (http_status == 509) {
- error509 = true;
+ error509 = true;
- getDownload().getView().set509Error(true);
- }
-
- } else {
-
- byte[] buffer = new byte[THROTTLE_SLICE_SIZE];
-
- while (!_exit && !_download.isStopped() && !_download.getChunkwriter().isExit() && chunk.getOutputStream().size() < chunk.getSize() && (reads = is.read(buffer)) != -1) {
-
- chunk.getOutputStream().write(buffer, 0, reads);
-
- _download.getPartialProgressQueue().add(reads);
-
- _download.getProgress_meter().secureNotify();
-
- if (_download.isPaused() && !_download.isStopped()) {
-
- _download.pause_worker();
-
- secureWait();
-
- } else if (!_download.isPaused() && _download.getMain_panel().getDownload_manager().isPaused_all()) {
-
- _download.pause();
-
- _download.pause_worker();
-
- secureWait();
+ getDownload().getView().set509Error(true);
}
- }
- is.close();
+ } else {
+
+ byte[] buffer = new byte[THROTTLE_SLICE_SIZE];
+
+ int reads;
+
+ while (!_exit && !_download.isStopped() && !_download.getChunkwriter().isExit() && chunk.getOutputStream().size() < chunk.getSize() && (reads = is.read(buffer)) != -1) {
+
+ chunk.getOutputStream().write(buffer, 0, reads);
+
+ _download.getPartialProgressQueue().add(reads);
+
+ _download.getProgress_meter().secureNotify();
+
+ if (_download.isPaused() && !_download.isStopped()) {
+
+ _download.pause_worker();
+
+ secureWait();
+
+ } else if (!_download.isPaused() && _download.getMain_panel().getDownload_manager().isPaused_all()) {
+
+ _download.pause();
+
+ _download.pause_worker();
+
+ secureWait();
+ }
+ }
+
+ }
if (chunk.getOutputStream().size() < chunk.getSize()) {
@@ -318,12 +311,8 @@ public class ChunkDownloader implements Runnable, SecureSingleThreadNotifiable {
} catch (ChunkInvalidException e) {
- } catch (IOException ex) {
- _download.stopDownloader(ex.getMessage());
- Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
- } catch (URISyntaxException ex) {
- Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
+ _download.stopDownloader(ex.getMessage());
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
diff --git a/src/main/java/com/tonikelope/megabasterd/ChunkDownloaderMono.java b/src/main/java/com/tonikelope/megabasterd/ChunkDownloaderMono.java
index 44db87e7f..53b05aaaa 100644
--- a/src/main/java/com/tonikelope/megabasterd/ChunkDownloaderMono.java
+++ b/src/main/java/com/tonikelope/megabasterd/ChunkDownloaderMono.java
@@ -3,7 +3,6 @@ package com.tonikelope.megabasterd;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
-import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.tonikelope.megabasterd.MiscTools.*;
@@ -26,21 +25,15 @@ public class ChunkDownloaderMono extends ChunkDownloader {
@Override
public void run() {
- String worker_url = null;
- Chunk chunk;
- int reads, conta_error, http_status = 200;
- boolean error, error509;
- HttpGet httpget = null;
- CloseableHttpResponse httpresponse = null;
-
Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Worker [{1}]: let''s do some work!", new Object[]{Thread.currentThread().getName(), getId()});
try (CloseableHttpClient httpclient = MiscTools.getApacheKissHttpClient()) {
- conta_error = 0;
- error = false;
-
- error509 = false;
+ String worker_url = null;
+ int conta_error = 0, http_status = 200;
+ boolean error = false, error509 = false;
+ HttpGet httpget = null;
+ CloseableHttpResponse httpresponse = null;
getDownload().getView().set509Error(false);
@@ -58,7 +51,7 @@ public class ChunkDownloaderMono extends ChunkDownloader {
}
}
- chunk = new Chunk(getDownload().nextChunkId(), getDownload().getFile_size(), null);
+ Chunk chunk = new Chunk(getDownload().nextChunkId(), getDownload().getFile_size(), null);
try {
@@ -114,6 +107,8 @@ public class ChunkDownloaderMono extends ChunkDownloader {
byte[] buffer = new byte[THROTTLE_SLICE_SIZE];
+ int reads;
+
while (!getDownload().isStopped() && !getDownload().getChunkwriter().isExit() && chunk.getOutputStream().size() < chunk.getSize() && (reads = is.read(buffer, 0, Math.min((int) (chunk.getSize() - chunk.getOutputStream().size()), buffer.length))) != -1) {
chunk.getOutputStream().write(buffer, 0, reads);
@@ -199,16 +194,10 @@ public class ChunkDownloaderMono extends ChunkDownloader {
} catch (ChunkInvalidException e) {
- } catch (IOException ex) {
-
- Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
-
- getDownload().stopDownloader(ex.getMessage());
-
- } catch (URISyntaxException ex) {
- Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
+
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
+ getDownload().stopDownloader(ex.getMessage());
}
getDownload().stopThisSlot(this);
diff --git a/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java b/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java
index 4f94a339b..a71d33cdd 100644
--- a/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java
+++ b/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java
@@ -9,7 +9,6 @@ import java.io.PipedOutputStream;
import java.io.RandomAccessFile;
import java.net.SocketTimeoutException;
import java.net.URI;
-import java.net.URISyntaxException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@@ -107,20 +106,20 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
@Override
public void run() {
- Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} ChunkUploader {1} hello! {2}", new Object[]{Thread.currentThread().getName(), getId(), getUpload().getFile_name()});
- String worker_url = _upload.getUl_url();
- Chunk chunk;
- int reads, conta_error, http_status, tot_bytes_up;
- boolean error;
- OutputStream out;
+ Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} ChunkUploader {1} hello! {2}", new Object[]{Thread.currentThread().getName(), getId(), getUpload().getFile_name()});
try (final CloseableHttpClient httpclient = getApacheKissHttpClient(); RandomAccessFile f = new RandomAccessFile(_upload.getFile_name(), "r");) {
- conta_error = 0;
+ String worker_url = _upload.getUl_url();
+
+ int conta_error = 0;
while (!_upload.getMain_panel().isExit() && !_exit && !_upload.isStopped() && conta_error < MAX_SLOT_ERROR) {
- chunk = new Chunk(_upload.nextChunkId(), _upload.getFile_size(), worker_url, Upload.CHUNK_SIZE_MULTI);
+
+ int reads, http_status, tot_bytes_up;
+
+ Chunk chunk = new Chunk(_upload.nextChunkId(), _upload.getFile_size(), worker_url, Upload.CHUNK_SIZE_MULTI);
f.seek(chunk.getOffset());
@@ -138,7 +137,7 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
tot_bytes_up = 0;
- error = false;
+ boolean error = false;
CloseableHttpResponse httpresponse = null;
@@ -165,35 +164,37 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
});
THREAD_POOL.execute(futureTask);
- out = new ThrottledOutputStream(pipeout, _upload.getMain_panel().getStream_supervisor());
- Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Uploading chunk {1} from worker {2}...", new Object[]{Thread.currentThread().getName(), chunk.getId(), _id});
+ try (OutputStream out = new ThrottledOutputStream(pipeout, _upload.getMain_panel().getStream_supervisor())) {
- while (!_exit && !_upload.isStopped() && (reads = cis.read(buffer)) != -1) {
- out.write(buffer, 0, reads);
+ Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} Uploading chunk {1} from worker {2}...", new Object[]{Thread.currentThread().getName(), chunk.getId(), _id});
- _upload.getPartialProgress().add(reads);
+ while (!_exit && !_upload.isStopped() && (reads = cis.read(buffer)) != -1) {
+ out.write(buffer, 0, reads);
- _upload.getProgress_meter().secureNotify();
+ _upload.getPartialProgress().add(reads);
- tot_bytes_up += reads;
+ _upload.getProgress_meter().secureNotify();
- if (_upload.isPaused() && !_upload.isStopped()) {
+ tot_bytes_up += reads;
- _upload.pause_worker();
+ if (_upload.isPaused() && !_upload.isStopped()) {
- secureWait();
+ _upload.pause_worker();
- } else if (!_upload.isPaused() && _upload.getMain_panel().getUpload_manager().isPaused_all()) {
+ secureWait();
- _upload.pause();
+ } else if (!_upload.isPaused() && _upload.getMain_panel().getUpload_manager().isPaused_all()) {
- _upload.pause_worker();
+ _upload.pause();
- secureWait();
+ _upload.pause_worker();
+
+ secureWait();
+ }
}
+
}
- out.close();
}
if (!_upload.isStopped()) {
@@ -414,7 +415,7 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
} catch (ChunkInvalidException e) {
- } catch (IOException | URISyntaxException ex) {
+ } catch (Exception ex) {
_upload.stopUploader();
diff --git a/src/main/java/com/tonikelope/megabasterd/ChunkUploaderMono.java b/src/main/java/com/tonikelope/megabasterd/ChunkUploaderMono.java
index 38cb2e298..544fd30fb 100644
--- a/src/main/java/com/tonikelope/megabasterd/ChunkUploaderMono.java
+++ b/src/main/java/com/tonikelope/megabasterd/ChunkUploaderMono.java
@@ -8,7 +8,6 @@ import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.RandomAccessFile;
import java.net.URI;
-import java.net.URISyntaxException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@@ -41,16 +40,12 @@ public class ChunkUploaderMono extends ChunkUploader {
@Override
public void run() {
- Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} ChunkUploaderMONO {1} hello! {2}", new Object[]{Thread.currentThread().getName(), getId(), getUpload().getFile_name()});
- String worker_url = getUpload().getUl_url();
- Chunk chunk;
- int reads, conta_error, http_status, tot_bytes_up = -1;
- boolean error = false;
+ Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} ChunkUploaderMONO {1} hello! {2}", new Object[]{Thread.currentThread().getName(), getId(), getUpload().getFile_name()});
try (CloseableHttpClient httpclient = getApacheKissHttpClient(); RandomAccessFile f = new RandomAccessFile(getUpload().getFile_name(), "r");) {
- conta_error = 0;
+ String worker_url = getUpload().getUl_url();
OutputStream out = null;
@@ -58,9 +53,13 @@ public class ChunkUploaderMono extends ChunkUploader {
while (!isExit() && !getUpload().isStopped()) {
+ int conta_error = 0, reads, http_status, tot_bytes_up = -1;
+
+ boolean error = false;
+
CloseableHttpResponse httpresponse = null;
- chunk = new Chunk(getUpload().nextChunkId(), getUpload().getFile_size(), null);
+ Chunk chunk = new Chunk(getUpload().nextChunkId(), getUpload().getFile_size(), null);
f.seek(chunk.getOffset());
@@ -293,7 +292,7 @@ public class ChunkUploaderMono extends ChunkUploader {
} catch (ChunkInvalidException e) {
- } catch (URISyntaxException | IOException ex) {
+ } catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
diff --git a/src/main/java/com/tonikelope/megabasterd/ChunkWriter.java b/src/main/java/com/tonikelope/megabasterd/ChunkWriter.java
index 03174fdf0..74c3ad5c4 100644
--- a/src/main/java/com/tonikelope/megabasterd/ChunkWriter.java
+++ b/src/main/java/com/tonikelope/megabasterd/ChunkWriter.java
@@ -121,7 +121,7 @@ public final class ChunkWriter implements Runnable, SecureSingleThreadNotifiable
if (_file_size > 0) {
while (!_exit && (!_download.isStopped() || !_download.getChunkworkers().isEmpty()) && _bytes_written < _file_size) {
while (_chunk_queue.containsKey(_last_chunk_id_written + 1)) {
- current_chunk = _chunk_queue.get(_last_chunk_id_written + 1);
+ current_chunk = _chunk_queue.remove(_last_chunk_id_written + 1);
try (CipherInputStream cis = new CipherInputStream(current_chunk.getInputStream(), genDecrypter("AES", "AES/CTR/NoPadding", _byte_file_key, forwardMEGALinkKeyIV(_byte_iv, _bytes_written)))) {
while ((reads = cis.read(buffer)) != -1) {
@@ -133,8 +133,6 @@ public final class ChunkWriter implements Runnable, SecureSingleThreadNotifiable
_bytes_written += current_chunk.getSize();
- _chunk_queue.remove(current_chunk.getId());
-
_last_chunk_id_written = current_chunk.getId();
}
diff --git a/src/main/java/com/tonikelope/megabasterd/Download.java b/src/main/java/com/tonikelope/megabasterd/Download.java
index 540dae4c5..595ed83ef 100644
--- a/src/main/java/com/tonikelope/megabasterd/Download.java
+++ b/src/main/java/com/tonikelope/megabasterd/Download.java
@@ -1199,36 +1199,38 @@ public final class Download implements Transference, Runnable, SecureSingleThrea
} while (!_exit && chunk.getOutputStream().size() < chunk.getSize());
- InputStream chunk_is = chunk.getInputStream();
+ try (InputStream chunk_is = chunk.getInputStream()) {
- while (!_exit && (reads = chunk_is.read(byte_block)) != -1) {
+ while (!_exit && (reads = chunk_is.read(byte_block)) != -1) {
- if (reads < byte_block.length) {
+ if (reads < byte_block.length) {
- for (int i = reads; i < byte_block.length; i++) {
- byte_block[i] = 0;
+ for (int i = reads; i < byte_block.length; i++) {
+ byte_block[i] = 0;
+ }
}
+
+ int_block = bin2i32a(byte_block);
+
+ for (int i = 0; i < chunk_mac.length; i++) {
+ chunk_mac[i] ^= int_block[i];
+ }
+
+ chunk_mac = bin2i32a(cryptor.doFinal(i32a2bin(chunk_mac)));
}
- int_block = bin2i32a(byte_block);
-
- for (int i = 0; i < chunk_mac.length; i++) {
- chunk_mac[i] ^= int_block[i];
+ for (int i = 0; i < file_mac.length; i++) {
+ file_mac[i] ^= chunk_mac[i];
}
- chunk_mac = bin2i32a(cryptor.doFinal(i32a2bin(chunk_mac)));
+ file_mac = bin2i32a(cryptor.doFinal(i32a2bin(file_mac)));
+
+ setProgress(tot);
}
-
- for (int i = 0; i < file_mac.length; i++) {
- file_mac[i] ^= chunk_mac[i];
- }
-
- file_mac = bin2i32a(cryptor.doFinal(i32a2bin(file_mac)));
-
- setProgress(tot);
}
} catch (ChunkInvalidException e) {
+
}
int[] cbc = {file_mac[0] ^ file_mac[1], file_mac[2] ^ file_mac[3]};
diff --git a/src/main/java/com/tonikelope/megabasterd/MainPanel.java b/src/main/java/com/tonikelope/megabasterd/MainPanel.java
index fef0f7072..0c4c9fd2e 100644
--- a/src/main/java/com/tonikelope/megabasterd/MainPanel.java
+++ b/src/main/java/com/tonikelope/megabasterd/MainPanel.java
@@ -48,7 +48,7 @@ import org.apache.http.auth.UsernamePasswordCredentials;
*/
public final class MainPanel {
- public static final String VERSION = "3.0";
+ public static final String VERSION = "3.1";
public static final int THROTTLE_SLICE_SIZE = 16 * 1024;
public static final int DEFAULT_BYTE_BUFFER_SIZE = 16 * 1024;
public static final int STREAMER_PORT = 1337;
diff --git a/src/main/java/com/tonikelope/megabasterd/StreamChunk.java b/src/main/java/com/tonikelope/megabasterd/StreamChunk.java
index 360e3b13e..f95d20275 100644
--- a/src/main/java/com/tonikelope/megabasterd/StreamChunk.java
+++ b/src/main/java/com/tonikelope/megabasterd/StreamChunk.java
@@ -2,6 +2,7 @@ package com.tonikelope.megabasterd;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
/**
*
@@ -9,12 +10,30 @@ import java.io.ByteArrayOutputStream;
*/
public final class StreamChunk {
+ public class ByteArrayOutInputStream extends ByteArrayOutputStream {
+
+ public ByteArrayOutInputStream(int size) {
+ super(size);
+ }
+
+ /**
+ * Get an input stream based on the contents of this output stream. Do
+ * not use the output stream after calling this method.
+ *
+ * @return an {@link InputStream}
+ */
+ public ByteArrayInputStream toInputStream() {
+ return new ByteArrayInputStream(this.buf, 0, this.count);
+ }
+ }
+
private final long _offset;
private final long _size;
private final String _url;
- private final ByteArrayOutputStream _data_os;
+ private final ByteArrayOutInputStream _data_os;
+ private boolean _can_write;
- public StreamChunk(long offset, long size, String url) throws ChunkInvalidException {
+ public StreamChunk(long offset, long size, String url) throws ChunkInvalidException, IOException {
if (offset < 0 || size < 0 || url == null) {
throw new ChunkInvalidException("Offset: " + offset + " Size: " + size);
@@ -23,11 +42,12 @@ public final class StreamChunk {
_offset = offset;
_size = size;
_url = url + "/" + _offset + "-" + (_offset + _size - 1);
- _data_os = new ByteArrayOutputStream((int) _size);
+ _data_os = new ByteArrayOutInputStream((int) _size);
}
public ByteArrayInputStream getInputStream() {
- return new ByteArrayInputStream(_data_os.toByteArray());
+ _can_write = false;
+ return _data_os.toInputStream();
}
public long getOffset() {
@@ -42,7 +62,12 @@ public final class StreamChunk {
return _url;
}
- public ByteArrayOutputStream getOutputStream() {
+ public ByteArrayOutputStream getOutputStream() throws IOException {
+
+ if (!_can_write) {
+
+ throw new IOException("Chunk outputstream is not available!");
+ }
return _data_os;
}
diff --git a/src/main/java/com/tonikelope/megabasterd/StreamChunkDownloader.java b/src/main/java/com/tonikelope/megabasterd/StreamChunkDownloader.java
index 65c14b37d..b9acab54e 100644
--- a/src/main/java/com/tonikelope/megabasterd/StreamChunkDownloader.java
+++ b/src/main/java/com/tonikelope/megabasterd/StreamChunkDownloader.java
@@ -43,8 +43,8 @@ public class StreamChunkDownloader implements Runnable {
String url = _chunkwriter.getUrl();
- boolean error = false;
- boolean error509 = false;
+ boolean error = false, error509 = false;
+
String current_proxy = null;
long offset = -1;
diff --git a/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java b/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java
index 035009d20..aeace46b0 100644
--- a/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java
+++ b/src/main/java/com/tonikelope/megabasterd/StreamChunkWriter.java
@@ -87,7 +87,7 @@ public class StreamChunkWriter implements Runnable, SecureMultiThreadNotifiable
while (!_exit && _bytes_written < _end_offset && _chunk_queue.containsKey(_bytes_written)) {
- StreamChunk current_chunk = _chunk_queue.get(_bytes_written);
+ StreamChunk current_chunk = _chunk_queue.remove(_bytes_written);
InputStream is = current_chunk.getInputStream();
@@ -102,8 +102,6 @@ public class StreamChunkWriter implements Runnable, SecureMultiThreadNotifiable
_bytes_written += reads;
}
- _chunk_queue.remove(current_chunk.getOffset());
-
secureNotifyAll();
Logger.getLogger(getClass().getName()).log(Level.INFO, "{0} StreamChunkWriter has written {1} / {2} ...", new Object[]{Thread.currentThread().getName(), _bytes_written, _end_offset});
diff --git a/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java b/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java
index 5dd49f12c..5d96b7145 100644
--- a/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java
+++ b/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java
@@ -135,58 +135,20 @@ public final class UploadMACGenerator implements Runnable, SecureSingleThreadNot
upload_workers_finish = true;
}
- chunk = _chunk_queue.get(_last_chunk_id_read + 1);
+ chunk = _chunk_queue.remove(_last_chunk_id_read + 1);
- InputStream chunk_is = chunk.getInputStream();
+ try (InputStream chunk_is = chunk.getInputStream()) {
- if (Upload.CHUNK_SIZE_MULTI == 1 || chunk.getId() <= 7) {
+ if (Upload.CHUNK_SIZE_MULTI == 1 || chunk.getId() <= 7) {
- try {
+ try {
- int[] chunk_mac = {file_iv[0], file_iv[1], file_iv[0], file_iv[1]};
- byte[] byte_block = new byte[16];
+ int[] chunk_mac = {file_iv[0], file_iv[1], file_iv[0], file_iv[1]};
+ byte[] byte_block = new byte[16];
- while ((reads = chunk_is.read(byte_block)) != -1) {
-
- if (reads < byte_block.length) {
- for (int i = reads; i < byte_block.length; i++) {
- byte_block[i] = 0;
- }
- }
-
- int_block = bin2i32a(byte_block);
-
- for (int i = 0; i < chunk_mac.length; i++) {
- chunk_mac[i] ^= int_block[i];
- }
-
- chunk_mac = bin2i32a(cryptor.doFinal(i32a2bin(chunk_mac)));
- }
-
- for (int i = 0; i < file_mac.length; i++) {
- file_mac[i] ^= chunk_mac[i];
- }
-
- file_mac = bin2i32a(cryptor.doFinal(i32a2bin(file_mac)));
-
- } catch (IOException | IllegalBlockSizeException | BadPaddingException ex) {
- Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
- }
- } else {
-
- do {
- int[] chunk_mac = {file_iv[0], file_iv[1], file_iv[0], file_iv[1]};
-
- byte[] byte_block = new byte[16];
-
- long chunk_size = 0;
-
- do {
-
- if ((reads = chunk_is.read(byte_block)) != -1) {
+ while ((reads = chunk_is.read(byte_block)) != -1) {
if (reads < byte_block.length) {
-
for (int i = reads; i < byte_block.length; i++) {
byte_block[i] = 0;
}
@@ -199,22 +161,62 @@ public final class UploadMACGenerator implements Runnable, SecureSingleThreadNot
}
chunk_mac = bin2i32a(cryptor.doFinal(i32a2bin(chunk_mac)));
-
- chunk_size += byte_block.length;
}
- } while (reads != -1 && chunk_size < 1024 * 1024);
-
- if (chunk_size > 0) {
-
for (int i = 0; i < file_mac.length; i++) {
file_mac[i] ^= chunk_mac[i];
}
file_mac = bin2i32a(cryptor.doFinal(i32a2bin(file_mac)));
- }
- } while (reads != -1);
+ } catch (IOException | IllegalBlockSizeException | BadPaddingException ex) {
+ Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
+ }
+ } else {
+
+ do {
+ int[] chunk_mac = {file_iv[0], file_iv[1], file_iv[0], file_iv[1]};
+
+ byte[] byte_block = new byte[16];
+
+ long chunk_size = 0;
+
+ do {
+
+ if ((reads = chunk_is.read(byte_block)) != -1) {
+
+ if (reads < byte_block.length) {
+
+ for (int i = reads; i < byte_block.length; i++) {
+ byte_block[i] = 0;
+ }
+ }
+
+ int_block = bin2i32a(byte_block);
+
+ for (int i = 0; i < chunk_mac.length; i++) {
+ chunk_mac[i] ^= int_block[i];
+ }
+
+ chunk_mac = bin2i32a(cryptor.doFinal(i32a2bin(chunk_mac)));
+
+ chunk_size += byte_block.length;
+ }
+
+ } while (reads != -1 && chunk_size < 1024 * 1024);
+
+ if (chunk_size > 0) {
+
+ for (int i = 0; i < file_mac.length; i++) {
+ file_mac[i] ^= chunk_mac[i];
+ }
+
+ file_mac = bin2i32a(cryptor.doFinal(i32a2bin(file_mac)));
+ }
+
+ } while (reads != -1);
+
+ }
}
@@ -222,8 +224,6 @@ public final class UploadMACGenerator implements Runnable, SecureSingleThreadNot
_last_chunk_id_read = chunk.getId();
- _chunk_queue.remove(chunk.getId());
-
new_chunk = true;
temp_file_data = (String.valueOf(_bytes_read) + "|" + Bin2BASE64(i32a2bin(file_mac)));