本文将分享c#–Xamarin中的WebException,使用HttpClient的详细内容,并且还将对.netxamarin进行详尽解释,此外,我们还将为大家带来关于AndroidHttpClie
本文将分享c# – Xamarin中的WebException,使用HttpClient的详细内容,并且还将对.net xamarin进行详尽解释,此外,我们还将为大家带来关于Android HttpClient:NetworkOnMainThreadException、android – 使用loopj SyncHttpClient时的IOException、Apache HTTPClient SSLPeerUnverifiedException、Apache HttpClient临时错误:NoHttpResponseException的相关知识,希望对你有所帮助。
本文目录一览:- c# – Xamarin中的WebException,使用HttpClient(.net xamarin)
- Android HttpClient:NetworkOnMainThreadException
- android – 使用loopj SyncHttpClient时的IOException
- Apache HTTPClient SSLPeerUnverifiedException
- Apache HttpClient临时错误:NoHttpResponseException
c# – Xamarin中的WebException,使用HttpClient(.net xamarin)
System.Net.Http.HttpRequestException: An error occurred while sending the request ---> System.Net.WebException: Error: SecureChannelFailure (The authentication or decryption has Failed.) ---> System.IO.IOException: The authentication or decryption has Failed. ---> System.IO.IOException: The authentication or decryption has Failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has Failed.
我的代码如下;
public async Task<List<T>> GetList<T>(string url) { HttpClient client = new HttpClient(); var response = await client.GetAsync(new Uri(url)); response.EnsureSuccessstatusCode(); var content = await response.Content.ReadAsstringAsync(); return JsonConvert.DeserializeObject<List<T>>(content); }
android中的MainClass调用核心类,它调用此服务类.
当API不使用HTTPS时,HttpClient请求会起作用,但每当我使用启用了HTTPS的API时,都会抛出此错误.
我也使用可移植类库来存储代码,因此无法使用HttpWebRequest进行Web请求.
我也尝试过;
ServicePointManager.ServerCertificateValidationCallback += (o,certificate,chain,errors) => true;
和;
System.Security.Cryptography.AesCryptoServiceProvider b = new System.Security.Cryptography.AesCryptoServiceProvider();
在我的应用程序OnCreate类(android)中.
我还将HttpClient实现更改为AndroidClientHandler,同时将SSL / TLS实现更改为1.1.在模拟器和设备上尝试此操作.
有人有建议吗?
解决方法
打开Android项目属性 – > Android选项 – >高级
将HttpClient实现设置从Default切换到Android
似乎默认的Mono客户端处理程序因HTTPS而中断.
Android HttpClient:NetworkOnMainThreadException
我在下面有一些代码:
protected void testConnection(String url) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
ResponseHandler<String> responsehandler = new BasicResponseHandler();
try {
String connection = httpclient.execute(httpget, responsehandler);
Toast.makeText(getBaseContext(), R.string.connection_succeed, Toast.LENGTH_SHORT).show();
view_result.setText(connection);
} catch(IOException e) {
Toast.makeText(getBaseContext(), R.string.connection_Failed, Toast.LENGTH_SHORT).show();
}
httpclient.getConnectionManager().shutdown();
}
并在Menifest中添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
但它是一个例外:
networkonmainthreadException,
我能怎么做?
解决方法:
在ICS及更高版本上,您无法再在UI线程上执行网络操作.相反,你被迫创建一个新的线程并在那里做你的网络.
可能的工具是Android的AsyncTask和普通的Java Thread.
可以在这里找到一个很好的教程:Android Threads, Handlers and AsyncTask – Tutorial
android – 使用loopj SyncHttpClient时的IOException
我需要在几个区域使用loopj的SyncHttpClient.当我使用AsyncHttpClient时,请求成功返回.当我使用SyncHttpClient时,如此处接受的答案所示:How to use loopJ SyncHttpClient for synchronous calls?,我在onFailure中遇到了一个断点. statusCode为0,errorResponse为null,throwable为java.io.IOException:未处理的异常:null.
这是相关的代码.我再次使用Async时效果很好:
buttonTest.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// AsyncHttpClient httpClient = new AsyncHttpClient();
SyncHttpClient httpClient = new SyncHttpClient();
httpClient.get("http://10.0.1.6:3000/home/test_endpoint", new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
String stringResponse = response.toString();
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
String error = errorResponse.toString();
}
});
String temp = "got here";
}
});
我正在使用编译’com.loopj.android:android-async-http:1.4.9′
解决方法:
当我点击这个时我做了一些调试,我发现loopj正在吃以下异常:
android.os.networkonmainthreadException
我无法提供详细的堆栈跟踪,因为这个异常似乎没有正确记录(由于某些原因,logcat根本没有提取它)
但是,它位于这里:
AsyncHttpRequest.makeRequestWithRetries(AsyncHttpRequest.java:203)
我一直在运行我的代码:
Handler handler = new Handler();
Runnable r = new Runnable(){
public void run(){
SyncHttpClient client ....
client.get(.....); // hit error here
}
};
正如您所看到的,我碰巧在Handler.post()方法中运行我的SyncHttpClient,但显然实现不算作(非主线程上的网络)
修复它的关键是使用了mikeorr85的代码所包含的“新线程(…)”.像这样……
new Thread(Runnable r = new Runnable(){
public void run(){
SyncHttpClient client ....
client.get(.....); // hit error here
}
}).start();
Apache HTTPClient SSLPeerUnverifiedException
使用Apache HttpClient 4.2.1。使用从基于表单的登录示例复制的代码
http://hc.apache.org/httpcomponents-client-
ga/examples.html
访问受SSL保护的登录表单时出现异常:
Getting library items from https://appserver.gtportalbase.com/agileBase/AppController.servlet?return=blankjavax.net.ssl.SSLPeerUnverifiedException: peer not authenticatedClosing http connectionat sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640)at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
据我所知,该证书很好(请参阅堆栈跟踪之前的URL),并且不会过期-浏览器不会抱怨。
我尝试将证书导入到我的密钥库中
如何使用Apache
HttpClient处理无效的SSL证书?
没有变化。我相信您可以创建一个自定义SSLContext来强制Java忽略该错误,但是我宁愿解决根本原因,因为我不想打开任何安全漏洞。
有任何想法吗?
答案1
小编典典编辑 我知道这个答案很久以前就被接受了,并且也被投票了3次,但这是(至少部分是)错误的,所以这里有更多关于此异常的信息。不便之处敬请原谅。
javax.net.ssl.SSLPeerUnverifiedException:对等方未通过身份验证
当远程服务器根本不发送证书时, 通常会 抛出此异常。但是,由于在此版本sun.security.ssl.SSLSocketImpl.getSession()
中实现的方式以及实现的方式,因此在使用Apache HTTP
Client时会遇到一些极端情况。
当使用Apache HTTP Client时,当不信任远程证书时也会抛出该异常,这通常会抛出“sun.security.validator.ValidatorException: PKIX path building failed
”。
发生这种情况的原因是因为Apache HTTP Client SSLSession
在执行其他操作之前会尝试获取和对等证书。
提醒一下,有3种方法可以通过发起握手SSLSocket
:
- 调用开始显式开始握手的startHandshake,或
- 尝试在此套接字上读取或写入应用程序数据会导致隐式握手,或者
- 如果当前没有有效的会话,则对getSession的调用尝试建立会话,并且隐式握手已完成。
这是3个示例,所有示例均针对具有不可信证书的主机(使用javax.net.ssl.SSLSocketFactory
,而不是Apache)。
范例1:
SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443); sslSocket.startHandshake();
这将引发“ javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException: PKIX path building failed
”(如预期)。
范例2:
SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443); sslSocket.getInputStream().read();
这也会引发“ javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException: PKIX path building failed
”(如预期)。
范例3:
SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443); SSLSession sslSession = sslSocket.getSession(); sslSession.getPeerCertificates();
但是,这引发了javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
。
这是Apache
HTTP客户端AbstractVerifier
org.apache.http.conn.ssl.SSLSocketFactory
在4.2.1版中使用的逻辑。更高版本基于发出的HTTPCLIENT-1346报告显式调用startHandshake()
。
最终,这似乎来自的实现sun.security.ssl.SSLSocketImpl.getSession()
,该实现捕获了IOException
在调用startHandshake(false)
(内部方法)时抛出的潜在s
,而没有进一步抛出它。这可能是一个错误,尽管这不会对安全产生重大影响,因为SSLSocket
无论如何仍将关闭。
范例4:
SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory(); SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443); SSLSession sslSession = sslSocket.getSession(); // sslSession.getPeerCertificates(); sslSocket.getInputStream().read();
值得庆幸的是,javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException: PKIX path buildingfailed
每当您实际尝试使用它时,它仍然会抛出“ ” SSLSocket
(在没有获得对等证书的情况下获得会话不会造成漏洞)。
如何解决这个问题
像其他任何不信任的证书问题一样,确保您使用的信任库包含必要的信任锚(例如,颁发要尝试验证的链的CA证书,或者可能是实际服务器)特殊情况证书)。
要解决此问题,您应该将CA证书(或者可能是服务器证书本身)导入到信任库中。你可以这样做:
- 在您的JRE信任库中,通常是
cacerts
文件(不一定是最好的文件,因为这会影响使用该JRE的所有应用程序), - 在您的信任库的本地副本中(您可以使用
-Djavax.net.ssl.trustStore=...
选项进行配置), - 通过
SSLContext
为该连接创建一个特定对象。(有人建议使用不执行任何操作的信任管理器,但这会使您的连接容易受到MITM攻击。)
初步答案
javax.net.ssl.SSLPeerUnverifiedException:对等方未通过身份验证
这与信任证书无关,或者您必须创建一个自定义SSLContext
:这是由于服务器根本不发送任何证书。
显然,该服务器未配置为正确支持TLS。这将失败(您将不会获得远程证书):
openssl s_client -tls1 -showcerts -connect
appserver.gtportalbase.com:443
但是,SSLv3似乎可以工作:
openssl s_client -ssl3 -showcerts -connect
appserver.gtportalbase.com:443
如果您知道谁在运行此服务器,则值得与他们联系以解决此问题。至少现在,服务器应该真正支持TLSv1。
同时,解决此问题的一种方法是创建您自己的问题并将org.apache.http.conn.ssl.SSLSocketFactory
其用于与Apache
Http客户端的此连接。
该工厂需要创建一个SSLSocket
照常使用的方法sslSocket.setEnabledProtocols(new String[]{"SSLv3"});
,以在返回该套接字之前使用它来禁用TLS,否则默认情况下将启用它。
Apache HttpClient临时错误:NoHttpResponseException
我有一个Web服务正在接受XML的POST方法。它工作正常,然后在某个随机的时刻,它无法与服务器通信,并抛出message,并抛出IOExceptionThe target server failed to respond
。后续调用工作正常。
当我打了一些电话然后将应用程序闲置大约10-15分钟时,它就会发生。在此之后我进行的第一个调用将返回此错误。
我尝试了几件事…
我像这样设置重试处理程序
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() { public boolean retryRequest(IOException e, int retryCount, HttpContext httpCtx) { if (retryCount >= 3){ Logger.warn(CALLER, "Maximum tries reached, exception would be thrown to outer block"); return false; } if (e instanceof org.apache.http.NoHttpResponseException){ Logger.warn(CALLER, "No response from server on "+retryCount+" call"); return true; } return false; } }; httpPost.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler);
但是此重试从未被调用过。(是的,我正在使用正确的instanceof子句)。在调试时,此类永远不会被调用。
我什至尝试设置HttpProtocolParams.setUseExpectContinue(httpClient.getParams(),false);
但没有用。有人可以建议我现在可以做什么吗?
重要事项 除了弄清楚为什么我会得到例外,我还有一个重要的担忧是为什么重试处理程序不在这里工作?
答案1
小编典典由连接管理器保持活动状态的最有可能的持久连接变得陈旧。也就是说,目标服务器会在其连接空闲时关闭其末端的连接,而HttpClient无法对该事件做出反应,从而使连接半关闭或“陈旧”。通常这不是问题。HttpClient使用多种技术来验证从池中租借时的连接有效性。即使禁用了过时的连接检查并且使用了过时的连接来传输请求消息,请求执行通常也会在具有SocketException的写操作中失败,并会自动重试。但是,在某些情况下,写操作可以毫无例外地终止,随后的读操作将返回-1(流的结尾)。
解决此问题的最简单方法是将过期的连接和闲置了超过一段时间(例如,在池中闲置一分钟之后)之后空闲的连接驱逐出去。有关详细信息,请参见HttpClient教程的本节。
今天关于c# – Xamarin中的WebException,使用HttpClient和.net xamarin的介绍到此结束,谢谢您的阅读,有关Android HttpClient:NetworkOnMainThreadException、android – 使用loopj SyncHttpClient时的IOException、Apache HTTPClient SSLPeerUnverifiedException、Apache HttpClient临时错误:NoHttpResponseException等更多相关知识的信息可以在本站进行查询。
本文标签: