diff --git a/pom.xml b/pom.xml
index a2010de53..3f11f9140 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.tonikelope
MegaBasterd
- 7.72
+ 7.73
jar
@@ -20,6 +20,11 @@
+
+ commons-io
+ commons-io
+ 2.11.0
+
org.sejda.webp-imageio
webp-imageio-sejda
diff --git a/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java b/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java
index b164b6cf8..902b1a65a 100644
--- a/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java
+++ b/src/main/java/com/tonikelope/megabasterd/ChunkUploader.java
@@ -25,6 +25,8 @@ import java.nio.channels.Channels;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.CipherInputStream;
+import org.apache.commons.io.input.QueueInputStream;
+import org.apache.commons.io.output.QueueOutputStream;
/**
*
@@ -117,6 +119,8 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE];
+ byte[] buffer_enc = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE];
+
boolean fatal_error = false;
int conta_error = 0;
@@ -141,9 +145,9 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
chunk_id = _upload.nextChunkId();
- long chunk_offset = ChunkWriterManager.calculateChunkOffset(chunk_id, Upload.CHUNK_SIZE_MULTI);
+ long chunk_offset = ChunkWriterManager.calculateChunkOffset(chunk_id, 1);
- long chunk_size = ChunkWriterManager.calculateChunkSize(chunk_id, _upload.getFile_size(), chunk_offset, Upload.CHUNK_SIZE_MULTI);
+ long chunk_size = ChunkWriterManager.calculateChunkSize(chunk_id, _upload.getFile_size(), chunk_offset, 1);
ChunkWriterManager.checkChunkID(chunk_id, _upload.getFile_size(), chunk_offset);
@@ -194,12 +198,25 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
f.seek(chunk_offset);
- try ( CipherInputStream cis = new CipherInputStream(new BufferedInputStream(Channels.newInputStream(f.getChannel())), genCrypter("AES", "AES/CTR/NoPadding", _upload.getByte_file_key(), forwardMEGALinkKeyIV(_upload.getByte_file_iv(), chunk_offset))); OutputStream out = new ThrottledOutputStream(con.getOutputStream(), _upload.getMain_panel().getStream_supervisor())) {
+ ByteArrayOutputStream chunk_mac = new ByteArrayOutputStream();
+
+ try ( QueueInputStream qis = new QueueInputStream(); QueueOutputStream qos = qis.newQueueOutputStream(); BufferedInputStream bis = new BufferedInputStream(Channels.newInputStream(f.getChannel())); CipherInputStream cis = new CipherInputStream(qis, genCrypter("AES", "AES/CTR/NoPadding", _upload.getByte_file_key(), forwardMEGALinkKeyIV(_upload.getByte_file_iv(), chunk_offset))); OutputStream out = new ThrottledOutputStream(con.getOutputStream(), _upload.getMain_panel().getStream_supervisor())) {
LOG.log(Level.INFO, "{0} Uploading chunk {1} from worker {2} {3}...", new Object[]{Thread.currentThread().getName(), chunk_id, _id, _upload.getFile_name()});
- while (!_exit && tot_bytes_up < chunk_size && (reads = cis.read(buffer)) != -1) {
- out.write(buffer, 0, reads);
+ while (!_exit && tot_bytes_up < chunk_size && (reads = bis.read(buffer)) != -1) {
+
+ chunk_mac.write(buffer, 0, reads);
+
+ for (int i = 0; i < reads; i++) {
+ qos.write(buffer[i]);
+ }
+
+ for (int i = 0; i < reads; i++) {
+ buffer_enc[i] = (byte) cis.read();
+ }
+
+ out.write(buffer_enc, 0, reads);
_upload.getPartialProgress().add((long) reads);
@@ -215,6 +232,8 @@ public class ChunkUploader implements Runnable, SecureSingleThreadNotifiable {
}
}
+
+ _upload.getMac_generator().CHUNK_QUEUE.put(chunk_offset, chunk_mac);
}
if (!_exit) {
diff --git a/src/main/java/com/tonikelope/megabasterd/MainPanel.java b/src/main/java/com/tonikelope/megabasterd/MainPanel.java
index 5b3b74742..13c8671bd 100644
--- a/src/main/java/com/tonikelope/megabasterd/MainPanel.java
+++ b/src/main/java/com/tonikelope/megabasterd/MainPanel.java
@@ -67,7 +67,7 @@ import javax.swing.UIManager;
*/
public final class MainPanel {
- public static final String VERSION = "7.72";
+ public static final String VERSION = "7.73";
public static final boolean FORCE_SMART_PROXY = false; //TRUE FOR DEBUGING SMART PROXY
public static final int THROTTLE_SLICE_SIZE = 16 * 1024;
public static final int DEFAULT_BYTE_BUFFER_SIZE = 16 * 1024;
diff --git a/src/main/java/com/tonikelope/megabasterd/MiscTools.java b/src/main/java/com/tonikelope/megabasterd/MiscTools.java
index edc72ba89..d7dbee679 100644
--- a/src/main/java/com/tonikelope/megabasterd/MiscTools.java
+++ b/src/main/java/com/tonikelope/megabasterd/MiscTools.java
@@ -30,6 +30,7 @@ import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -48,6 +49,7 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
@@ -239,54 +241,29 @@ public class MiscTools {
public static int[] bin2i32a(byte[] bin) {
int l = (int) (4 * Math.ceil((double) bin.length / 4));
- byte[] new_bin = Arrays.copyOfRange(bin, 0, l);
+ IntBuffer intBuf = ByteBuffer.wrap(bin, 0, l).order(ByteOrder.BIG_ENDIAN).asIntBuffer();
- bin = new_bin;
+ int[] array = new int[intBuf.remaining()];
- ByteBuffer bin_buffer = ByteBuffer.wrap(bin);
- IntBuffer int_buffer = bin_buffer.asIntBuffer();
+ intBuf.get(array);
- if (int_buffer.hasArray()) {
- return int_buffer.array();
- } else {
- ArrayList list = new ArrayList<>();
-
- while (int_buffer.hasRemaining()) {
- list.add(int_buffer.get());
- }
-
- int[] aux = new int[list.size()];
-
- for (int i = 0; i < aux.length; i++) {
- aux[i] = list.get(i);
- }
-
- return aux;
- }
+ return array;
}
- public static byte[] i32a2bin(int[] i32a) {
- ByteBuffer bin_buffer = ByteBuffer.allocate(i32a.length * 4);
- IntBuffer int_buffer = bin_buffer.asIntBuffer();
- int_buffer.put(i32a);
+ public static byte[] i32a2bin(int[] values) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
- if (bin_buffer.hasArray()) {
- return bin_buffer.array();
- } else {
- ArrayList list = new ArrayList<>();
+ DataOutputStream dos = new DataOutputStream(baos);
- while (int_buffer.hasRemaining()) {
- list.add(bin_buffer.get());
+ for (int i = 0; i < values.length; ++i) {
+ try {
+ dos.writeInt(values[i]);
+ } catch (IOException ex) {
+ Logger.getLogger(MiscTools.class.getName()).log(Level.SEVERE, null, ex);
}
-
- byte[] aux = new byte[list.size()];
-
- for (int i = 0; i < aux.length; i++) {
- aux[i] = list.get(i);
- }
-
- return aux;
}
+
+ return baos.toByteArray();
}
public static BigInteger mpi2big(byte[] s) {
diff --git a/src/main/java/com/tonikelope/megabasterd/Upload.java b/src/main/java/com/tonikelope/megabasterd/Upload.java
index a4c3d0d3f..ef8bca71e 100644
--- a/src/main/java/com/tonikelope/megabasterd/Upload.java
+++ b/src/main/java/com/tonikelope/megabasterd/Upload.java
@@ -39,7 +39,6 @@ import javax.swing.JComponent;
public class Upload implements Transference, Runnable, SecureSingleThreadNotifiable {
public static final int WORKERS_DEFAULT = 6;
- public static final int CHUNK_SIZE_MULTI = 1; //Otra cosa da errores al reanudar una subida (investigar)
public static final boolean DEFAULT_THUMBNAILS = true;
public static final boolean UPLOAD_LOG = false;
private static final Logger LOG = Logger.getLogger(Upload.class.getName());
@@ -62,7 +61,7 @@ public class Upload implements Transference, Runnable, SecureSingleThreadNotifia
private long _last_chunk_id_dispatched;
private final ConcurrentLinkedQueue _partialProgressQueue;
private final ExecutorService _thread_pool;
- private int[] _file_meta_mac;
+ private volatile int[] _file_meta_mac;
private String _fid;
private boolean _notified;
private volatile String _completion_handler;
@@ -1305,7 +1304,7 @@ public class Upload implements Transference, Runnable, SecureSingleThreadNotifia
public long calculateLastUploadedChunk(long bytes_read) {
if (bytes_read > 3584 * 1024) {
- return 7 + (long) Math.floor((float) (bytes_read - 3584 * 1024) / (1024 * 1024 * Upload.CHUNK_SIZE_MULTI));
+ return 7 + (long) Math.floor((float) (bytes_read - 3584 * 1024) / (1024 * 1024 * 1));
} else {
long i = 0, tot = 0;
diff --git a/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java b/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java
index 293d76456..2002bca2d 100644
--- a/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java
+++ b/src/main/java/com/tonikelope/megabasterd/UploadMACGenerator.java
@@ -11,10 +11,10 @@ package com.tonikelope.megabasterd;
import static com.tonikelope.megabasterd.CryptTools.*;
import static com.tonikelope.megabasterd.MiscTools.*;
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
@@ -33,6 +33,7 @@ public class UploadMACGenerator implements Runnable, SecureSingleThreadNotifiabl
private final Object _secure_notify_lock;
private boolean _notified;
private volatile boolean _exit;
+ public final ConcurrentHashMap CHUNK_QUEUE = new ConcurrentHashMap<>();
public UploadMACGenerator(Upload upload) {
_secure_notify_lock = new Object();
@@ -122,36 +123,40 @@ public class UploadMACGenerator implements Runnable, SecureSingleThreadNotifiabl
Cipher cryptor = genCrypter("AES", "AES/CBC/NoPadding", _upload.getByte_file_key(), i32a2bin(mac_iv));
- try ( BufferedInputStream is = new BufferedInputStream(new FileInputStream(_upload.getFile_name()))) {
+ int[] chunk_mac = new int[4];
+ byte[] byte_block = new byte[16];
+ byte[] chunk_bytes;
- if (tot > 0) {
- is.skip(tot);
- }
+ try {
+ while (!_exit && !_upload.isStopped() && !_upload.getMain_panel().isExit()) {
- int[] chunk_mac = new int[4];
- byte[] byte_block = new byte[16];
+ int reads;
- try {
- while (!_exit && !_upload.isStopped() && !_upload.getMain_panel().isExit()) {
+ long chunk_offset = ChunkWriterManager.calculateChunkOffset(chunk_id, 1);
- int reads;
+ long chunk_size = ChunkWriterManager.calculateChunkSize(chunk_id, _upload.getFile_size(), chunk_offset, 1);
- long chunk_offset = ChunkWriterManager.calculateChunkOffset(chunk_id, 1);
+ ChunkWriterManager.checkChunkID(chunk_id, _upload.getFile_size(), chunk_offset);
- long chunk_size = ChunkWriterManager.calculateChunkSize(chunk_id, _upload.getFile_size(), chunk_offset, 1);
+ while (!CHUNK_QUEUE.containsKey(chunk_offset)) {
+ MiscTools.pausar(1000);
+ }
- ChunkWriterManager.checkChunkID(chunk_id, _upload.getFile_size(), chunk_offset);
+ try {
- try {
+ chunk_mac[0] = file_iv[0];
+ chunk_mac[1] = file_iv[1];
+ chunk_mac[2] = file_iv[0];
+ chunk_mac[3] = file_iv[1];
- chunk_mac[0] = file_iv[0];
- chunk_mac[1] = file_iv[1];
- chunk_mac[2] = file_iv[0];
- chunk_mac[3] = file_iv[1];
+ long conta_chunk = 0L;
- long conta_chunk = 0L;
+ try ( ByteArrayOutputStream baos = CHUNK_QUEUE.remove(chunk_offset)) {
+ chunk_bytes = baos.toByteArray();
+ }
- while (conta_chunk < chunk_size && (reads = is.read(byte_block)) != -1) {
+ try ( ByteArrayInputStream bais = new ByteArrayInputStream(chunk_bytes)) {
+ while (conta_chunk < chunk_size && (reads = bais.read(byte_block)) != -1) {
if (reads < byte_block.length) {
for (int i = reads; i < byte_block.length; i++) {
@@ -172,45 +177,46 @@ public class UploadMACGenerator implements Runnable, SecureSingleThreadNotifiabl
tot += reads;
}
-
- 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) {
- LOG.log(Level.SEVERE, ex.getMessage());
}
- chunk_id++;
-
- int new_cbc_per = (int) ((((double) tot) / _upload.getFile_size()) * 100);
-
- if (new_cbc_per != cbc_per) {
- _upload.getView().updateCBC("CBC-MAC " + String.valueOf(new_cbc_per) + "%");
- cbc_per = new_cbc_per;
+ for (int i = 0; i < file_mac.length; i++) {
+ file_mac[i] ^= chunk_mac[i];
}
+
+ file_mac = bin2i32a(cryptor.doFinal(i32a2bin(file_mac)));
+
+ } catch (IllegalBlockSizeException | BadPaddingException ex) {
+ LOG.log(Level.SEVERE, ex.getMessage());
}
- mac = (tot == _upload.getFile_size());
+ chunk_id++;
- } catch (ChunkInvalidException e) {
+ int new_cbc_per = (int) ((((double) tot) / _upload.getFile_size()) * 100);
- mac = true;
- }
-
- _upload.setTemp_mac_data(String.valueOf(tot) + "#" + String.valueOf(chunk_id) + "#" + Bin2BASE64(i32a2bin(file_mac)));
-
- if (mac) {
-
- int[] meta_mac = {file_mac[0] ^ file_mac[1], file_mac[2] ^ file_mac[3]};
-
- _upload.setFile_meta_mac(meta_mac);
-
- LOG.log(Level.INFO, "{0} MAC GENERATOR {1} finished MAC CALCULATION. Waiting workers to finish uploading (if any)...", new Object[]{Thread.currentThread().getName(), getUpload().getFile_name()});
+ if (new_cbc_per != cbc_per) {
+ _upload.getView().updateCBC("CBC-MAC " + String.valueOf(new_cbc_per) + "%");
+ cbc_per = new_cbc_per;
+ }
}
+
+ mac = (tot == _upload.getFile_size());
+
+ } catch (ChunkInvalidException e) {
+
+ mac = true;
+ }
+
+ _upload.setTemp_mac_data(String.valueOf(tot) + "#" + String.valueOf(chunk_id) + "#" + Bin2BASE64(i32a2bin(file_mac)));
+
+ if (mac) {
+
+ int[] meta_mac = {file_mac[0] ^ file_mac[1], file_mac[2] ^ file_mac[3]};
+
+ _upload.setFile_meta_mac(meta_mac);
+
+ LOG.log(Level.INFO, "{0} MAC GENERATOR {1} finished MAC CALCULATION. Waiting workers to finish uploading (if any)...", new Object[]{Thread.currentThread().getName(), getUpload().getFile_name()});
+
}
while (!_exit && !_upload.isStopped() && !_upload.getChunkworkers().isEmpty()) {
diff --git a/src/main/java/com/tonikelope/megabasterd/UploadView.form b/src/main/java/com/tonikelope/megabasterd/UploadView.form
index 0d75c04a9..015b6986d 100644
--- a/src/main/java/com/tonikelope/megabasterd/UploadView.form
+++ b/src/main/java/com/tonikelope/megabasterd/UploadView.form
@@ -106,11 +106,13 @@
-
-
-
-
-
+
+
+
+
+
+
+
@@ -387,9 +389,6 @@
-
-
-
diff --git a/src/main/java/com/tonikelope/megabasterd/UploadView.java b/src/main/java/com/tonikelope/megabasterd/UploadView.java
index 56f24e12a..8b975fd38 100644
--- a/src/main/java/com/tonikelope/megabasterd/UploadView.java
+++ b/src/main/java/com/tonikelope/megabasterd/UploadView.java
@@ -319,7 +319,6 @@ public class UploadView extends javax.swing.JPanel implements TransferenceView {
open_browser_button.setFont(new java.awt.Font("Dialog", 1, 16)); // NOI18N
open_browser_button.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/icons8-export-30.png"))); // NOI18N
open_browser_button.setText("Open folder in browser");
- open_browser_button.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
open_browser_button.setDoubleBuffered(true);
open_browser_button.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -398,11 +397,12 @@ public class UploadView extends javax.swing.JPanel implements TransferenceView {
.addComponent(file_name_label)
.addComponent(slot_status_label))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(folder_link_button)
- .addComponent(file_link_button)
- .addComponent(file_size_label)
- .addComponent(open_browser_button, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(open_browser_button)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(folder_link_button)
+ .addComponent(file_link_button)
+ .addComponent(file_size_label)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(progress_pbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
diff --git a/src/main/resources/images/mbasterd_screen.png b/src/main/resources/images/mbasterd_screen.png
index 036dd1829..2dadace6c 100644
Binary files a/src/main/resources/images/mbasterd_screen.png and b/src/main/resources/images/mbasterd_screen.png differ