如何测试 Android HttpURLConnection 是否有效?
How to test if Android HttpURLConnection is valid?
我的应用使用 HttpUrlConnection()
定期从服务器下载文件。下面是简短的代码示例:
HttpURLConnection conn;
url = new URL( "http://google.com/index.html" );
conn = url.openConnection(); // returns non-null
int rcode = conn.getResponseCode(): // returns 200
// get input stream, read from it and process bytes read
这很好用。但是,如果我替换为伪造的 URL,例如
url=new URL("http://BOGUS-SITE.com/index.html";
它仍然连接正常,getResponseCode() returns 响应代码 200。输入流 reader returns -1 字节读取。好的,就这样吧。 (有趣的是,如果 URL 的文件名部分是假的,我 do 会得到一个 File-Not-Found 异常。
但是,在我实际尝试读取它之前,如何检测到连接不良(例如,到不存在的主机)?也许那是不可能的?
我想我可以解析 URL 并尝试解析站点名称或对其执行 ping 操作,但这似乎是一个 hack。
更完整的代码摘录:
// Download a file by its URL
public static int
doDownload(
String fileurl) // file url, e.g. "http:google.com/index.html"
{
// NOTE: 'log()' is a wrapper for 'Log.i()'
int BUFSIZE=10000;
HttpURLConnection hconn;
int rcode,nr,nrtot=0;
InputStream is;
BufferedInputStream bis;
byte[] buf;
URL url;
try {
url = new URL( fileurl ); // form URL
hconn = (HttpURLConnection)url.openConnection(); // open connection
log( "Opened connection to \""+fileurl+"\"" );
rcode = hconn.getResponseCode(); // get response code
log("Read HTTP response code: " + rcode);
is = hconn.getInputStream();
bis = new BufferedInputStream( is ); // get buffered stream to read
buf = new byte[BUFSIZE];
while( true ) { // read loop
nr = bis.read( buf, 0, BUFSIZE ); // read some bytes
if( nr <= 0 ) break; // break read loop on EOF
nrtot += nr; // update total read count
}
}
catch( Exception e ) {
return( -1 ); // rtn ERROR
}
return( nrtot ); // return num bytes read
}
更新
我做了一些进一步的调查。我发现为什么有时会返回响应代码 200 而有时会发生 UnknownHostException:这取决于指定的特定“坏”url 主机。例如,如果我指定
- “http://google.com/index.html”,返回200码,下载成功
- 如果我指定“”http://google.comXXX/index.html”,仍然返回 200,但下载失败(没有读取字节)。在这种情况下,报告了一个不同的 IP 地址,nslookup 报告该地址属于“akamaitechnologies.com”(???).
- 在其他情况下,发生 UnknownHostException。
我现在正在尝试其他“坏”URLs 来尝试查看模式。
我发现了问题,这是一个 DNS 问题。我发现我的 AT&T phone 正在使用“sbcglobal.net”(AT&T 的默认 DNS 服务器)的 DNS 服务。该 DNS 服务器 returns 一个 IP 地址,即使是 不存在的 名称。特别是,它 returns 属于“akamaitechnologies.com”(无论是什么)的地址。由于 是一个现有站点 ,http 连接并且 getResponseCode returns 200。由于它无法提供我请求的文件,因此下载失败。我认为这是为 akamaitechnologies 产生流量的营销噱头。
当我将 phone 设置为使用“dns.google”(8.8.8.8) 的 DNS 时,一切正常。
这种类型的 DNS 欺骗是一件坏事,因为许多应用依赖于未知主机异常来检测输入不正确的域名,例如在电子邮件地址中。
我的应用使用 HttpUrlConnection()
定期从服务器下载文件。下面是简短的代码示例:
HttpURLConnection conn;
url = new URL( "http://google.com/index.html" );
conn = url.openConnection(); // returns non-null
int rcode = conn.getResponseCode(): // returns 200
// get input stream, read from it and process bytes read
这很好用。但是,如果我替换为伪造的 URL,例如
url=new URL("http://BOGUS-SITE.com/index.html";
它仍然连接正常,getResponseCode() returns 响应代码 200。输入流 reader returns -1 字节读取。好的,就这样吧。 (有趣的是,如果 URL 的文件名部分是假的,我 do 会得到一个 File-Not-Found 异常。
但是,在我实际尝试读取它之前,如何检测到连接不良(例如,到不存在的主机)?也许那是不可能的?
我想我可以解析 URL 并尝试解析站点名称或对其执行 ping 操作,但这似乎是一个 hack。
更完整的代码摘录:
// Download a file by its URL
public static int
doDownload(
String fileurl) // file url, e.g. "http:google.com/index.html"
{
// NOTE: 'log()' is a wrapper for 'Log.i()'
int BUFSIZE=10000;
HttpURLConnection hconn;
int rcode,nr,nrtot=0;
InputStream is;
BufferedInputStream bis;
byte[] buf;
URL url;
try {
url = new URL( fileurl ); // form URL
hconn = (HttpURLConnection)url.openConnection(); // open connection
log( "Opened connection to \""+fileurl+"\"" );
rcode = hconn.getResponseCode(); // get response code
log("Read HTTP response code: " + rcode);
is = hconn.getInputStream();
bis = new BufferedInputStream( is ); // get buffered stream to read
buf = new byte[BUFSIZE];
while( true ) { // read loop
nr = bis.read( buf, 0, BUFSIZE ); // read some bytes
if( nr <= 0 ) break; // break read loop on EOF
nrtot += nr; // update total read count
}
}
catch( Exception e ) {
return( -1 ); // rtn ERROR
}
return( nrtot ); // return num bytes read
}
更新
我做了一些进一步的调查。我发现为什么有时会返回响应代码 200 而有时会发生 UnknownHostException:这取决于指定的特定“坏”url 主机。例如,如果我指定
- “http://google.com/index.html”,返回200码,下载成功
- 如果我指定“”http://google.comXXX/index.html”,仍然返回 200,但下载失败(没有读取字节)。在这种情况下,报告了一个不同的 IP 地址,nslookup 报告该地址属于“akamaitechnologies.com”(???).
- 在其他情况下,发生 UnknownHostException。
我现在正在尝试其他“坏”URLs 来尝试查看模式。
我发现了问题,这是一个 DNS 问题。我发现我的 AT&T phone 正在使用“sbcglobal.net”(AT&T 的默认 DNS 服务器)的 DNS 服务。该 DNS 服务器 returns 一个 IP 地址,即使是 不存在的 名称。特别是,它 returns 属于“akamaitechnologies.com”(无论是什么)的地址。由于 是一个现有站点 ,http 连接并且 getResponseCode returns 200。由于它无法提供我请求的文件,因此下载失败。我认为这是为 akamaitechnologies 产生流量的营销噱头。
当我将 phone 设置为使用“dns.google”(8.8.8.8) 的 DNS 时,一切正常。
这种类型的 DNS 欺骗是一件坏事,因为许多应用依赖于未知主机异常来检测输入不正确的域名,例如在电子邮件地址中。