forked from I2P_Developers/i2p.i2p
UPnP fixes part 6:
Fix malformed HTTP requests Check HTTP response code in Parser Check content type in Parser Debug log in Parser Show device URL in CLI Don't retry after parser exception Close resources in finally block
This commit is contained in:
@ -1634,6 +1634,9 @@ public class UPnP extends ControlPoint implements DeviceChangeListener, EventLis
|
||||
": " + DataHelper.escapeHTML(device.getFriendlyName()) + "</h3>");
|
||||
System.out.println("<p>UDN: " + DataHelper.escapeHTML(device.getUDN()));
|
||||
System.out.println("<br>IP: " + getIP(device));
|
||||
String loc = device.getLocation();
|
||||
if (loc != null && loc.length() > 0)
|
||||
System.out.println("<br>URL: <a href=\"" + loc + "\">" + loc + "</a>");
|
||||
System.out.println(sb.toString());
|
||||
sb.setLength(0);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
Reference in New Issue
Block a user