okhttp客户端在TMG代理服务器下抛出异常

Posted

技术标签:

【中文标题】okhttp客户端在TMG代理服务器下抛出异常【英文标题】:okhttp client throwing exception under TMG proxy server 【发布时间】:2015-01-14 05:53:45 【问题描述】:

我正在为我的 java 应用程序使用 github 的方形 OKHTTP 客户端库,如下所示:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
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.TrustManager;
import javax.net.ssl.X509TrustManager;


import com.squareup.okhttp.Authenticator;
import com.squareup.okhttp.Credentials;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;


public class TestOkHttp 

static public void main(String argcp[])
    try 
        OkHttpClient okHttpClient = new OkHttpClient();
          TrustManager[] trustAllCerts = new TrustManager[] 
                   new X509TrustManager() 

                    @Override
                    public X509Certificate[] getAcceptedIssuers() 
                        // TODO Auto-generated method stub
                        return null;
                    

                    @Override
                    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                            throws CertificateException 
                        // TODO Auto-generated method stub

                    

                    @Override
                    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                            throws CertificateException 
                        // TODO Auto-generated method stub

                    
                ;

                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                okHttpClient.setSslSocketFactory(sc.getSocketFactory());
            Proxy p=new Proxy(Proxy.Type.HTTP,new InetSocketAddress("10.1.1.0", 8080));
          okHttpClient.setProxy(p);
            HostnameVerifier hostNameVerifier = new HostnameVerifier() 

                @Override
                public boolean verify(String sourceHost, SSLSession arg1) 
                    // TODO Auto-generated method stub
                    return sourceHost.equals("serverwithtls.com");
                

            ;

            okHttpClient.setHostnameVerifier(hostNameVerifier);
        okHttpClient.setAuthenticator(new Authenticator() 

            @Override
            public Request authenticateProxy(Proxy proxy, Response response)
                    throws IOException 
                 String credential = Credentials.basic("username","password");
                            return response.request().newBuilder()
                                .header("Authorization", credential)
                                .build();               
                            

            @Override
            public Request authenticate(Proxy arg0, Response arg1)
                    throws IOException 
                // TODO Auto-generated method stub
                return null;
            


        );
         Request request = new Request.Builder()
            .url("https://serverwithtls.com")
            .build();

        Response response = okHttpClient.newCall(request).execute();
        System.out.println(response.body().string());
     catch (Exception e) 
        e.printStackTrace();
    



我的网络连接在 Microsoft TMG 代理服务器后面需要代理用户身份验证,执行上述代码时出现以下异常:

java.net.ProtocolException:意外的状态行:

错误消息 在 com.squareup.okhttp.internal.http.StatusLine.parse(StatusLine.java:54) 在 com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:187) 在 com.squareup.okhttp.Connection.makeTunnel(Connection.java:395) 在 com.squareup.okhttp.Connection.upgradeToTls(Connection.java:223) 在 com.squareup.okhttp.Connection.connect(Connection.java:153) 在 com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:169) 在 com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:119) 在 com.squareup.okhttp.internal.http.RouteSelector.next(RouteSelector.java:134) 在 com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:314) 在 com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:237) 在 com.squareup.okhttp.Call.getResponse(Call.java:233) 在 com.squareup.okhttp.Call.execute(Call.java:84)

我尝试在不同的代理服务器下工作,效果很好。

有什么帮助吗?

【问题讨论】:

有关于这个问题的消息吗?解决方案? 自从我研究这个已经有一段时间了,@MarianPaździoch OKhttp 不支持 TMG 代理(或者至少当时不支持),所以我选择了 ApacheClient,它成功通过了 TMG 代理服务器。 【参考方案1】:

看起来像是 OkHttp 中的一个错误,我们在哪里没有丢弃 407 上的完整响应正文。在我们的 GitHub 问题跟踪器上打开一个问题,我会看看。如果感兴趣的代理可以通过公共 Internet 访问,请将其私下发送给我,jesse@swank.ca,我会确认这一点。

【讨论】:

我刚刚在 OkHttp 的问题跟踪器上发布了你提到的。然而不幸的是,我们感兴趣的代理无法访问。我还有其他方法可以进一步解决这个问题吗? 如果不是公开的,如果你能私下分享代理地址还是很方便的。我是 swank.ca 的杰西。否则,如果您可以使用 Wireshark 捕获代理的响应,那将很有用。

以上是关于okhttp客户端在TMG代理服务器下抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

CImg 在 Debug 模式下抛出异常,在 Release 中工作正常

python 如果不存在则创建文件,在其他情况下抛出异常

拦截 GWT RPC 的异步代理服务异常

TMG2010和OUTLOOK的问题

Python哈希函数啥情况下抛出异常

6.TMG2010公网发布