我有一个类似的问题。这是我如何应用到你的情况:
import javax.net.ssl.HttpsURLConnection;
import okhttp3.Dns;
import okhttp3.OkHttpClient;
OkHttpClient mOkHttpClient= new OkHttpClient.Builder()
.dns(hostname -> {
if(hostname.equals("proxy.example.com"))
hostname = "api.example.com";
return Dns.SYSTEM.lookup(hostname);
})
.hostnameVerifier((hostname, session) -> {
if(hostname.equals("proxy.example.com"))
return true;
return HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session);
}).build();
然后,像这样更新你的代码:
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
//.host("api.example.com") don't use this host
.host("proxy.example.com") // use the one in the host header
.build();
okhttprequest = new com.squareup.okhttp.Request.Builder()
.url(url)
.method("GET", requestBody)
//.header("Host", "proxy.example.com") don't need anymore
.build();
response = mOkHttpClient.newCall(okhttprequest).execute();
这是问题所在及解决方案的说明:
您希望在主机头中使用“proxy.example.com”,但okhttp也会根据给定的URL创建此标头,而在您的情况下是“api.example.com”。
我找不到阻止okhttp这样做的方法。还有另一种方法。
我们在URL中使用“proxy.example.com”,以便由okhttp创建的主机标头将为“host: proxy.example.com”,然后我们还添加了一个特殊情况用于DNS查找。
在“proxy.example.com”的DNS解析期间,我们将主机更改为“api.example.com”,以便您的请求将转到由“api.example.com”指向的IP地址的服务器。
这会产生一个副作用。服务器返回的证书将包含名称“api.example.com”,而由于URL中的主机是“proxy.example.com”,因此主机名验证将失败。
为了防止这种情况发生,我们添加了一个特殊情况来验证“proxy.example.com”,并在验证期间如果主机名为“proxy.example.com”,则返回true。
'