reintroduce support for old http upload

This commit is contained in:
Daniel Gultsch 2018-05-26 21:43:50 +02:00
parent bc50239c2a
commit 1854e37e7a
5 changed files with 74 additions and 24 deletions

View file

@ -351,6 +351,16 @@ public class IqGenerator extends AbstractGenerator {
return packet; return packet;
} }
public IqPacket requestHttpUploadLegacySlot(Jid host, DownloadableFile file, String mime) {
IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
packet.setTo(host);
Element request = packet.addChild("request", Namespace.HTTP_UPLOAD_LEGACY);
request.addChild("filename").setContent(convertFilename(file.getName()));
request.addChild("size").setContent(String.valueOf(file.getExpectedSize()));
request.addChild("content-type").setContent(mime);
return packet;
}
public IqPacket requestP1S3Slot(Jid host, String md5) { public IqPacket requestP1S3Slot(Jid host, String md5) {
IqPacket packet = new IqPacket(IqPacket.TYPE.SET); IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
packet.setTo(host); packet.setTo(host);

View file

@ -33,14 +33,16 @@ import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.XmppConnection;
public enum Method { public enum Method {
P1_S3, HTTP_UPLOAD; P1_S3, HTTP_UPLOAD, HTTP_UPLOAD_LEGACY;
public static Method determine(Account account) { public static Method determine(Account account) {
XmppConnection.Features features = account.getXmppConnection() == null ? null : account.getXmppConnection().getFeatures(); XmppConnection.Features features = account.getXmppConnection() == null ? null : account.getXmppConnection().getFeatures();
if (features == null) { if (features == null) {
return HTTP_UPLOAD; return HTTP_UPLOAD;
} }
if (features.httpUpload(0)) { if (features.useLegacyHttpUpload()) {
return HTTP_UPLOAD_LEGACY;
} else if (features.httpUpload(0)) {
return HTTP_UPLOAD; return HTTP_UPLOAD;
} else if (features.p1S3FileTransfer()) { } else if (features.p1S3FileTransfer()) {
return P1_S3; return P1_S3;

View file

@ -58,11 +58,42 @@ public class SlotRequester {
if (method == Method.HTTP_UPLOAD) { if (method == Method.HTTP_UPLOAD) {
Jid host = account.getXmppConnection().findDiscoItemByFeature(Namespace.HTTP_UPLOAD); Jid host = account.getXmppConnection().findDiscoItemByFeature(Namespace.HTTP_UPLOAD);
requestHttpUpload(account, host, file, mime, callback); requestHttpUpload(account, host, file, mime, callback);
} else if (method == Method.HTTP_UPLOAD_LEGACY) {
Jid host = account.getXmppConnection().findDiscoItemByFeature(Namespace.HTTP_UPLOAD_LEGACY);
requestHttpUploadLegacy(account, host, file, mime, callback);
} else { } else {
requestP1S3(account, Jid.of(account.getServer()), file.getName(), md5, callback); requestP1S3(account, Jid.of(account.getServer()), file.getName(), md5, callback);
} }
} }
private void requestHttpUploadLegacy(Account account, Jid host, DownloadableFile file, String mime, OnSlotRequested callback) {
IqPacket request = service.getIqGenerator().requestHttpUploadLegacySlot(host, file, mime);
service.sendIqPacket(account, request, (a, packet) -> {
if (packet.getType() == IqPacket.TYPE.RESULT) {
Element slotElement = packet.findChild("slot", Namespace.HTTP_UPLOAD_LEGACY);
if (slotElement != null) {
try {
final String putUrl = slotElement.findChildContent("put");
final String getUrl = slotElement.findChildContent("get");
if (getUrl != null && putUrl != null) {
Slot slot = new Slot(new URL(putUrl));
slot.getUrl = new URL(getUrl);
slot.headers = new HashMap<>();
slot.headers.put("Content-Type", mime == null ? "application/octet-stream" : mime);
callback.success(slot);
return;
}
} catch (MalformedURLException e) {
//fall through
}
}
}
Log.d(Config.LOGTAG, account.getJid().toString() + ": invalid response to slot request " + packet);
callback.failure(IqParser.extractErrorMessage(packet));
});
}
private void requestHttpUpload(Account account, Jid host, DownloadableFile file, String mime, OnSlotRequested callback) { private void requestHttpUpload(Account account, Jid host, DownloadableFile file, String mime, OnSlotRequested callback) {
IqPacket request = service.getIqGenerator().requestHttpUploadSlot(host, file, mime); IqPacket request = service.getIqGenerator().requestHttpUploadSlot(host, file, mime);
service.sendIqPacket(account, request, (a, packet) -> { service.sendIqPacket(account, request, (a, packet) -> {
@ -85,9 +116,9 @@ public class SlotRequester {
if (HttpUploadConnection.WHITE_LISTED_HEADERS.contains(name) && value != null && !value.trim().contains("\n")) { if (HttpUploadConnection.WHITE_LISTED_HEADERS.contains(name) && value != null && !value.trim().contains("\n")) {
slot.headers.put(name, value.trim()); slot.headers.put(name, value.trim());
} }
slot.headers.put("Content-Type", mime == null ? "application/octet-stream" : mime);
} }
} }
slot.headers.put("Content-Type", mime == null ? "application/octet-stream" : mime);
callback.success(slot); callback.success(slot);
return; return;
} }

View file

@ -6,6 +6,7 @@ public final class Namespace {
public static final String REGISTER = "jabber:iq:register"; public static final String REGISTER = "jabber:iq:register";
public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams";
public static final String HTTP_UPLOAD = "urn:xmpp:http:upload:0"; public static final String HTTP_UPLOAD = "urn:xmpp:http:upload:0";
public static final String HTTP_UPLOAD_LEGACY = "urn:xmpp:http:upload";
public static final String STANZA_IDS = "urn:xmpp:sid: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 = "urn:xmpp:mam:2";
public static final String MAM_LEGACY = "urn:xmpp:mam:0"; public static final String MAM_LEGACY = "urn:xmpp:mam:0";

View file

@ -1815,36 +1815,42 @@ public class XmppConnection implements Runnable {
if (Config.DISABLE_HTTP_UPLOAD) { if (Config.DISABLE_HTTP_UPLOAD) {
return false; return false;
} else { } else {
List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(Namespace.HTTP_UPLOAD); for(String namespace : new String[]{Namespace.HTTP_UPLOAD, Namespace.HTTP_UPLOAD_LEGACY}) {
if (items.size() > 0) { List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(namespace);
try { if (items.size() > 0) {
long maxsize = Long.parseLong(items.get(0).getValue().getExtendedDiscoInformation(Namespace.HTTP_UPLOAD, "max-file-size")); try {
if (filesize <= maxsize) { long maxsize = Long.parseLong(items.get(0).getValue().getExtendedDiscoInformation(namespace, "max-file-size"));
return true; if (filesize <= maxsize) {
} else { return true;
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": http upload is not available for files with size " + filesize + " (max is " + maxsize + ")"); } else {
return false; Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": http upload is not available for files with size " + filesize + " (max is " + maxsize + ")");
return false;
}
} catch (Exception e) {
//ignored
} }
} catch (Exception e) {
return true;
} }
} else {
return false;
} }
return false;
} }
} }
public boolean useLegacyHttpUpload() {
return findDiscoItemByFeature(Namespace.HTTP_UPLOAD) == null && findDiscoItemByFeature(Namespace.HTTP_UPLOAD_LEGACY) != null;
}
public long getMaxHttpUploadSize() { public long getMaxHttpUploadSize() {
List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(Namespace.HTTP_UPLOAD); for(String namespace : new String[]{Namespace.HTTP_UPLOAD, Namespace.HTTP_UPLOAD_LEGACY}) {
if (items.size() > 0) { List<Entry<Jid, ServiceDiscoveryResult>> items = findDiscoItemsByFeature(namespace);
try { if (items.size() > 0) {
return Long.parseLong(items.get(0).getValue().getExtendedDiscoInformation(Namespace.HTTP_UPLOAD, "max-file-size")); try {
} catch (Exception e) { return Long.parseLong(items.get(0).getValue().getExtendedDiscoInformation(namespace, "max-file-size"));
return -1; } catch (Exception e) {
//ignored
}
} }
} else {
return -1;
} }
return -1;
} }
public boolean stanzaIds() { public boolean stanzaIds() {