diff options
author | Christian Schneppe <christian@pix-art.de> | 2018-01-29 21:46:45 +0100 |
---|---|---|
committer | Christian Schneppe <christian@pix-art.de> | 2018-01-29 21:46:45 +0100 |
commit | be98b5bb3d5404d0dece95ba0158ffb6ef1640f0 (patch) | |
tree | 654be352319a4b51bd13fc8a01503aefec8ec099 /src/main/java | |
parent | 35025a1af20559a990ed6160875d3e98fb82e9cd (diff) |
support new http upload namespace
Diffstat (limited to 'src/main/java')
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"; |