aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/pixart/messenger/generator/IqGenerator.java8
-rw-r--r--src/main/java/de/pixart/messenger/http/HttpUploadConnection.java181
-rw-r--r--src/main/java/de/pixart/messenger/utils/Namespace.java2
3 files changed, 100 insertions, 91 deletions
diff --git a/src/main/java/de/pixart/messenger/generator/IqGenerator.java b/src/main/java/de/pixart/messenger/generator/IqGenerator.java
index 8e3584598..234ddc3b4 100644
--- a/src/main/java/de/pixart/messenger/generator/IqGenerator.java
+++ b/src/main/java/de/pixart/messenger/generator/IqGenerator.java
@@ -354,11 +354,9 @@ public class IqGenerator extends AbstractGenerator {
IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
packet.setTo(host);
Element request = packet.addChild("request", Namespace.HTTP_UPLOAD);
- request.addChild("filename").setContent(convertFilename(file.getName()));
- request.addChild("size").setContent(String.valueOf(file.getExpectedSize()));
- if (mime != null) {
- request.addChild("content-type").setContent(mime);
- }
+ request.setAttribute("filename", convertFilename(file.getName()));
+ request.setAttribute("size", file.getExpectedSize());
+ request.setAttribute("content-type", mime);
return packet;
}
diff --git a/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java b/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java
index 88a95584c..36c6b293f 100644
--- a/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java
+++ b/src/main/java/de/pixart/messenger/http/HttpUploadConnection.java
@@ -11,6 +11,7 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.HashMap;
import javax.net.ssl.HttpsURLConnection;
@@ -26,7 +27,6 @@ import de.pixart.messenger.services.XmppConnectionService;
import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.Namespace;
import de.pixart.messenger.xml.Element;
-import de.pixart.messenger.xmpp.OnIqPacketReceived;
import de.pixart.messenger.xmpp.jid.Jid;
import de.pixart.messenger.xmpp.stanzas.IqPacket;
@@ -43,6 +43,7 @@ public class HttpUploadConnection implements Transferable {
private String mime;
private URL mGetUrl;
private URL mPutUrl;
+ private HashMap<String,String> mPutHeaders;
private boolean mUseTor = false;
private byte[] key = null;
@@ -122,103 +123,113 @@ public class HttpUploadConnection implements Transferable {
this.mFileInputStream = pair.first;
Jid host = account.getXmppConnection().findDiscoItemByFeature(Namespace.HTTP_UPLOAD);
IqPacket request = mXmppConnectionService.getIqGenerator().requestHttpUploadSlot(host, file, mime);
- mXmppConnectionService.sendIqPacket(account, request, new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- Element slot = packet.findChild("slot", Namespace.HTTP_UPLOAD);
- if (slot != null) {
- try {
- mGetUrl = new URL(slot.findChildContent("get"));
- mPutUrl = new URL(slot.findChildContent("put"));
- if (!canceled) {
- new Thread(new FileUploader()).start();
+ mXmppConnectionService.sendIqPacket(account, request, (account, packet) -> {
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ Element slot = packet.findChild("slot", Namespace.HTTP_UPLOAD);
+ if (slot != null) {
+ try {
+ final Element put = slot.findChild("put");
+ final Element get = slot.findChild("get");
+ final String putUrl = put == null ? null : put.getAttribute("url");
+ final String getUrl = get == null ? null : get.getAttribute("url");
+ if (getUrl != null && putUrl != null) {
+ this.mGetUrl = new URL(getUrl);
+ this.mPutUrl = new URL(putUrl);
+ this.mPutHeaders = new HashMap<>();
+ for (Element child : put.getChildren()) {
+ if ("header".equals(child.getName())) {
+ String name = child.getAttribute("name");
+ String value = child.getContent();
+ if (name != null && value != null && !name.trim().contains("\n") && !value.trim().contains("\n")) {
+ this.mPutHeaders.put(name.trim(), value.trim());
+ }
+ }
}
- return;
- } catch (MalformedURLException e) {
- //fall through
}
+ if (!canceled) {
+ new Thread(this::upload).start();
+ }
+ return;
+ } catch (MalformedURLException e) {
+ //fall through
}
}
- Log.d(Config.LOGTAG, account.getJid().toString() + ": invalid response to slot request " + packet);
- fail(IqParser.extractErrorMessage(packet));
}
+ Log.d(Config.LOGTAG, account.getJid().toString() + ": invalid response to slot request " + packet);
+ fail(IqParser.extractErrorMessage(packet));
});
message.setTransferable(this);
mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND);
}
- private class FileUploader implements Runnable {
-
- @Override
- public void run() {
- this.upload();
- }
-
- private void upload() {
- OutputStream os = null;
- HttpURLConnection connection = null;
- PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_upload_" + message.getUuid());
- try {
- wakeLock.acquire();
- final int expectedFileSize = (int) file.getExpectedSize();
- final int readTimeout = (expectedFileSize / 2048) + Config.SOCKET_TIMEOUT * 1000; //assuming a minimum transfer speed of 16kbit/s
- Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString() + " w/ read timeout of " + readTimeout + "s");
- if (mUseTor) {
- connection = (HttpURLConnection) mPutUrl.openConnection(mHttpConnectionManager.getProxy());
- } else {
- connection = (HttpURLConnection) mPutUrl.openConnection();
- }
- if (connection instanceof HttpsURLConnection) {
- mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, true);
- }
- connection.setRequestMethod("PUT");
- connection.setFixedLengthStreamingMode(expectedFileSize);
- connection.setRequestProperty("Content-Type", mime == null ? "application/octet-stream" : mime);
- connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getIdentityName());
- connection.setDoOutput(true);
- connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000);
- connection.setReadTimeout(readTimeout * 1000);
- connection.connect();
- os = connection.getOutputStream();
- transmitted = 0;
- int count;
- byte[] buffer = new byte[4096];
- while (((count = mFileInputStream.read(buffer)) != -1) && !canceled) {
- transmitted += count;
- os.write(buffer, 0, count);
- mHttpConnectionManager.updateConversationUi(false);
- }
- os.flush();
- os.close();
- mFileInputStream.close();
- int code = connection.getResponseCode();
- if (code == 200 || code == 201) {
- Log.d(Config.LOGTAG, "finished uploading file");
- if (key != null) {
- mGetUrl = CryptoHelper.toAesGcmUrl(new URL(mGetUrl.toString() + "#" + CryptoHelper.bytesToHex(key)));
- }
- mXmppConnectionService.getFileBackend().updateFileParams(message, mGetUrl);
- mXmppConnectionService.getFileBackend().updateMediaScanner(file);
- message.setTransferable(null);
- message.setCounterpart(message.getConversation().getJid().toBareJid());
- mXmppConnectionService.resendMessage(message, delayed);
- } else {
- Log.d(Config.LOGTAG, "http upload failed because response code was " + code);
- fail("http upload failed because response code was " + code);
+ private void upload() {
+ OutputStream os = null;
+ HttpURLConnection connection = null;
+ PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_upload_" + message.getUuid());
+ try {
+ final int expectedFileSize = (int) file.getExpectedSize();
+ final int readTimeout = (expectedFileSize / 2048) + Config.SOCKET_TIMEOUT; //assuming a minimum transfer speed of 16kbit/s
+ wakeLock.acquire(readTimeout);
+ Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString() + " w/ read timeout of " + readTimeout + "s");
+ if (mUseTor) {
+ connection = (HttpURLConnection) mPutUrl.openConnection(mHttpConnectionManager.getProxy());
+ } else {
+ connection = (HttpURLConnection) mPutUrl.openConnection();
+ }
+ if (connection instanceof HttpsURLConnection) {
+ mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, true);
+ }
+ connection.setRequestMethod("PUT");
+ connection.setFixedLengthStreamingMode(expectedFileSize);
+ connection.setRequestProperty("Content-Type", mime == null ? "application/octet-stream" : mime);
+ connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getIdentityName());
+ if (mPutHeaders != null) {
+ for (HashMap.Entry<String, String> entry : mPutHeaders.entrySet()) {
+ connection.setRequestProperty(entry.getKey(), entry.getValue());
}
- } catch (IOException e) {
- e.printStackTrace();
- Log.d(Config.LOGTAG, "http upload failed " + e.getMessage());
- fail(e.getMessage());
- } finally {
- FileBackend.close(mFileInputStream);
- FileBackend.close(os);
- if (connection != null) {
- connection.disconnect();
+ }
+ connection.setDoOutput(true);
+ connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000);
+ connection.setReadTimeout(readTimeout * 1000);
+ connection.connect();
+ os = connection.getOutputStream();
+ transmitted = 0;
+ int count;
+ byte[] buffer = new byte[4096];
+ while (((count = mFileInputStream.read(buffer)) != -1) && !canceled) {
+ transmitted += count;
+ os.write(buffer, 0, count);
+ mHttpConnectionManager.updateConversationUi(false);
+ }
+ os.flush();
+ os.close();
+ mFileInputStream.close();
+ int code = connection.getResponseCode();
+ if (code == 200 || code == 201) {
+ Log.d(Config.LOGTAG, "finished uploading file");
+ if (key != null) {
+ mGetUrl = CryptoHelper.toAesGcmUrl(new URL(mGetUrl.toString() + "#" + CryptoHelper.bytesToHex(key)));
}
- wakeLock.release();
+ mXmppConnectionService.getFileBackend().updateFileParams(message, mGetUrl);
+ mXmppConnectionService.getFileBackend().updateMediaScanner(file);
+ message.setTransferable(null);
+ message.setCounterpart(message.getConversation().getJid().toBareJid());
+ mXmppConnectionService.resendMessage(message, delayed);
+ } else {
+ Log.d(Config.LOGTAG, "http upload failed because response code was " + code);
+ fail("http upload failed because response code was " + code);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ Log.d(Config.LOGTAG, "http upload failed " + e.getMessage());
+ fail(e.getMessage());
+ } finally {
+ FileBackend.close(mFileInputStream);
+ FileBackend.close(os);
+ if (connection != null) {
+ connection.disconnect();
}
+ wakeLock.release();
}
}
}
diff --git a/src/main/java/de/pixart/messenger/utils/Namespace.java b/src/main/java/de/pixart/messenger/utils/Namespace.java
index cdf8f8650..679fc191f 100644
--- a/src/main/java/de/pixart/messenger/utils/Namespace.java
+++ b/src/main/java/de/pixart/messenger/utils/Namespace.java
@@ -5,7 +5,7 @@ public final class Namespace {
public static final String ROSTER = "jabber:iq:roster";
public static final String REGISTER = "jabber:iq:register";
public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams";
- public static final String HTTP_UPLOAD = "urn:xmpp:http:upload";
+ public static final String HTTP_UPLOAD = "urn:xmpp:http:upload:0";
public static final String STANZA_IDS = "urn:xmpp:sid:0";
public static final String MAM = "urn:xmpp:mam:2";
public static final String MAM_LEGACY = "urn:xmpp:mam:0";