我有一些代码可以下载一个 XML 文件,该文件已经在付费应用程序中发布了几年 - 从来没有遇到过任何问题,直到最近我在 HTC One 上看到了这种情况。
想知道我是否遗漏了什么或者是否应该在某处报告。
这是强制出现问题的示例代码:
package com.lutron.davetest;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.Menu;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView mainCenterText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainCenterText = (TextView) findViewById(R.id.mainCenterText);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Enter the IP address");
final EditText edit = new EditText(this);
builder.setView(edit);
builder.setPositiveButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mainCenterText.setText("");
String ip = edit.getText().toString();
new DownloadTask().execute(ip);
}
});
builder.create().show();
}
private class DownloadTask extends AsyncTask<String, Void, Void>{
@Override
protected Void doInBackground(String... params) {
try{
URL url = new URL("http", params[0], 80, "/file.xml");
URLConnection connection = url.openConnection();
InputStream in = new BufferedInputStream(connection.getInputStream());
byte buf[] = new byte[4096];
int len;
while((len = in.read(buf)) != -1 ) {
final String data = new String(buf, 0, len);
runOnUiThread(new Runnable() {
@Override
public void run() {
mainCenterText.append(data);
}
});
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
发生的情况是,在所有其他设备上从流中读取时,您只能获得文件内容。
在 HTC One 上你会得到这个,然后是文件内容:
onnection: close
Last-Modified: ???
Content-Type: text/html
这是 Android 4.1.2。
有什么方法可以配置 URLConnection 来避免这种情况吗?
最佳答案
哇。
深入研究这个问题,我们意识到这只发生在特定页面上,并验证了当这部手机在其浏览器中导航到它们提供的任何页面时,这些 HTTP header 仍然出现在正文中,从而导致错误。
我今天用 wireshark 连接了一个小的 HTTP session ,发现这些 header 被认为是正文的一部分!
HTTP层的所有换行都是\n\r,或者LF CR。
来自 HTTP 1.1 RFC 2616:http://www.ietf.org/rfc/rfc2616.txt
HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
protocol elements except the entity-body (see appendix 19.3 for
tolerant applications). The end-of-line marker within an entity-body
is defined by its associated media type, as described in section 3.7.
CRLF = CR LF
...
[…] a bare CR
or LF MUST NOT be substituted for CRLF within any of the HTTP control
structures (such as header fields and multipart boundaries).
...
6 Response
After receiving and interpreting a request message, a server responds
with an HTTP response message.
Response = Status-Line ; Section 6.1
*(( general-header ; Section 4.5
| response-header ; Section 6.2
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 7.2
这似乎是一个大问题 - 然而,应用程序可以持续到现在的唯一方法出现了应用程序应该容忍单个 LF 的建议 (19.3)。
所以我猜 HTC 在 HTC One 上忽略了这个建议!! :-P
为了解决这个问题,我尝试使用 HttpClient(Android SDK 中包含的版本),但也有同样的问题。我想尝试使用来自 Apache HTTP Components 的 jar 文件,但当然那些包名与 Android 框架中的版本有冲突,所以我用 Jar Jar Links 重新打包了它们。一旦进口被它取代,它就起作用了!
关于android - HTC One 漏洞?出现在 URLConnection InputStream 中的部分 HTTP header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16905782/