在okhttp请求中覆盖HOST头

4

我正在使用okhttp从我的Android APK发送一些HTTP请求。由于一些服务器端代理的要求,我希望URL端点像这样:" https://api.example.com ",但在HTTP请求中,我希望覆盖HOST头,变成 "Host: proxy.example.com"。我尝试使用类似以下的内容:

    HttpUrl url = new HttpUrl.Builder()
      .scheme("https")
      .host("api.example.com")
      .build();

    okhttprequest = new com.squareup.okhttp.Request.Builder()
      .url(url)
      .method("GET", requestBody)
      .header("Host", "proxy.example.com")
      .build();

    response = mOkHttpClient.newCall(okhttprequest).execute();

然而,当我查看网络包中的http请求时,HOST头仍然是"api.example.com"。不知道是否有任何建议可以覆盖HOST头?非常感谢!

2个回答

1

我有一个类似的问题。这是我如何应用到你的情况:

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。

'


0

默认情况下,OkHttp不允许您设置与URL主机不同的主机标头。您可以通过使用网络拦截器来设置主机标头。


谢谢回复。我也尝试使用网络拦截器,但仍然无法正常工作...看起来Okhttp不希望主机头被更改为与端点URL不同的值... - Bob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接