Fix XEP-0363 HTTP File Upload elements

Smack still expected the URLs as element text and not as value of an
'url' attribute.

Fixes SMACK-790.
This commit is contained in:
Florian Schmaus 2017-12-09 14:35:35 +01:00
parent 36a278eeca
commit 0a0066c806
7 changed files with 88 additions and 21 deletions

View File

@ -470,6 +470,22 @@ public final class HttpFileUploadManager extends Manager {
} }
} }
public static UploadService.Version namespaceToVersion(String namespace) {
UploadService.Version version;
switch (namespace) {
case NAMESPACE:
version = Version.v0_3;
break;
case NAMESPACE_0_2:
version = Version.v0_2;
break;
default:
version = null;
break;
}
return version;
}
private static boolean containsHttpFileUploadNamespace(DiscoverInfo discoverInfo) { private static boolean containsHttpFileUploadNamespace(DiscoverInfo discoverInfo) {
return discoverInfo.containsFeature(NAMESPACE) || discoverInfo.containsFeature(NAMESPACE_0_2); return discoverInfo.containsFeature(NAMESPACE) || discoverInfo.containsFeature(NAMESPACE_0_2);
} }

View File

@ -22,7 +22,7 @@ import org.jxmpp.jid.DomainBareJid;
public class UploadService { public class UploadService {
enum Version { public enum Version {
/** /**
* Upload service as specified in XEP-0363 v0.2 or lower. * Upload service as specified in XEP-0363 v0.2 or lower.
* *

View File

@ -33,8 +33,9 @@ public class Slot extends IQ {
public static final String ELEMENT = "slot"; public static final String ELEMENT = "slot";
public static final String NAMESPACE = SlotRequest.NAMESPACE; public static final String NAMESPACE = SlotRequest.NAMESPACE;
private final URL putUrl; protected final URL putUrl;
private final URL getUrl; protected final URL getUrl;
private final Map<String, String> headers; private final Map<String, String> headers;
public Slot(URL putUrl, URL getUrl) { public Slot(URL putUrl, URL getUrl) {
@ -73,12 +74,21 @@ public class Slot extends IQ {
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.rightAngleBracket(); xml.rightAngleBracket();
xml.element("put", putUrl.toString()); xml.halfOpenElement("put").attribute("url", putUrl.toString());
xml.element("get", getUrl.toString()); if (headers.isEmpty()) {
for (Map.Entry<String, String> entry : getHeaders().entrySet()) { xml.closeEmptyElement();
xml.openElement("header").attribute(entry.getKey(), entry.getValue()); } else {
xml.rightAngleBracket();
for (Map.Entry<String, String> entry : getHeaders().entrySet()) {
xml.halfOpenElement("header").attribute("name", entry.getKey()).rightAngleBracket();
xml.escape(entry.getValue());
xml.closeElement("header");
}
xml.closeElement("put");
} }
xml.halfOpenElement("get").attribute("url", getUrl.toString()).closeEmptyElement();
return xml; return xml;
} }
} }

View File

@ -28,4 +28,13 @@ public class Slot_V0_2 extends Slot {
super(putUrl, getUrl, null, NAMESPACE); super(putUrl, getUrl, null, NAMESPACE);
} }
@Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.rightAngleBracket();
xml.element("put", putUrl.toString());
xml.element("get", getUrl.toString());
return xml;
}
} }

View File

@ -25,6 +25,8 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.httpfileupload.HttpFileUploadManager;
import org.jivesoftware.smackx.httpfileupload.UploadService;
import org.jivesoftware.smackx.httpfileupload.element.Slot; import org.jivesoftware.smackx.httpfileupload.element.Slot;
import org.jivesoftware.smackx.httpfileupload.element.Slot_V0_2; import org.jivesoftware.smackx.httpfileupload.element.Slot_V0_2;
@ -42,6 +44,10 @@ public class SlotProvider extends IQProvider<Slot> {
@Override @Override
public Slot parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException { public Slot parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException {
final String namespace = parser.getNamespace(); final String namespace = parser.getNamespace();
final UploadService.Version version = HttpFileUploadManager.namespaceToVersion(namespace);
assert version != null;
URL putUrl = null; URL putUrl = null;
URL getUrl = null; URL getUrl = null;
Map<String, String> headers = null; Map<String, String> headers = null;
@ -53,11 +59,34 @@ public class SlotProvider extends IQProvider<Slot> {
case XmlPullParser.START_TAG: case XmlPullParser.START_TAG:
String name = parser.getName(); String name = parser.getName();
switch (name) { switch (name) {
case "put": case "put": {
putUrl = new URL(parser.nextText()); String putUrlString;
switch (version) {
case v0_2:
putUrlString = parser.nextText();
break;
case v0_3:
putUrlString = parser.getAttributeValue(null, "url");
break;
default:
throw new AssertionError();
}
putUrl = new URL(putUrlString);
break; break;
}
case "get": case "get":
getUrl = new URL(parser.nextText()); String getUrlString;
switch (version) {
case v0_2:
getUrlString = parser.nextText();
break;
case v0_3:
getUrlString = parser.getAttributeValue(null, "url");
break;
default:
throw new AssertionError();
}
getUrl = new URL(getUrlString);
break; break;
case "header": case "header":
String headerName = ParserUtils.getRequiredAttribute(parser, "name"); String headerName = ParserUtils.getRequiredAttribute(parser, "name");
@ -77,13 +106,14 @@ public class SlotProvider extends IQProvider<Slot> {
} }
} }
switch (namespace) { switch (version) {
case Slot.NAMESPACE: case v0_3:
return new Slot(putUrl, getUrl, headers); return new Slot(putUrl, getUrl, headers);
case Slot_V0_2.NAMESPACE: case v0_2:
return new Slot_V0_2(putUrl, getUrl); return new Slot_V0_2(putUrl, getUrl);
default: default:
throw new AssertionError(); throw new AssertionError();
} }
} }
} }

View File

@ -16,23 +16,26 @@
*/ */
package org.jivesoftware.smackx.httpfileupload; package org.jivesoftware.smackx.httpfileupload;
import java.net.MalformedURLException; import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import java.io.IOException;
import java.net.URL; import java.net.URL;
import org.jivesoftware.smackx.httpfileupload.element.Slot; import org.jivesoftware.smackx.httpfileupload.element.Slot;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.xml.sax.SAXException;
public class SlotCreateTest { public class SlotCreateTest {
String testSlot String testSlot
= "<slot xmlns='urn:xmpp:http:upload:0'>" = "<slot xmlns='urn:xmpp:http:upload:0'>"
+ "<put>https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</put>" + "<put url='https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png'></put>"
+ "<get>https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</get>" + "<get url='https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png'></get>"
+ "</slot>"; + "</slot>";
@Test @Test
public void checkSlotRequestCreation() throws MalformedURLException { public void checkSlotRequestCreation() throws SAXException, IOException {
Slot slot = new Slot(new URL("https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png"), Slot slot = new Slot(new URL("https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png"),
new URL("https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png")); new URL("https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png"));
@ -41,6 +44,6 @@ public class SlotCreateTest {
Assert.assertEquals(new URL("https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png"), Assert.assertEquals(new URL("https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png"),
slot.getGetUrl()); slot.getGetUrl());
Assert.assertEquals(testSlot, slot.getChildElementXML().toString()); assertXMLEqual(testSlot, slot.getChildElementXML().toString());
} }
} }

View File

@ -26,7 +26,6 @@ import org.jivesoftware.smackx.httpfileupload.element.Slot;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class SlotProviderTest { public class SlotProviderTest {
/** /**
@ -39,8 +38,8 @@ public class SlotProviderTest {
+ "to='romeo@montague.tld/garden' " + "to='romeo@montague.tld/garden' "
+ "type='result'>" + "type='result'>"
+ "<slot xmlns='urn:xmpp:http:upload:0'>" + "<slot xmlns='urn:xmpp:http:upload:0'>"
+ "<put>https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</put>" + "<put url='https://upload.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png'></put>"
+ "<get>https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png</get>" + "<get url='https://download.montague.tld/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/my_juliet.png'></get>"
+ "</slot>" + "</slot>"
+ "</iq>"; + "</iq>";