diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index 28eb6c125..c4706ffe2 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -1634,6 +1634,9 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis ": " + DataHelper.escapeHTML(device.getFriendlyName()) + ""); System.out.println("
UDN: " + DataHelper.escapeHTML(device.getUDN()));
System.out.println("
IP: " + getIP(device));
+ String loc = device.getLocation();
+ if (loc != null && loc.length() > 0)
+ System.out.println("
URL: " + loc + "");
System.out.println(sb.toString());
sb.setLength(0);
}
diff --git a/router/java/src/org/cybergarage/upnp/ControlPoint.java b/router/java/src/org/cybergarage/upnp/ControlPoint.java
index 0d8b8b62c..00638a119 100644
--- a/router/java/src/org/cybergarage/upnp/ControlPoint.java
+++ b/router/java/src/org/cybergarage/upnp/ControlPoint.java
@@ -64,6 +64,7 @@ package org.cybergarage.upnp;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Locale;
import org.cybergarage.http.HTTPRequest;
import org.cybergarage.http.HTTPRequestListener;
@@ -253,6 +254,15 @@ public class ControlPoint implements HTTPRequestListener
String location = ssdpPacket.getLocation();
try {
URL locationUrl = new URL(location);
+ // I2P
+ // Roku fake json port, the real UPnP port is 8060
+ if (locationUrl.getPort() == 9080) {
+ String lcusn = usn.toLowerCase(Locale.US);
+ if (lcusn.contains("rku") || lcusn.contains("roku")) {
+ Debug.warning("Ignoring Roku at " + location);
+ return;
+ }
+ }
Parser parser = UPnP.getXMLParser();
Node rootNode = parser.parse(locationUrl);
Device rootDev = getDevice(rootNode);
@@ -270,12 +280,10 @@ public class ControlPoint implements HTTPRequestListener
performAddDeviceListener( rootDev );
}
catch (MalformedURLException me) {
- Debug.warning(ssdpPacket.toString());
- Debug.warning(me);
+ Debug.warning("Bad location: " + location, me);
}
catch (ParserException pe) {
- Debug.warning(ssdpPacket.toString());
- Debug.warning(pe);
+ Debug.warning("Error parsing data at location: " + location, pe);
}
}
diff --git a/router/java/src/org/cybergarage/xml/Parser.java b/router/java/src/org/cybergarage/xml/Parser.java
index 8ae1d0001..404b1ba99 100644
--- a/router/java/src/org/cybergarage/xml/Parser.java
+++ b/router/java/src/org/cybergarage/xml/Parser.java
@@ -21,6 +21,7 @@ package org.cybergarage.xml;
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.net.HttpURLConnection;
@@ -29,6 +30,7 @@ import java.net.URL;
import org.cybergarage.http.HTTP;
import org.cybergarage.http.HTTPRequest;
import org.cybergarage.http.HTTPResponse;
+import org.cybergarage.util.Debug;
public abstract class Parser
{
@@ -58,9 +60,15 @@ public abstract class Parser
if (port == -1)
port = 80;
String uri = locationURL.getPath();
+ // I2P note: Roku port 9080 now ignored in ControlPoint.addDevice()
+ // I2P fix - Roku
+ if (uri.length() <= 0)
+ uri = "/";
+ HttpURLConnection urlCon = null;
+ InputStream urlIn = null;
try {
- HttpURLConnection urlCon = (HttpURLConnection)locationURL.openConnection();
+ urlCon = (HttpURLConnection)locationURL.openConnection();
// I2P mods to prevent hangs (see HTTPRequest for more info)
// this seems to work, getInputStream actually does the connect(),
// (as shown by a thread dump)
@@ -73,29 +81,50 @@ public abstract class Parser
if (host != null)
urlCon.setRequestProperty(HTTP.HOST, host);
- InputStream urlIn = urlCon.getInputStream();
+ // I2P fix
+ int code = urlCon.getResponseCode();
+ if (code < 200 || code >= 300)
+ throw new ParserException("Bad response code " + code);
+ // I2P fix - Roku port 9080
+ // not valid json either; returns "status=ok"
+ if ("application/json".equals(urlCon.getContentType()))
+ throw new ParserException("JSON response");
+ urlIn = urlCon.getInputStream();
Node rootElem = parse(urlIn);
-
- urlIn.close();
- urlCon.disconnect();
return rootElem;
+ } catch (ParserException pe) {
+ throw pe;
} catch (Exception e) {
+ // Why try twice???
//throw new ParserException(e);
+ Debug.warning("Failed fetch but retrying with HTTPRequest, URL: " + locationURL, e);
+ } finally {
+ if (urlIn != null) try { urlIn.close(); } catch (IOException ioe) {}
+ if (urlCon != null) urlCon.disconnect();
}
HTTPRequest httpReq = new HTTPRequest();
httpReq.setMethod(HTTP.GET);
httpReq.setURI(uri);
HTTPResponse httpRes = httpReq.post(host, port);
- if (httpRes.isSuccessful() == false)
- throw new ParserException("HTTP comunication failed: no answer from peer." +
- "Unable to retrive resoure -> "+locationURL.toString());
+ if (!httpRes.isSuccessful())
+ throw new ParserException("HTTP comunication failed. " +
+ "Unable to retrieve resource -> " + locationURL +
+ "\nRequest:\n" + httpReq +
+ "\nResponse:\n" + httpRes);
String content = new String(httpRes.getContent());
ByteArrayInputStream strBuf = new ByteArrayInputStream(content.getBytes());
- return parse(strBuf);
+ try {
+ return parse(strBuf);
+ } catch (ParserException pe) {
+ Debug.warning("Parse error at resource " + locationURL +
+ "\nRequest:\n" + httpReq +
+ "\nResponse:\n" + httpRes, pe);
+ throw pe;
+ }
}
////////////////////////////////////////////////