首页 文章

Apache httpclient 4.x 302重定向并关闭keepalive?

提问于
浏览
1

我一直在尝试向服务器发出HTTP GET请求,该服务器使用HttpClient 4.4.1(GA)返回带有重定向路径的302 . 我有一些问题使它在不使用keepalive时无缝地工作 .

这是我的代码:

HttpGet httpget = new HttpGet("http://10.104.107.22:1354/video/Manifest");
    Header header = new BasicHeader(HttpHeaders.CONNECTION,
            "close");
    ArrayList<Header> headers = new ArrayList<>();
    headers.add(header);
    CloseableHttpClient client = HttpClients.custom().setDefaultHeaders(headers).build();
    HttpEntity entity = null;
    CloseableHttpResponse response = client.execute(httpget);

    try{    
        entity = response.getEntity();  
            if (entity != null) {
                long len = entity.getContentLength();
                if (len != -1 && len < 2048) {
                    responseBody = EntityUtils.toString(entity);
                } 
                else {
                    InputStream instream = entity.getContent();
                    try {
                        StringWriter writer = new StringWriter();
                        IOUtils.copy(instream, writer, "UTF-8");
                        responseBody = writer.toString();
                    } finally {
                        instream.close();
                    }
                }
            }
    }
    finally{
        EntityUtils.consume(entity);
        response.close();
        client.close();
    }

很简单 .

获取GET请求时,服务器会响应

HTTP/1.1 302 Moved Temporarily
    Content-Length: 0
    Location: http://10.104.107.22:1354/video/Manifest?sessionID=250849653588053716653279720260905006780
    Date: Mon, 06 Apr 2015 19:18:42 GMT

很酷,现在我们知道去哪了 . 问题是,httpclient然后抱怨错误:

Apr 08, 2015 2:39:29 PM org.apache.http.impl.execchain.RetryExec execute
    INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request to /127.0.0.1->{}->http://10.104.107.22:1354:         The target server failed to respond
    Apr 08, 2015 2:39:29 PM org.apache.http.impl.execchain.RetryExec execute
    INFO: Retrying request to /127.0.0.1->{}->http://10.104.107.22:1354

按照它的说法,它然后重试从IOException恢复并在同一连接中发送带有重定向URL的另一个请求!

GET /video/Manifest?sessionID=250849653588053716653279720260905006780 HTTP/1.1
    Connection: close
    Host: 10.104.107.22:1354
    User-Agent: Apache-HttpClient/4.4.1 (Java 1.5 minimum; Java/1.7.0_55)
    Accept-Encoding: gzip,deflate

现在,因为我们从头开始指定了“Connection:close”作为 Headers ,所以服务器会 grab 这一点并关闭其侧面的套接字 . 然后我的客户端获得RST信号 . 重新发送的Url会再次重新发送请求,这次工作正常 .

我试图解决的问题是如何阻止客户端在同一连接中发送重定向请求 . 我设法通过在CloseableHttpClient对象上使用 disableRedirectHandling() 的第一个请求之后禁用重定向,然后在单独的连接中自己处理302响应来设置"solve" . 如果我使用keepAlive来处理这个问题,事情也可以正常工作,虽然我必须在完成后用 ConnectionKeepAliveStrategy 策略超时客户端套接字 .

有没有办法让HttpClient 4.4.1能够自动处理单独请求中302重定向的处理?

编辑:按要求发布GET请求的完整通信 .

GET /video/Manifest HTTP/1.1
    Connection: close
    Host: 10.104.107.22:1354
    User-Agent: Apache-HttpClient/4.4.1 (Java 1.5 minimum; Java/1.7.0_55)
    Accept-Encoding: gzip,deflate

    HTTP/1.1 302 Moved Temporarily
    Content-Length: 0
    Location: http://10.104.107.22:1354/video/Manifest?sessionID=250849653588053716653279720260905006780
    Date: Wed, 08 Apr 2015 14:36:42 GMT

    GET /video/Manifest?sessionID=250849653588053716653279720260905006780 HTTP/1.1
    Connection: close
    Host: 10.104.107.22:1354
    User-Agent: Apache-HttpClient/4.4.1 (Java 1.5 minimum; Java/1.7.0_55)
    Accept-Encoding: gzip,deflate

然后我从服务器获取RST信号 .

Header Wire上下文日志记录 .

