Https连接Android
我有一个应用程序连接到使用有效证书的web服务。唯一的区别是它是一个通配符SSL 问题是:我有一个Https连接Android,android,https,Android,Https,我有一个应用程序连接到使用有效证书的web服务。唯一的区别是它是一个通配符SSL 问题是:我有一个 ERROR/NoHttpResponseException(5195): org.apache.http.NoHttpResponseException: The target server failed to respond 当我使用3G时。当在WIFI上工作时,在模拟器上工作时,通过我的手机将模拟器拴在3G上工作。但我手机上的3G应用根本不起作用。在HTC Legend CM7.0.3(2.
ERROR/NoHttpResponseException(5195): org.apache.http.NoHttpResponseException: The target server failed to respond
当我使用3G时。当在WIFI上工作时,在模拟器上工作时,通过我的手机将模拟器拴在3G上工作。但我手机上的3G应用根本不起作用。在HTC Legend CM7.0.3(2.3.3)和Nexus S 2.3.3两个不同网络(维珍移动加拿大和Fido)上进行测试
我的设备有一个PCAP转储,显示了一些错误,但我不太了解它
确认号:TCP断开。未设置ACK标志时,确认字段为非零
我也试过修复这个。我不知道还能去哪里
顺便说一下,web服务与3G上的浏览器配合使用
我们还将basic auth与HttpRequestInterceptor一起使用
我想这就是我能提供的全部细节。如果还需要别的什么,尽管问吧
这也是相关的,我已经尝试了两种修复方法,它们都不起作用
编辑
我开始认为这可能更适合serverfault.com
这是转储和屏幕截图
编辑2
这是我用来连接到所讨论的web服务的代码
protected HttpEntity sendData(List<NameValuePair> pairs, String method)
throws ClientProtocolException, IOException,
AuthenticationException {
pairs.add(new BasicNameValuePair(KEY_SECURITY, KEY));
pairs.add(new BasicNameValuePair(LANG_KEY, lang));
pairs.add(new BasicNameValuePair(OS_KEY, OS));
pairs.add(new BasicNameValuePair(MODEL_KEY, model));
pairs.add(new BasicNameValuePair(CARRIER_KEY, carrier));
DefaultHttpClient client = getClient();
HttpPost post = new HttpPost();
try {
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
post.setEntity(new UrlEncodedFormEntity(pairs));
} catch (UnsupportedEncodingException e1) {
Log.e("UnsupportedEncodingException", e1.toString());
}
URI uri = URI.create(method);
post.setURI(uri);
client.addRequestInterceptor(preemptiveAuth, 0);
HttpHost target = new HttpHost(host, port, protocol);
HttpContext httpContext = new BasicHttpContext();
HttpResponse response = client.execute(target, post, httpContext);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 401) {
throw new AuthenticationException("Invalid username or password");
}
return response.getEntity();
}
受保护的HttpEntity sendData(列表对、字符串方法)
抛出ClientProtocolException、IOException、,
身份验证异常{
添加(新的BasicNameValuePair(KEY_SECURITY,KEY));
添加(新的BasicNameValuePair(LANG_KEY,LANG));
添加(新的BasicNameValuePair(OS_键,OS));
添加(新的BasicNameValuePair(MODEL_KEY,MODEL));
添加(新的BasicNameValuePair(CARRIER_键,CARRIER));
DefaultHttpClient=getClient();
HttpPost=新的HttpPost();
试一试{
post.setHeader(“内容类型”、“应用程序/x-www-form-urlencoded”);
setEntity(新的UrlEncodedFormEntity(对));
}捕获(不支持DencodingException e1){
Log.e(“UnsupportedEncodingException”,e1.toString());
}
URI=URI.create(方法);
post.setURI(uri);
addRequestInterceptor(preemptiveAuth,0);
HttpHost目标=新的HttpHost(主机、端口、协议);
HttpContext HttpContext=新的BasicHttpContext();
HttpResponse response=client.execute(target、post、httpContext);
int statusCode=response.getStatusLine().getStatusCode();
如果(状态代码==401){
抛出新的AuthenticationException(“无效用户名或密码”);
}
返回response.getEntity();
}
您是否尝试过中提到的解决方案
抄写
我终于解决了这个问题:只是一个HTTP头,在路上被squid服务器处理得很糟糕: 预期:100人继续 android SDK上的DefaultHttpClient似乎默认存在。要解决此问题,只需在代码中添加:
HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false);
ArrayList nameValuePairs=新的ArrayList();
nameValuePairs.add(新的基本nameValuePairs(“年份”,“1980”));
//http post
试一试{
HttpClient HttpClient=新的DefaultHttpClient();
HttpPost HttpPost=新的HttpPost(“http://example.com/getAllPeopleBornAfter.php");
setEntity(新的UrlEncodedFormEntity(nameValuePairs));
HttpResponse response=httpclient.execute(httppost);
HttpEntity=response.getEntity();
InputStream=entity.getContent();
}捕获(例外e){
e(“Log_标记”,“http连接错误”+e.toString());
}
//将响应转换为字符串
试一试{
BufferedReader reader=新的BufferedReader(新的InputStreamReader(is,“iso-8859-1”),8;
StringBuilder sb=新的StringBuilder();
字符串行=null;
而((line=reader.readLine())!=null){
sb.附加(第+行“n”);
}
is.close();
结果=sb.toString();
}捕获(例外e){
Log.e(“Log_标记”,“错误转换结果”+e.toString());
}
请参阅http连接的此代码我们终于找到了问题。这与代码无关 正是反向DNS超时。因为我没有收到来自反向DNS的任何答复,我的apache/ssl会话被提前关闭 通过在根设备上使用谷歌的DNS,它工作了 现在唯一要做的就是修复我们的反向DNS 以下是一个解决方法: 在DefaultHttpClient或AndroidHttpClient实例上调用此方法。它将阻止进行反向DNS查找
private void workAroundReverseDnsBugInHoneycombAndEarlier(HttpClient client) {
// Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice Cream Sandwich)
// http://code.google.com/p/android/issues/detail?id=13117
SocketFactory socketFactory = new LayeredSocketFactory() {
SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory();
@Override public Socket createSocket() throws IOException {
return delegate.createSocket();
}
@Override public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params) throws IOException {
return delegate.connectSocket(sock, host, port, localAddress, localPort, params);
}
@Override public boolean isSecure(Socket sock) throws IllegalArgumentException {
return delegate.isSecure(sock);
}
@Override public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException {
injectHostname(socket, host);
return delegate.createSocket(socket, host, port, autoClose);
}
private void injectHostname(Socket socket, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(socket.getInetAddress(), host);
} catch (Exception ignored) {
}
}
};
client.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", socketFactory, 443));
}
我在我的问题中发布了3个答案,它们都不起作用,其中之一就是这个。这个解决方案对我不起作用。哦,我一定打开了其他链接,我的朋友。你能添加一些相关代码吗?也许会有帮助。@Nicklas A,添加了一些代码。如果需要一些特定的东西,只需提问。这是非常无用的,因为httpclient.execute()上的代码崩溃。看看我的代码,我设置了它,不管怎样,看看我的答案,它解决了我的问题。它是否影响nio连接?@Kai,不知道,从未用它测试过。
private void workAroundReverseDnsBugInHoneycombAndEarlier(HttpClient client) {
// Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice Cream Sandwich)
// http://code.google.com/p/android/issues/detail?id=13117
SocketFactory socketFactory = new LayeredSocketFactory() {
SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory();
@Override public Socket createSocket() throws IOException {
return delegate.createSocket();
}
@Override public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params) throws IOException {
return delegate.connectSocket(sock, host, port, localAddress, localPort, params);
}
@Override public boolean isSecure(Socket sock) throws IllegalArgumentException {
return delegate.isSecure(sock);
}
@Override public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException {
injectHostname(socket, host);
return delegate.createSocket(socket, host, port, autoClose);
}
private void injectHostname(Socket socket, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(socket.getInetAddress(), host);
} catch (Exception ignored) {
}
}
};
client.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", socketFactory, 443));
}