使用 okHttp 握手失败但使用 HttpURLConnection 工作
Handshake Failed using using okHttp but working using HttpURLConnection
我正在尝试向服务器发送 get 请求(发送 get 请求进行测试,实际上我需要向同一台服务器发送 post 请求。如果 get 有效,post 将有效)
link 到服务器是
https://bits-bosm.org/2017/registrations/signup/
问题是当我使用 okHttp 发送请求时,我收到一个失败响应,提示握手失败。
这是我使用 okHttp(在 kotlin 中)发送请求的代码
val request = Request.Builder()
.url("https://bits-bosm.org/2017/registrations/signup/")
.build()
okHttpClient.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
val mMessage = e?.message?.toString()
Log.w("failure Response", mMessage)
}
override fun onResponse(call: Call?, response: Response?) {
val mMessage = response?.body()?.string()
Log.e("Message", mMessage)
}
})
但是如果我使用 HttpUrlConnection 将 get 请求发送到同一台服务器,我会收到响应。
这是相同的代码 (java)
private static final String USER_AGENT = "Mozilla/5.0";
private static final String GET_URL = "https://bits-bosm.org/2017/registrations/signup/";
static void sendGET() throws IOException {
URL obj = new URL(GET_URL);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println("GET Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
Log.e("Result", response.toString());
} else {
System.out.println("GET request not worked");
}
}
根据我在互联网上搜索的内容和我可以推断的内容,问题是该站点是使用自证书签名的,而 okHttp 不允许它们。我什至尝试使用我在 Internet 上找到的不检查证书(Custom SSLSocketFactory)和其他一些解决方案的代码片段,但其中 none 有效。另外,我现在不关心安全性,我只想让它发挥作用。但是我无法访问后端,也无法 change/remove ssl 安全。
如何才能让它发挥作用?有什么我想念的吗?
这是广泛用作解决方法的不安全的 OkHttpClient。
请勿在生产中使用它,它仅用于开发目的。
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
public class Http {
private final static String SSL = "SSL";
private static OkHttpClient InsecureHttpClient;
public static OkHttpClient client () {
if (InsecureHttpClient == null) {
try {
InsecureHttpClient = insecureOkHttpClient ();
} catch (Exception e) {
e.printStackTrace ();
}
}
return InsecureHttpClient;
}
private static OkHttpClient insecureOkHttpClient () throws Exception {
TrustManager [] trustAllCerts = new TrustManager [] { trustManager () };
SSLContext sslContext = SSLContext.getInstance (SSL);
sslContext.init (null, trustAllCerts, new SecureRandom ());
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory ();
OkHttpClient.Builder builder = new OkHttpClient.Builder ();
builder.sslSocketFactory (sslSocketFactory, (X509TrustManager)trustAllCerts [0]);
builder.hostnameVerifier (hostnameVerifier ());
return builder.build ();
}
private static TrustManager trustManager () {
return new X509TrustManager () {
@Override
public void checkClientTrusted (X509Certificate [] chain, String authType) throws CertificateException { }
@Override
public void checkServerTrusted (X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public X509Certificate [] getAcceptedIssuers () {
return new X509Certificate [] { };
}
};
}
private static HostnameVerifier hostnameVerifier () {
return new HostnameVerifier () {
@Override
public boolean verify (String hostname, SSLSession session) {
return true;
}
};
}
}
然后您显然可以像下面的测试代码一样使用上述客户端:(顺便说一句,它适用于您的 url)
final Request request = new Request.Builder ()
.url ("https://bits-bosm.org/2017/registrations/signup/")
.get ()
.addHeader ("Accept", "text/html")
.build ();
final OkHttpClient httpClient = Http.client ();
new Thread (new Runnable () {
@Override
public void run () {
try {
Response response = httpClient.newCall (request).execute ();
Logger.error (MainActivity.class.getSimpleName () + " --> Http Response", response.body ().string ());
} catch (IOException e) {
e.printStackTrace ();
}
}
}).start ();
我正在尝试向服务器发送 get 请求(发送 get 请求进行测试,实际上我需要向同一台服务器发送 post 请求。如果 get 有效,post 将有效)
link 到服务器是 https://bits-bosm.org/2017/registrations/signup/
问题是当我使用 okHttp 发送请求时,我收到一个失败响应,提示握手失败。
这是我使用 okHttp(在 kotlin 中)发送请求的代码
val request = Request.Builder()
.url("https://bits-bosm.org/2017/registrations/signup/")
.build()
okHttpClient.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
val mMessage = e?.message?.toString()
Log.w("failure Response", mMessage)
}
override fun onResponse(call: Call?, response: Response?) {
val mMessage = response?.body()?.string()
Log.e("Message", mMessage)
}
})
但是如果我使用 HttpUrlConnection 将 get 请求发送到同一台服务器,我会收到响应。
这是相同的代码 (java)
private static final String USER_AGENT = "Mozilla/5.0";
private static final String GET_URL = "https://bits-bosm.org/2017/registrations/signup/";
static void sendGET() throws IOException {
URL obj = new URL(GET_URL);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println("GET Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
Log.e("Result", response.toString());
} else {
System.out.println("GET request not worked");
}
}
根据我在互联网上搜索的内容和我可以推断的内容,问题是该站点是使用自证书签名的,而 okHttp 不允许它们。我什至尝试使用我在 Internet 上找到的不检查证书(Custom SSLSocketFactory)和其他一些解决方案的代码片段,但其中 none 有效。另外,我现在不关心安全性,我只想让它发挥作用。但是我无法访问后端,也无法 change/remove ssl 安全。
如何才能让它发挥作用?有什么我想念的吗?
这是广泛用作解决方法的不安全的 OkHttpClient。
请勿在生产中使用它,它仅用于开发目的。
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
public class Http {
private final static String SSL = "SSL";
private static OkHttpClient InsecureHttpClient;
public static OkHttpClient client () {
if (InsecureHttpClient == null) {
try {
InsecureHttpClient = insecureOkHttpClient ();
} catch (Exception e) {
e.printStackTrace ();
}
}
return InsecureHttpClient;
}
private static OkHttpClient insecureOkHttpClient () throws Exception {
TrustManager [] trustAllCerts = new TrustManager [] { trustManager () };
SSLContext sslContext = SSLContext.getInstance (SSL);
sslContext.init (null, trustAllCerts, new SecureRandom ());
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory ();
OkHttpClient.Builder builder = new OkHttpClient.Builder ();
builder.sslSocketFactory (sslSocketFactory, (X509TrustManager)trustAllCerts [0]);
builder.hostnameVerifier (hostnameVerifier ());
return builder.build ();
}
private static TrustManager trustManager () {
return new X509TrustManager () {
@Override
public void checkClientTrusted (X509Certificate [] chain, String authType) throws CertificateException { }
@Override
public void checkServerTrusted (X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public X509Certificate [] getAcceptedIssuers () {
return new X509Certificate [] { };
}
};
}
private static HostnameVerifier hostnameVerifier () {
return new HostnameVerifier () {
@Override
public boolean verify (String hostname, SSLSession session) {
return true;
}
};
}
}
然后您显然可以像下面的测试代码一样使用上述客户端:(顺便说一句,它适用于您的 url)
final Request request = new Request.Builder ()
.url ("https://bits-bosm.org/2017/registrations/signup/")
.get ()
.addHeader ("Accept", "text/html")
.build ();
final OkHttpClient httpClient = Http.client ();
new Thread (new Runnable () {
@Override
public void run () {
try {
Response response = httpClient.newCall (request).execute ();
Logger.error (MainActivity.class.getSimpleName () + " --> Http Response", response.body ().string ());
} catch (IOException e) {
e.printStackTrace ();
}
}
}).start ();