-Experimental "fix" for 509
This commit is contained in:
tonikelope 2016-10-24 01:14:21 +02:00
parent 81bf08df54
commit 5e515ff8a7
10 changed files with 662 additions and 149 deletions

View File

@ -127,10 +127,10 @@ public class ChunkDownloader implements Runnable, SecureNotifiable {
chunk = new Chunk(_download.nextChunkId(), _download.getFile_size(), worker_url);
URL url = new URL(chunk.getUrl());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(MainPanel.CONNECTION_TIMEOUT);
conn.setRequestProperty("User-Agent", MegaAPI.USER_AGENT);
conn.setRequestProperty("Connection", "close");
KissHttpURLConnection kissconn = new KissHttpURLConnection(url);
kissconn.doGET();
error = false;
@ -138,9 +138,9 @@ public class ChunkDownloader implements Runnable, SecureNotifiable {
if(!_exit && !_download.isStopped()) {
is = new ThrottledInputStream(conn.getInputStream(), _download.getMain_panel().getStream_supervisor());
is = new ThrottledInputStream(kissconn.getInputStream(), _download.getMain_panel().getStream_supervisor());
http_status = conn.getResponseCode();
http_status = kissconn.getStatus_code();
if ( http_status != HttpURLConnection.HTTP_OK )
{
@ -236,7 +236,8 @@ public class ChunkDownloader implements Runnable, SecureNotifiable {
getLogger(ChunkDownloader.class.getName()).log(Level.SEVERE, null, ex);
} finally {
conn.disconnect();
kissconn.close();
}
}

View File

@ -5,6 +5,7 @@ import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Logger.getLogger;
import static megabasterd.MainPanel.THROTTLE_SLICE_SIZE;
import static megabasterd.MiscTools.getWaitTimeExpBackOff;
@ -31,7 +32,7 @@ public class ChunkDownloaderMono extends ChunkDownloader {
System.out.println("Worker ["+getId()+"]: let's do some work!");
HttpURLConnection conn=null;
KissHttpURLConnection kissconn = null;
try
{
@ -50,17 +51,19 @@ public class ChunkDownloaderMono extends ChunkDownloader {
worker_url=getDownload().getDownloadUrlForWorker();
}
chunk = new Chunk(getDownload().nextChunkId(), getDownload().getFile_size(), worker_url);
chunk = new Chunk(getDownload().nextChunkId(), getDownload().getFile_size(), null);
if(url == null || error) {
url = new URL(worker_url+"/"+chunk.getOffset());
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(MainPanel.CONNECTION_TIMEOUT);
conn.setRequestProperty("User-Agent", MegaAPI.USER_AGENT);
conn.setRequestProperty("Connection", "close");
is = new ThrottledInputStream(conn.getInputStream(), getDownload().getMain_panel().getStream_supervisor());
http_status = conn.getResponseCode();
kissconn = new KissHttpURLConnection(url);
kissconn.doGET();
is = new ThrottledInputStream(kissconn.getInputStream(), getDownload().getMain_panel().getStream_supervisor());
http_status = kissconn.getStatus_code();
}
error = false;
@ -164,11 +167,15 @@ public class ChunkDownloaderMono extends ChunkDownloader {
getDownload().emergencyStopDownloader(ex.getMessage());
} finally {
if(conn!=null) {
conn.disconnect();
if(kissconn != null) {
try {
kissconn.close();
} catch (IOException ex) {
Logger.getLogger(ChunkDownloaderMono.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
getDownload().stopThisSlot(this);

View File

@ -144,13 +144,10 @@ public class ChunkUploader implements Runnable, SecureNotifiable {
}while(!_exit && !_upload.isStopped() && chunk.getOutputStream().size()<chunk.getSize());
URL url = new URL(chunk.getUrl());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(MainPanel.CONNECTION_TIMEOUT);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", MegaAPI.USER_AGENT);
conn.setRequestProperty("Connection", "close");
conn.setFixedLengthStreamingMode(chunk.getSize());
KissHttpURLConnection kissconn = new KissHttpURLConnection(url);
kissconn.doPOST(chunk.getSize());
tot_bytes_up=0;
@ -162,7 +159,7 @@ public class ChunkUploader implements Runnable, SecureNotifiable {
CipherInputStream cis = new CipherInputStream(chunk.getInputStream(), CryptTools.genCrypter("AES", "AES/CTR/NoPadding", _upload.getByte_file_key(), CryptTools.forwardMEGALinkKeyIV(_upload.getByte_file_iv(), chunk.getOffset())));
out = new ThrottledOutputStream(conn.getOutputStream(), _upload.getMain_panel().getStream_supervisor());
out = new ThrottledOutputStream(kissconn.getOutputStream(), _upload.getMain_panel().getStream_supervisor());
System.out.println(" Subiendo chunk "+chunk.getId()+" desde worker "+ _id +"...");
@ -186,7 +183,7 @@ public class ChunkUploader implements Runnable, SecureNotifiable {
if(!_upload.isStopped()) {
http_status = conn.getResponseCode();
http_status = kissconn.getStatus_code();
if (http_status != HttpURLConnection.HTTP_OK )
{
@ -209,11 +206,13 @@ public class ChunkUploader implements Runnable, SecureNotifiable {
} else {
if((conn.getContentLengthLong() > 0 || conn.getContentLengthLong() == -1) && _upload.getCompletion_handle() == null) {
String content_length = kissconn.getResponseHeader("Content-Length");
if((content_length == null || Long.parseLong(content_length) > 0) && _upload.getCompletion_handle() == null) {
String content_encoding = conn.getContentEncoding();
String content_encoding = kissconn.getResponseHeader("Content-Encoding");
InputStream is=(content_encoding!=null && content_encoding.equals("gzip"))?new GZIPInputStream(conn.getInputStream()):conn.getInputStream();
InputStream is=(content_encoding!=null && content_encoding.equals("gzip"))?new GZIPInputStream(kissconn.getInputStream()):kissconn.getInputStream();
ByteArrayOutputStream byte_res = new ByteArrayOutputStream();
@ -295,7 +294,7 @@ public class ChunkUploader implements Runnable, SecureNotifiable {
getLogger(ChunkUploader.class.getName()).log(Level.SEVERE, null, ex);
} finally {
conn.disconnect();
kissconn.close();
}
}

View File

@ -16,6 +16,7 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Logger.getLogger;
import java.util.zip.GZIPInputStream;
import javax.crypto.CipherInputStream;
@ -43,7 +44,7 @@ public class ChunkUploaderMono extends ChunkUploader {
byte[] buffer = new byte[MainPanel.THROTTLE_SLICE_SIZE];
boolean error = false;
OutputStream out=null;
HttpURLConnection conn=null;
KissHttpURLConnection kissconn = null;
try
{
@ -55,7 +56,7 @@ public class ChunkUploaderMono extends ChunkUploader {
while(!isExit() && !getUpload().isStopped())
{
chunk = new Chunk(getUpload().nextChunkId(), getUpload().getFile_size(), worker_url);
chunk = new Chunk(getUpload().nextChunkId(), getUpload().getFile_size(), null);
f.seek(chunk.getOffset());
@ -72,14 +73,13 @@ public class ChunkUploaderMono extends ChunkUploader {
if(url == null || error) {
url = new URL(worker_url+"/"+chunk.getOffset());
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(MainPanel.CONNECTION_TIMEOUT);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", MegaAPI.USER_AGENT);
conn.setRequestProperty("Connection", "close");
conn.setFixedLengthStreamingMode(getUpload().getFile_size()-chunk.getOffset());
out = new ThrottledOutputStream(conn.getOutputStream(), getUpload().getMain_panel().getStream_supervisor());
kissconn = new KissHttpURLConnection(url);
kissconn.doPOST(getUpload().getFile_size()-chunk.getOffset());
out = new ThrottledOutputStream(kissconn.getOutputStream(), getUpload().getMain_panel().getStream_supervisor());
}
tot_bytes_up=0;
@ -179,23 +179,25 @@ public class ChunkUploaderMono extends ChunkUploader {
}
if(!error && chunk.getOffset() + tot_bytes_up == getUpload().getFile_size() && conn != null) {
if(!error && chunk.getOffset() + tot_bytes_up == getUpload().getFile_size() && kissconn != null) {
http_status = conn.getResponseCode();
http_status = kissconn.getStatus_code();
String content_length = kissconn.getResponseHeader("Content-Length");
if (http_status != HttpURLConnection.HTTP_OK )
{
throw new IOException("UPLOAD FAILED! (HTTP STATUS: "+ http_status+")");
} else if(!(conn.getContentLengthLong() > 0 || conn.getContentLengthLong() == -1)) {
} else if(!(content_length == null || Long.parseLong(content_length) > 0)) {
throw new IOException("UPLOAD FAILED! (Empty completion handle!)");
} else {
String content_encoding = conn.getContentEncoding();
String content_encoding = kissconn.getResponseHeader("Content-Encoding");
InputStream is=(content_encoding!=null && content_encoding.equals("gzip"))?new GZIPInputStream(conn.getInputStream()):conn.getInputStream();
InputStream is=(content_encoding!=null && content_encoding.equals("gzip"))?new GZIPInputStream(kissconn.getInputStream()):kissconn.getInputStream();
ByteArrayOutputStream byte_res = new ByteArrayOutputStream();
@ -234,9 +236,13 @@ public class ChunkUploaderMono extends ChunkUploader {
} finally {
if(conn!=null) {
if(kissconn!=null) {
conn.disconnect();
try {
kissconn.close();
} catch (IOException ex) {
Logger.getLogger(ChunkUploaderMono.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

View File

@ -0,0 +1,443 @@
package megabasterd;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.CookieManager;
import java.net.Socket;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
*
* @author tonikelope
*
* EXPERIMENTAL!!
*/
public class KissHttpURLConnection {
private URL _url;
private int _status_code;
private final Map<String,List<String>> _response_headers;
private final Map<String,List<String>> _request_headers;
private Socket _socket;
private final CookieManager _cookie_manager;
private boolean _cookies_put;
public KissHttpURLConnection(URL url) {
_url = url;
_response_headers = new HashMap<>();
_request_headers = new HashMap<>();
_cookie_manager = new CookieManager();
_cookies_put=false;
_socket = null;
_status_code = -1;
}
public CookieManager getCookie_manager() {
return _cookie_manager;
}
public InputStream getInputStream() throws IOException {
try {
if(_status_code == -1) {
_parseStatusCode();
}
if(_response_headers.isEmpty()) {
_parseResponseHeaders();
}
if(!_cookies_put) {
_cookie_manager.put(_url.toURI(), _response_headers);
_cookies_put = true;
}
} catch (URISyntaxException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
return _socket.getInputStream();
}
public OutputStream getOutputStream() throws IOException {
return _socket.getOutputStream();
}
public Map<String,List<String>> getRequest_headers() {
return _request_headers;
}
public Map<String,List<String>> getResponse_headers() {
return _response_headers;
}
public String getRequestHeader(String key) {
return getRequestHeader(key, 0);
}
public String getRequestHeader(String key, int pos) {
return _request_headers.containsKey(_capitalizeHeaderKey(key))?_request_headers.get(_capitalizeHeaderKey(key)).get(pos):null;
}
public String getResponseHeader(String key) {
return getResponseHeader(key, 0);
}
public String getResponseHeader(String key, int pos) {
return _response_headers.containsKey(_capitalizeHeaderKey(key))?_response_headers.get(_capitalizeHeaderKey(key)).get(pos):null;
}
public void setRequestHeader(String key, String val) {
key = _capitalizeHeaderKey(key);
if(!_request_headers.containsKey(key)) {
List list;
_request_headers.put(key, list = new ArrayList<>());
list.add(val);
} else {
_request_headers.get(key).add(val);
}
}
public void removeRequestHeader(String key) {
_request_headers.remove(_capitalizeHeaderKey(key));
}
public void removeRequestHeader(String key, String value) {
key = _capitalizeHeaderKey(key);
_request_headers.get(key).remove(value);
if(_request_headers.get(key).isEmpty()) {
_request_headers.remove(key);
}
}
public URL getUrl() {
return _url;
}
public void setUrl(URL url) {
_url = url;
try {
close();
} catch (IOException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
public int getStatus_code() {
if(_status_code == -1) {
try {
_parseStatusCode();
} catch (IOException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
return _status_code;
}
public void close() throws IOException {
if(_socket != null && !_socket.isClosed()) {
_socket.close();
}
_socket = null;
}
private void _parseStatusCode() throws IOException {
int b;
ByteArrayOutputStream byte_res = new ByteArrayOutputStream();
do{
b = _socket.getInputStream().read();
if(b != -1) {
byte_res.write(b);
}
}while(b!=-1 && b != 0x0A);
String temp = new String(byte_res.toByteArray()).trim();
Pattern header_pattern = Pattern.compile("HTTP*/*[0-9]+\\.[0-9]+ +([0-9]+)");
Matcher matcher = header_pattern.matcher(temp);
if(matcher.find()) {
_status_code = Integer.parseInt(matcher.group(1));
} else {
throw new IOException("BAD HTTP STATUS CODE!");
}
}
private void _parseResponseHeaders() {
try {
String temp;
Pattern header_pattern = Pattern.compile("([^:]+):(.*)");
do {
int b;
ByteArrayOutputStream byte_res = new ByteArrayOutputStream();
do{
b = _socket.getInputStream().read();
byte_res.write(b);
}while(b != -1 && b != 0x0A);
temp = new String(byte_res.toByteArray()).trim();
if(temp.length() > 0) {
Matcher matcher = header_pattern.matcher(temp);
if(matcher.find()) {
String key = _capitalizeHeaderKey(matcher.group(1).trim());
if(!_response_headers.containsKey(key)) {
List list;
_response_headers.put(key, (list = new ArrayList<>()));
list.add(matcher.group(2).trim());
} else {
List list = _response_headers.get(key);
list.add(matcher.group(2).trim());
}
}
}
}while(temp.length() > 0);
} catch (IOException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void doGET() {
try {
_initSocket();
_status_code = -1;
if(!_response_headers.isEmpty() && !_cookies_put) {
_cookie_manager.put(_url.toURI(), _response_headers);
_cookies_put = true;
}
_response_headers.clear();
ByteArrayOutputStream byte_req = new ByteArrayOutputStream();
byte_req.write(("GET " + (_url.getFile().isEmpty()?"/":_url.getFile()) + " HTTP/1.1\r\n").getBytes());
byte_req.write(("Host: "+_url.getHost()+"\r\n").getBytes());
byte_req.write(("Connection: close\r\n").getBytes());
for(Map.Entry pair : _request_headers.entrySet()) {
for(Object s:(List)pair.getValue()) {
byte_req.write((pair.getKey()+":"+(String)s+"\r\n").getBytes());
}
}
for(List list : _cookie_manager.get(_url.toURI(), _request_headers).values()) {
for(Object s:list) {
byte_req.write(("Cookie: "+(String)s + "\r\n").getBytes());
}
}
byte_req.write("\r\n".getBytes());
_socket.getOutputStream().write(byte_req.toByteArray());
_cookie_manager.put(_url.toURI(), _response_headers);
_cookies_put = true;
} catch (IOException | URISyntaxException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void doPOST(long length) {
try {
_initSocket();
_status_code = -1;
if(!_response_headers.isEmpty() && !_cookies_put) {
_cookie_manager.put(_url.toURI(),_response_headers);
_cookies_put = true;
}
_response_headers.clear();
ByteArrayOutputStream byte_req = new ByteArrayOutputStream();
byte_req.write(("POST " + (_url.getFile().isEmpty()?"/":_url.getFile()) + " HTTP/1.1\r\n").getBytes());
byte_req.write(("Host: "+_url.getHost()+"\r\n").getBytes());
byte_req.write(("Connection: close\r\n").getBytes());
byte_req.write(("Content-Length: " + length + "\r\n").getBytes());
for(Map.Entry pair : _request_headers.entrySet()) {
for(Object s:(List)pair.getValue()) {
byte_req.write((pair.getKey()+":"+(String)s+"\r\n").getBytes());
}
}
for(List list : _cookie_manager.get(_url.toURI(), _request_headers).values()) {
for(Object s:list) {
byte_req.write(("Cookie: "+(String)s + "\r\n").getBytes());
}
}
byte_req.write("\r\n".getBytes());
_socket.getOutputStream().write(byte_req.toByteArray());
_cookies_put = false;
} catch (IOException | URISyntaxException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void _initSocket() {
if(_socket == null){
if(_url.getProtocol().equals("http")) {
try {
_socket = new Socket(_url.getHost(), _url.getPort()!=-1?_url.getPort():_url.getDefaultPort());
} catch (UnknownHostException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
} else if(_url.getProtocol().equals("https")) {
try {
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
_socket = (SSLSocket)factory.createSocket(_url.getHost(), _url.getPort()!=-1?_url.getPort():_url.getDefaultPort());
((SSLSocket)_socket).setUseClientMode(true);
((SSLSocket)_socket).startHandshake();
} catch (IOException ex) {
Logger.getLogger(KissHttpURLConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
private String _capitalizeHeaderKey(String value) {
StringBuilder builder = new StringBuilder(value);
for(int i=0; i<builder.length(); i++) {
if(i == 0 || builder.charAt(i-1) == '-') {
builder.setCharAt(i, Character.toUpperCase(builder.charAt(i)));
}
}
return builder.toString();
}
}

View File

@ -358,6 +358,8 @@ public final class KissVideoStreamServer implements HttpHandler, SecureNotifiabl
String httpmethod = xchg.getRequestMethod();
URLConnection urlConn = null;
try{
Headers reqheaders=xchg.getRequestHeaders();
@ -423,7 +425,7 @@ public final class KissVideoStreamServer implements HttpHandler, SecureNotifiabl
String file_ext = file_name.substring(file_name.lastIndexOf('.')+1).toLowerCase();
URLConnection urlConn;
if(httpmethod.equals("HEAD")) {
@ -537,10 +539,6 @@ public final class KissVideoStreamServer implements HttpHandler, SecureNotifiabl
urlConn.setConnectTimeout(MainPanel.CONNECTION_TIMEOUT);
urlConn.setRequestProperty("User-Agent", MegaAPI.USER_AGENT);
urlConn.setRequestProperty("Connection", "close");
is = urlConn.getInputStream();
byte[] iv = CryptTools.initMEGALinkKeyIV(file_key);

View File

@ -59,7 +59,7 @@ import static megabasterd.Transference.MAX_TRANSFERENCE_SPEED_DEFAULT;
*/
public final class MainPanel {
public static final String VERSION="1.37";
public static final String VERSION="1.38";
public static final int CONNECTION_TIMEOUT = 30000;
public static final int THROTTLE_SLICE_SIZE=16*1024;
public static final int STREAMER_PORT = 1337;

View File

@ -4,15 +4,16 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Logger.getLogger;
import java.util.zip.GZIPInputStream;
import javax.crypto.Cipher;
@ -34,7 +35,6 @@ public final class MegaAPI {
public static final String API_URL = "https://g.api.mega.co.nz";
public static final String API_KEY = null;
public static final String USER_AGENT="Mozilla/5.0";
public static final int REQ_ID_LENGTH = 10;
@ -45,7 +45,7 @@ public final class MegaAPI {
return error != null?Integer.parseInt(error):0;
}
private int _seqno;
private long _seqno;
private String _sid;
@ -84,7 +84,7 @@ public final class MegaAPI {
Random randomno = new Random();
_seqno=randomno.nextInt();
_seqno=randomno.nextLong() & 0xffffffffL;
}
public String getEmail() {
@ -127,7 +127,7 @@ public final class MegaAPI {
String request = "[{\"a\":\"us\", \"user\":\""+_email+"\", \"uh\":\""+_user_hash+"\"}]";
URL url_api = new URL(API_URL+"/cs?id="+_seqno+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+(API_KEY!=null?"&ak="+API_KEY:""));
String res = _rawRequest(request, url_api);
@ -191,7 +191,7 @@ public final class MegaAPI {
URL url_api;
url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String res = _rawRequest(request, url_api);
@ -235,7 +235,7 @@ public final class MegaAPI {
try {
url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String res = _rawRequest(request, url_api);
@ -273,7 +273,7 @@ public final class MegaAPI {
}
private String _rawRequest(String request, URL url_api) throws IOException, MegaAPIException {
private String _rawRequest(String request, URL url_api) throws MegaAPIException {
boolean error;
@ -283,75 +283,85 @@ public final class MegaAPI {
do{
error = false;
KissHttpURLConnection kissconn = new KissHttpURLConnection(url_api);
kissconn.setRequestHeader("Content-Type", "application/json");
kissconn.doPOST(request.getBytes().length);
try {
kissconn.getOutputStream().write(request.getBytes());
} catch (IOException ex) {
Logger.getLogger(MegaAPI.class.getName()).log(Level.SEVERE, null, ex);
}
_seqno++;
HttpURLConnection conn = (HttpURLConnection) url_api.openConnection();
conn.setConnectTimeout(MainPanel.CONNECTION_TIMEOUT);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setRequestProperty("Connection", "close");
OutputStream out;
out = conn.getOutputStream();
out.write(request.getBytes());
out.close();
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK)
if (kissconn.getStatus_code() != HttpURLConnection.HTTP_OK)
{
System.out.println("Failed : HTTP error code : " + conn.getResponseCode());
System.out.println("Failed : HTTP error code : " + kissconn.getStatus_code());
error = true;
} else {
String content_encoding = conn.getContentEncoding();
InputStream is=(content_encoding!=null && content_encoding.equals("gzip"))?new GZIPInputStream(conn.getInputStream()):conn.getInputStream();
ByteArrayOutputStream byte_res = new ByteArrayOutputStream();
byte[] buffer = new byte[16*1024];
int reads;
while( (reads=is.read(buffer)) != -1 ) {
byte_res.write(buffer, 0, reads);
}
response = new String(byte_res.toByteArray());
int mega_error;
if( (mega_error=checkMEGAError(response))!=0 )
{
if(mega_error == -3) {
error = true;
InputStream is = null;
try {
String content_encoding = kissconn.getResponseHeader("Content-Encoding");
is = (content_encoding!=null && content_encoding.equals("gzip"))?new GZIPInputStream(kissconn.getInputStream()):kissconn.getInputStream();
ByteArrayOutputStream byte_res = new ByteArrayOutputStream();
byte[] buffer = new byte[16*1024];
int reads;
while( (reads=is.read(buffer)) != -1 ) {
} else {
throw new MegaAPIException(String.valueOf(mega_error));
byte_res.write(buffer, 0, reads);
} response = new String(byte_res.toByteArray());
int mega_error;
if( (mega_error=checkMEGAError(response))!=0 )
{
if(mega_error == -3) {
error = true;
} else {
throw new MegaAPIException(String.valueOf(mega_error));
}
}
}
} catch (IOException ex) {
Logger.getLogger(MegaAPI.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
kissconn.close();
} catch (IOException ex) {
Logger.getLogger(MegaAPI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
if(error) {
try {
Thread.sleep( getWaitTimeExpBackOff(conta_error++) );
} catch (InterruptedException ex) {
getLogger(MegaAPI.class.getName()).log(Level.SEVERE, null, ex);
try {
Thread.sleep( getWaitTimeExpBackOff(conta_error++) );
} catch (InterruptedException ex) {
getLogger(MegaAPI.class.getName()).log(Level.SEVERE, null, ex);
}
String new_url = url_api.getProtocol()+"://"+url_api.getAuthority()+url_api.getFile().replace("id\\=[0-9]+", "id="+String.valueOf(++_seqno));
url_api = new URL(new_url);
} catch (MalformedURLException ex) {
Logger.getLogger(MegaAPI.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
conta_error = 0;
}
conn.disconnect();
}while(error);
@ -375,12 +385,12 @@ public final class MegaAPI {
request = "[{\"a\":\"g\", \"g\":\"1\", \"n\":\""+file_id+"\"}]";
url_api = new URL(API_URL+"/cs?id="+_seqno+(API_KEY!=null?"&ak="+API_KEY:"")+"&n="+folder_id);
url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+(API_KEY!=null?"&ak="+API_KEY:"")+"&n="+folder_id);
} else {
request = "[{\"a\":\"g\", \"g\":\"1\", \"p\":\""+file_id+"\"}]";
url_api = new URL(API_URL+"/cs?id="+_seqno+(API_KEY!=null?"&ak="+API_KEY:""));
url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+(API_KEY!=null?"&ak="+API_KEY:""));
}
String data = _rawRequest(request, url_api);
@ -412,13 +422,13 @@ public final class MegaAPI {
request = "[{\"a\":\"g\", \"g\":\"1\", \"n\":\""+file_id+"\"}]";
url_api = new URL(API_URL+"/cs?id="+_seqno+(API_KEY!=null?"&ak="+API_KEY:"")+"&n="+folder_id);
url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+(API_KEY!=null?"&ak="+API_KEY:"")+"&n="+folder_id);
} else {
request = "[{\"a\":\"g\", \"p\":\""+file_id+"\"}]";
url_api = new URL(API_URL+"/cs?id="+_seqno+(API_KEY!=null?"&ak="+API_KEY:""));
url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+(API_KEY!=null?"&ak="+API_KEY:""));
}
String data = _rawRequest(request, url_api);
@ -450,8 +460,6 @@ public final class MegaAPI {
}
private byte[] _encAttr(String attr, byte[] key) {
byte[] attr_byte = ("MEGA"+attr).getBytes();
@ -510,7 +518,7 @@ public final class MegaAPI {
String request = "[{\"a\":\"u\", \"s\":"+String.valueOf(f.length())+"}]";
URL url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String res = _rawRequest(request, url_api);
@ -535,7 +543,7 @@ public final class MegaAPI {
byte[] enc_att = _encAttr("{\"n\":\""+fbasename+"\"}", i32a2bin(Arrays.copyOfRange(ul_key, 0, 4)));
URL url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String request = "[{\"a\":\"p\", \"t\":\""+mega_parent+"\", \"n\":[{\"h\":\""+completion_handle+"\", \"t\":0, \"a\":\""+Bin2UrlBASE64(enc_att)+"\", \"k\":\""+Bin2UrlBASE64(encryptKey(i32a2bin(fkey), master_key))+"\"}], \"i\":\""+_req_id+"\", \"cr\" : [ [\"" + root_node + "\"] , [\""+completion_handle+"\"] , [0,0, \""+Bin2UrlBASE64(encryptKey(i32a2bin(fkey), share_key))+"\"]]}]";
@ -588,7 +596,7 @@ public final class MegaAPI {
byte[] enc_node_key = encryptKey(node_key, master_key);
URL url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String request="[{\"a\":\"p\", \"t\":\""+parent_node+"\", \"n\":[{\"h\":\"xxxxxxxx\",\"t\":1,\"a\":\""+Bin2UrlBASE64(enc_att)+"\",\"k\":\""+Bin2UrlBASE64(enc_node_key)+"\"}],\"i\":\""+_req_id+"\"}]";
@ -621,7 +629,7 @@ public final class MegaAPI {
byte[] enc_node_key_s = encryptKey(node_key, share_key);
URL url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String request="[{\"a\":\"p\", \"t\":\""+parent_node+"\", \"n\":[{\"h\":\"xxxxxxxx\",\"t\":1,\"a\":\""+Bin2UrlBASE64(enc_att)+"\",\"k\":\""+Bin2UrlBASE64(enc_node_key)+"\"}],\"i\":\""+_req_id+"\", \"cr\" : [ [\"" + root_node + "\"] , [\"xxxxxxxx\"] , [0,0, \""+Bin2UrlBASE64(enc_node_key_s)+"\"]]}]";
@ -654,7 +662,7 @@ public final class MegaAPI {
String request = "[{\"a\":\"l\", \"n\":\""+node+"\"}]";
URL url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String res=_rawRequest(request, url_api);
@ -687,7 +695,7 @@ public final class MegaAPI {
String request = "[{\"a\":\"l\", \"n\":\""+node+"\", \"i\":\""+_req_id+"\"}]";
URL url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String res=_rawRequest(request, url_api);
@ -738,7 +746,7 @@ public final class MegaAPI {
System.out.println(request);
URL url_api = new URL(API_URL+"/cs?id="+_seqno+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+"&sid="+_sid+(API_KEY!=null?"&ak="+API_KEY:""));
String res=_rawRequest(request, url_api);
@ -772,7 +780,7 @@ public final class MegaAPI {
String request = "[{\"a\":\"f\", \"c\":\"1\", \"r\":\"1\"}]";
URL url_api = new URL(API_URL+"/cs?id="+_seqno+(API_KEY!=null?"&ak="+API_KEY:"")+"&n="+folder_id);
URL url_api = new URL(API_URL+"/cs?id="+String.valueOf(_seqno)+(API_KEY!=null?"&ak="+API_KEY:"")+"&n="+folder_id);
String res=_rawRequest(request, url_api);

View File

@ -16,6 +16,7 @@ import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@ -53,7 +54,6 @@ import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.xml.bind.DatatypeConverter;
import static megabasterd.MainPanel.CONNECTION_TIMEOUT;
import static megabasterd.MainPanel.VERSION;
public final class MiscTools {
@ -589,7 +589,7 @@ public final class MiscTools {
String response = new String(byte_res.toByteArray()).trim();
return findFirstRegex("http", response, 0)!=null?response:link;
return findFirstRegex("http", response, 0)!=null?response:link;
}
public static String formatBytes(Long bytes) {
@ -909,21 +909,25 @@ public final class MiscTools {
public static boolean checkMegaDownloadUrl(String string_url) {
boolean url_ok=false;
try {
URL url = new URL(string_url+"/0-0");
URLConnection connection = url.openConnection();
connection.setConnectTimeout(CONNECTION_TIMEOUT);
connection.setRequestProperty("User-Agent", MegaAPI.USER_AGENT);
try (InputStream is = connection.getInputStream()) {
while(is.read()!=-1);
}
url_ok=true;
}catch (Exception ex) {}
URL url = new URL(string_url+"/0");
KissHttpURLConnection kissconn = new KissHttpURLConnection(url);
kissconn.doGET();
url_ok=(kissconn.getStatus_code() == HttpURLConnection.HTTP_OK);
kissconn.close();
} catch (MalformedURLException ex) {
Logger.getLogger(MiscTools.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(MiscTools.class.getName()).log(Level.SEVERE, null, ex);
}
return url_ok;
}
@ -960,7 +964,7 @@ public final class MiscTools {
}
} catch (Exception ex) {
getLogger(AboutDialog.class.getName()).log(Level.SEVERE, null, ex);
getLogger(MiscTools.class.getName()).log(Level.SEVERE, null, ex);
}
return new_version;
@ -971,7 +975,53 @@ public final class MiscTools {
try {
Desktop.getDesktop().browse(new URI(url));
} catch (URISyntaxException | IOException ex) {
Logger.getLogger(AboutDialog.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(MiscTools.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static byte[] decodeChunkedByteArray(byte[] data) {
ByteArrayOutputStream decoded = new ByteArrayOutputStream();
boolean EOF = false;
int i = 0;
do {
int b;
ByteArrayOutputStream temp = new ByteArrayOutputStream();
do{
b = data[i++];
temp.write(b);
}while(b != -1 && b != 0x0A);
long chunk_length;
String cl = new String(temp.toByteArray()).trim();
chunk_length = Long.parseLong(cl.length()>0?cl:"-1",16);
if(chunk_length > 0) {
for(long j=0; j<chunk_length; j++) {
decoded.write(data[i++]);
}
} else if(chunk_length == 0) {
EOF = true;
}
} while(!EOF);
return decoded.toByteArray();
}
}

View File

@ -11,6 +11,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -313,7 +314,7 @@ public final class SettingsDialog extends javax.swing.JDialog {
swingReflectionInvoke("setVisible", unlock_accounts_button, false);
for (HashMap.Entry pair : _main_panel.getMega_accounts().entrySet()) {
for (Map.Entry pair : _main_panel.getMega_accounts().entrySet()) {
HashMap<String,Object> data = (HashMap)pair.getValue();
@ -341,7 +342,7 @@ public final class SettingsDialog extends javax.swing.JDialog {
swingReflectionInvoke("setVisible", unlock_accounts_button, false);
for (HashMap.Entry pair : _main_panel.getMega_accounts().entrySet()) {
for (Map.Entry pair : _main_panel.getMega_accounts().entrySet()) {
HashMap<String,Object> data = (HashMap)pair.getValue();
@ -1115,7 +1116,7 @@ public final class SettingsDialog extends javax.swing.JDialog {
insertSettingValueInDB("mega_master_pass_hash", _main_panel.getMega_master_pass_hash());
for (HashMap.Entry pair : _main_panel.getMega_accounts().entrySet()) {
for (Map.Entry pair : _main_panel.getMega_accounts().entrySet()) {
HashMap<String,Object> data = (HashMap)pair.getValue();
@ -1212,7 +1213,7 @@ public final class SettingsDialog extends javax.swing.JDialog {
swingReflectionInvoke("setEnabled", delete_all_accounts_button, true);
for (HashMap.Entry pair : _main_panel.getMega_accounts().entrySet()) {
for (Map.Entry pair : _main_panel.getMega_accounts().entrySet()) {
HashMap<String,Object> data = (HashMap)pair.getValue();
@ -1276,7 +1277,7 @@ public final class SettingsDialog extends javax.swing.JDialog {
mega_accounts_table.setModel(new_model);
for (HashMap.Entry pair : _main_panel.getMega_accounts().entrySet()) {
for (Map.Entry pair : _main_panel.getMega_accounts().entrySet()) {
try {
DBTools.deleteMegaAccount((String) pair.getKey());