2015/04/08 15:57:25:657 EDT [DEBUG] RequestAddCookies - CookieSpec selected: default
    2015/04/08 15:57:25:667 EDT [DEBUG] RequestAuthCache - Auth cache not set in the context
    2015/04/08 15:57:25:668 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
    2015/04/08 15:57:25:679 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
    2015/04/08 15:57:25:681 EDT [DEBUG] MainClientExec - Opening connection /127.0.0.1->{}->http://10.104.107.22:1354
    2015/04/08 15:57:25:683 EDT [DEBUG] DefaultHttpClientConnectionOperator - Connecting to /10.104.107.22:1354
    2015/04/08 15:57:25:686 EDT [DEBUG] DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:46323<->10.104.107.22:1354
    2015/04/08 15:57:25:686 EDT [DEBUG] MainClientExec - Executing request GET /video/Manifest HTTP/1.1
    2015/04/08 15:57:25:686 EDT [DEBUG] MainClientExec - Target auth state: UNCHALLENGED
    2015/04/08 15:57:25:687 EDT [DEBUG] MainClientExec - Proxy auth state: UNCHALLENGED
    2015/04/08 15:57:25:688 EDT [DEBUG] headers - http-outgoing-0 >> GET /video/Manifest HTTP/1.1
    2015/04/08 15:57:25:688 EDT [DEBUG] headers - http-outgoing-0 >> Connection: close
    2015/04/08 15:57:25:688 EDT [DEBUG] headers - http-outgoing-0 >> Host: 10.104.107.22:1354
    2015/04/08 15:57:25:688 EDT [DEBUG] headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.4.1 (Java/1.7.0_55)
    2015/04/08 15:57:25:688 EDT [DEBUG] headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
    2015/04/08 15:57:25:700 EDT [DEBUG] headers - http-outgoing-0 << HTTP/1.1 302 Moved Temporarily
    2015/04/08 15:57:25:700 EDT [DEBUG] headers - http-outgoing-0 << Content-Length: 0
    2015/04/08 15:57:25:701 EDT [DEBUG] headers - http-outgoing-0 << Location: http://10.104.107.22:1354/video/Manifest?sessionID=162729772390321694625639849465722594850
    2015/04/08 15:57:25:701 EDT [DEBUG] headers - http-outgoing-0 << Date: Wed, 08 Apr 2015 19:57:25 GMT
    2015/04/08 15:57:25:707 EDT [DEBUG] MainClientExec - Connection can be kept alive indefinitely
    2015/04/08 15:57:25:707 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection [id: 0][route: /127.0.0.1->{}->http://10.104.107.22:1354] can be kept alive indefinitely
    2015/04/08 15:57:25:707 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 0][route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
    2015/04/08 15:57:25:709 EDT [DEBUG] DefaultRedirectStrategy - Redirect requested to location 'http://10.104.107.22:1354/video/Manifest?sessionID=162729772390321694625639849465722594850'
    2015/04/08 15:57:25:713 EDT [DEBUG] RedirectExec - Redirecting to 'http://10.104.107.22:1354/video/Manifest?sessionID=162729772390321694625639849465722594850' via /127.0.0.1->{}->http://10.104.107.22:1354
    2015/04/08 15:57:25:714 EDT [DEBUG] RequestAddCookies - CookieSpec selected: default
    2015/04/08 15:57:25:714 EDT [DEBUG] RequestAuthCache - Auth cache not set in the context
    2015/04/08 15:57:25:714 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
    2015/04/08 15:57:25:715 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
    2015/04/08 15:57:25:715 EDT [DEBUG] MainClientExec - Executing request GET /video/Manifest?sessionID=162729772390321694625639849465722594850 HTTP/1.1
    2015/04/08 15:57:25:715 EDT [DEBUG] MainClientExec - Target auth state: UNCHALLENGED
    2015/04/08 15:57:25:716 EDT [DEBUG] MainClientExec - Proxy auth state: UNCHALLENGED
    2015/04/08 15:57:25:716 EDT [DEBUG] headers - http-outgoing-0 >> GET /video/Manifest?sessionID=162729772390321694625639849465722594850 HTTP/1.1
    2015/04/08 15:57:25:716 EDT [DEBUG] headers - http-outgoing-0 >> Connection: close
    2015/04/08 15:57:25:716 EDT [DEBUG] headers - http-outgoing-0 >> Host: 10.104.107.22:1354
    2015/04/08 15:57:25:716 EDT [DEBUG] headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.4.1 (Java/1.7.0_55)
    2015/04/08 15:57:25:717 EDT [DEBUG] headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
    2015/04/08 15:57:25:717 EDT [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: Close connection
    2015/04/08 15:57:25:718 EDT [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: Shutdown connection
    2015/04/08 15:57:25:718 EDT [DEBUG] MainClientExec - Connection discarded
    2015/04/08 15:57:25:718 EDT [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-0: Close connection
    2015/04/08 15:57:25:718 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 0][route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
    2015/04/08 15:57:25:718 EDT [INFO] RetryExec - I/O exception (org.apache.http.NoHttpResponseException) caught when processing request to /127.0.0.1->{}->http://10.104.107.22:1354: The target server failed to respond
    2015/04/08 15:57:25:718 EDT [DEBUG] RetryExec - The target server failed to respond <org.apache.http.NoHttpResponseException: The target server failed to respond>org.apache.http.NoHttpResponseException: The target server 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)
        at WorkingNonKeepAliveUseCase.requestWithoutKeepAlive(WorkingNonKeepAliveUseCase.java:109)
        at Runner.main(Runner.java:13)

    2015/04/08 15:57:25:720 EDT [INFO] RetryExec - Retrying request to /127.0.0.1->{}->http://10.104.107.22:1354
    2015/04/08 15:57:25:720 EDT [DEBUG] RequestAddCookies - CookieSpec selected: default
    2015/04/08 15:57:25:720 EDT [DEBUG] RequestAuthCache - Auth cache not set in the context
    2015/04/08 15:57:25:720 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
    2015/04/08 15:57:25:721 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 1][route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
    2015/04/08 15:57:25:721 EDT [DEBUG] MainClientExec - Opening connection /127.0.0.1->{}->http://10.104.107.22:1354
    2015/04/08 15:57:25:721 EDT [DEBUG] DefaultHttpClientConnectionOperator - Connecting to /10.104.107.22:1354
    2015/04/08 15:57:25:721 EDT [DEBUG] DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:40753<->10.104.107.22:1354
    2015/04/08 15:57:25:721 EDT [DEBUG] MainClientExec - Executing request GET /video/Manifest?sessionID=162729772390321694625639849465722594850 HTTP/1.1
    2015/04/08 15:57:25:721 EDT [DEBUG] MainClientExec - Target auth state: UNCHALLENGED
    2015/04/08 15:57:25:721 EDT [DEBUG] MainClientExec - Proxy auth state: UNCHALLENGED
    2015/04/08 15:57:25:722 EDT [DEBUG] headers - http-outgoing-1 >> GET /video/Manifest?sessionID=162729772390321694625639849465722594850 HTTP/1.1
    2015/04/08 15:57:25:722 EDT [DEBUG] headers - http-outgoing-1 >> Connection: close
    2015/04/08 15:57:25:722 EDT [DEBUG] headers - http-outgoing-1 >> Host: 10.104.107.22:1354
    2015/04/08 15:57:25:722 EDT [DEBUG] headers - http-outgoing-1 >> User-Agent: Apache-HttpClient/4.4.1 (Java/1.7.0_55)
    2015/04/08 15:57:25:722 EDT [DEBUG] headers - http-outgoing-1 >> Accept-Encoding: gzip,deflate
    2015/04/08 15:57:25:792 EDT [DEBUG] headers - http-outgoing-1 << HTTP/1.1 200 OK
    2015/04/08 15:57:25:792 EDT [DEBUG] headers - http-outgoing-1 << Content-Length: 17090
    2015/04/08 15:57:25:792 EDT [DEBUG] headers - http-outgoing-1 << Pragma: no-cache
    2015/04/08 15:57:25:793 EDT [DEBUG] headers - http-outgoing-1 << Cache-Control: max-age=0, no-cache, no-store
    2015/04/08 15:57:25:793 EDT [DEBUG] headers - http-outgoing-1 << Content-Type: application/vnd.ms-sstr+xml
    2015/04/08 15:57:25:793 EDT [DEBUG] headers - http-outgoing-1 << Date: Wed, 08 Apr 2015 19:57:25 GMT
    2015/04/08 15:57:25:794 EDT [DEBUG] MainClientExec - Connection can be kept alive indefinitely
    2015/04/08 15:57:26:795 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection [id: 1][route: /127.0.0.1->{}->http://10.104.107.22:1354] can be kept alive indefinitely
    2015/04/08 15:57:26:796 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 1][route: /127.0.0.1->{}->http://10.104.107.22:1354][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
    2015/04/08 15:57:26:796 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection manager is shutting down
    2015/04/08 15:57:26:796 EDT [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1: Close connection
    2015/04/08 15:57:26:797 EDT [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1: Close connection
    2015/04/08 15:57:26:797 EDT [DEBUG] PoolingHttpClientConnectionManager - Connection manager shut down

1 回答

  • 0

    问题在于这一部分

    2015/04/08 15:57:25:700 EDT [DEBUG] headers - http-outgoing-0 << HTTP/1.1 302 Moved Temporarily
    2015/04/08 15:57:25:700 EDT [DEBUG] headers - http-outgoing-0 << Content-Length: 0
    2015/04/08 15:57:25:701 EDT [DEBUG] headers - http-outgoing-0 << Location: http://10.104.107.22:1354/video/Manifest?sessionID=162729772390321694625639849465722594850
    2015/04/08 15:57:25:701 EDT [DEBUG] headers - http-outgoing-0 << Date: Wed, 08 Apr 2015 19:57:25 GMT
    

    服务器发回的重定向响应不包含服务器之后要关闭连接的任何线索 . HttpClient尽职尽责地将连接返回到池中,然后将其返回以处理导致I / O错误的重定向 .

    真的有充分理由完全禁用连接持久性吗?我认为你可能最好让HttpClient重用同一个会话的连接,然后在会话结束后立即驱逐连接池中的所有持久连接 .

    来自Oleg Kalnichevski的后续评论 .

    HttpClient期望相反的 endpoints 显式地声明其意图,如果它意图丢弃连接,则发送'Connection:close' .

    这解决了我的问题 .

相关问题