通过squid代理

时间:2016-03-02 14:36:25

标签: java authentication proxy httpclient squid

我需要从Java应用程序将文件上传到Web服务。因此我使用Apaches HttpClient。另外我需要通过代理连接。在我的例子中,这是一个带有基本身份验证的squid代理。将来,这可能会更改为使用其他身份验证类型的其他代理。

这是我当前代码的片段:

MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

... //fill entity

CredentialsProvider provider = new MyCredentialsProvider();         
HttpRoutePlanner routePlanner = new SystemDefaultRoutePlanner(ProxySelector.getDefault());
CloseableHttpClient client = HttpClients.custom()
    .setRoutePlanner(routePlanner)
    .setDefaultCredentialsProvider(provider)
    .build();

...

HttpPost post = new HttpPost(url);
post.setHeader("Cookie",cookies); //needed for session
post.setEntity(entity);

...

HttpResponse res = client.execute(post);

...

client.close();

MyCredentialsProvider是一个自制类,因为HttpClient的SystemDefaultCredentialsProvider似乎无法按预期工作。它基本上使用java.net.Authenticator从用户请求凭据。

使用此代码似乎一切正常。我可以在Java控制面板中使用我的squid代理集(无身份验证和基本身份验证)上传没有代理集的文件。当我上传一个稍微大一点的文件(大约64kb)时,我才会遇到这个问题。在这种情况下,client.execute(post)在超时运行时出现以下异常:[proxy ip]:[proxy port]无法响应

org.apache.http.NoHttpResponseException: [proxy ip]:[proxy port] failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
...

在Wireshark中我可以看到,HttpClient发出两个相同的http post请求。一个没有http标题"代理授权" n,一个没有"代理授权:基本..."。第一个获得预期的响应(需要407代理身份验证)。秒请求没有响应。我可以看到两个请求都只包含多部分实体的第一个参数。

我可以用HttpClient 4.2.1重现这种现象。

是否还有人参加过此活动?我想这有事可做,这两个请求都是在一个http连接中进行的。有谁知道如何配置HttpClient或squid代理来使其工作?

感谢您的帮助。

修改 如果我按照http://www.nuxeo.com/blog/using-httpclient-properly-avoid-closewait-tcp-connections/的说明操作,我可以将最大文件大小增加到大约1mb。我在执行请求之前设置了一个http标头:

post.setHeader("Connection", "close");

超过1mb的文件给我以下例外:

java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:126)
at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:162)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:115)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:122)
at org.apache.http.entity.mime.content.ByteArrayBody.writeTo(ByteArrayBody.java:97)
at org.apache.http.entity.mime.AbstractMultipartForm.doWriteTo(AbstractMultipartForm.java:134)
at org.apache.http.entity.mime.AbstractMultipartForm.writeTo(AbstractMultipartForm.java:157)
at org.apache.http.entity.mime.MultipartFormEntity.writeTo(MultipartFormEntity.java:113)
at org.apache.http.entity.mime.MultipartEntity.writeTo(MultipartEntity.java:180)
at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:158)
at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:162)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:237)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:122)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)

但这不是解决方案,因为我需要上传更大的文件(可能高达10mb)和多个文件!

0 个答案:

没有答案